blob: fb65846782a989cf59b6552d355c0dcf11ba9b53 [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);
mmenked1205bd3972015-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[] = {
mmenke0fd148d2015-09-30 23:00:082557 MockWrite(
2558 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2559 "Host: www.example.org\r\n"
2560 "Proxy-Connection: keep-alive\r\n\r\n"),
2561
2562 // After calling trans->RestartWithAuth(), this is the request we should
2563 // be issuing -- the final header line contains the credentials.
2564 MockWrite(
2565 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2566 "Host: www.example.org\r\n"
2567 "Proxy-Connection: keep-alive\r\n"
2568 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2569
2570 MockWrite(
2571 "GET / HTTP/1.1\r\n"
2572 "Host: www.example.org\r\n"
2573 "Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012574 };
2575
mmenke0fd148d2015-09-30 23:00:082576 // The proxy responds to the connect with a 407, using a persistent
ttuttle34f63b52015-03-05 04:33:012577 // connection.
2578 MockRead data_reads1[] = {
2579 // No credentials.
2580 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2581 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012582
ttuttle34f63b52015-03-05 04:33:012583 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2584
2585 MockRead("HTTP/1.1 200 OK\r\n"),
2586 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2587 MockRead("Content-Length: 5\r\n\r\n"),
2588 MockRead(SYNCHRONOUS, "hello"),
2589 };
2590
2591 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2592 data_writes1, arraysize(data_writes1));
2593 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:012594 SSLSocketDataProvider ssl(ASYNC, OK);
2595 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2596
2597 TestCompletionCallback callback1;
2598
2599 scoped_ptr<HttpTransaction> trans(
2600 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2601
2602 int rv = trans->Start(&request, callback1.callback(), log.bound());
2603 EXPECT_EQ(ERR_IO_PENDING, rv);
2604
2605 rv = callback1.WaitForResult();
2606 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462607 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012608 log.GetEntries(&entries);
2609 size_t pos = ExpectLogContainsSomewhere(
2610 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2611 NetLog::PHASE_NONE);
2612 ExpectLogContainsSomewhere(
2613 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2614 NetLog::PHASE_NONE);
2615
2616 const HttpResponseInfo* response = trans->GetResponseInfo();
2617 ASSERT_TRUE(response != NULL);
2618 EXPECT_FALSE(response->headers->IsKeepAlive());
2619 ASSERT_FALSE(response->headers.get() == NULL);
2620 EXPECT_EQ(407, response->headers->response_code());
2621 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2622 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2623
2624 LoadTimingInfo load_timing_info;
2625 // CONNECT requests and responses are handled at the connect job level, so
2626 // the transaction does not yet have a connection.
2627 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2628
2629 TestCompletionCallback callback2;
2630
2631 rv =
2632 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2633 EXPECT_EQ(ERR_IO_PENDING, rv);
2634
2635 rv = callback2.WaitForResult();
2636 EXPECT_EQ(OK, rv);
2637
2638 response = trans->GetResponseInfo();
2639 ASSERT_TRUE(response != NULL);
2640
2641 EXPECT_TRUE(response->headers->IsKeepAlive());
2642 EXPECT_EQ(200, response->headers->response_code());
2643 EXPECT_EQ(5, response->headers->GetContentLength());
2644 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2645
2646 // The password prompt info should not be set.
2647 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2648
2649 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2650 TestLoadTimingNotReusedWithPac(load_timing_info,
2651 CONNECT_TIMING_HAS_SSL_TIMES);
2652
2653 trans.reset();
2654 session->CloseAllConnections();
2655}
2656
2657// Test the request-challenge-retry sequence for basic auth, over a connection
2658// that requires a restart when setting up an SSL tunnel.
2659TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592660 HttpRequestInfo request;
2661 request.method = "GET";
bncce36dca22015-04-21 22:11:232662 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592663 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292664 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592665
[email protected]cb9bf6ca2011-01-28 13:15:272666 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032667 session_deps_.proxy_service =
2668 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512669 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072670 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:062671 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272672
[email protected]394816e92010-08-03 07:38:592673 // Since we have proxy, should try to establish tunnel.
2674 MockWrite data_writes1[] = {
mmenke0fd148d2015-09-30 23:00:082675 MockWrite(
2676 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2677 "Host: www.example.org\r\n"
2678 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592679
mmenkee0b5c882015-08-26 20:29:112680 // After calling trans->RestartWithAuth(), this is the request we should
2681 // be issuing -- the final header line contains the credentials.
mmenke0fd148d2015-09-30 23:00:082682 MockWrite(
2683 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2684 "Host: www.example.org\r\n"
2685 "Proxy-Connection: keep-alive\r\n"
2686 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592687
mmenke0fd148d2015-09-30 23:00:082688 MockWrite(
2689 "GET / HTTP/1.1\r\n"
2690 "Host: www.example.org\r\n"
2691 "Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:112692 };
2693
mmenke0fd148d2015-09-30 23:00:082694 // The proxy responds to the connect with a 407, using a persistent
2695 // connection.
2696 MockRead data_reads1[] = {
2697 // No credentials.
2698 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2699 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2700 MockRead("Proxy-Connection: close\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:112701
mmenke0fd148d2015-09-30 23:00:082702 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2703
2704 MockRead("HTTP/1.1 200 OK\r\n"),
2705 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2706 MockRead("Content-Length: 5\r\n\r\n"),
2707 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592708 };
2709
2710 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2711 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072712 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062713 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072714 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592715
[email protected]49639fa2011-12-20 23:22:412716 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592717
[email protected]262eec82013-03-19 21:01:362718 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502719 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502720
[email protected]49639fa2011-12-20 23:22:412721 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592722 EXPECT_EQ(ERR_IO_PENDING, rv);
2723
2724 rv = callback1.WaitForResult();
2725 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462726 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402727 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592728 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402729 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592730 NetLog::PHASE_NONE);
2731 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402732 entries, pos,
[email protected]394816e92010-08-03 07:38:592733 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2734 NetLog::PHASE_NONE);
2735
2736 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502737 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012738 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502739 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592740 EXPECT_EQ(407, response->headers->response_code());
2741 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042742 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592743
[email protected]029c83b62013-01-24 05:28:202744 LoadTimingInfo load_timing_info;
2745 // CONNECT requests and responses are handled at the connect job level, so
2746 // the transaction does not yet have a connection.
2747 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2748
[email protected]49639fa2011-12-20 23:22:412749 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592750
[email protected]49639fa2011-12-20 23:22:412751 rv = trans->RestartWithAuth(
2752 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592753 EXPECT_EQ(ERR_IO_PENDING, rv);
2754
2755 rv = callback2.WaitForResult();
2756 EXPECT_EQ(OK, rv);
2757
2758 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502759 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592760
2761 EXPECT_TRUE(response->headers->IsKeepAlive());
2762 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502763 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592764 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2765
2766 // The password prompt info should not be set.
2767 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502768
[email protected]029c83b62013-01-24 05:28:202769 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2770 TestLoadTimingNotReusedWithPac(load_timing_info,
2771 CONNECT_TIMING_HAS_SSL_TIMES);
2772
[email protected]0b0bf032010-09-21 18:08:502773 trans.reset();
[email protected]102e27c2011-02-23 01:01:312774 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592775}
2776
[email protected]11203f012009-11-12 23:02:312777// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012778// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2779TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2780 HttpRequestInfo request;
2781 request.method = "GET";
bncce36dca22015-04-21 22:11:232782 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012783 // Ensure that proxy authentication is attempted even
2784 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292785 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012786
2787 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032788 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:512789 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012790 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:062791 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012792
2793 scoped_ptr<HttpTransaction> trans(
2794 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2795
2796 // Since we have proxy, should try to establish tunnel.
2797 MockWrite data_writes1[] = {
2798 MockWrite(
bncce36dca22015-04-21 22:11:232799 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2800 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012801 "Proxy-Connection: keep-alive\r\n\r\n"),
2802
2803 // After calling trans->RestartWithAuth(), this is the request we should
2804 // be issuing -- the final header line contains the credentials.
2805 MockWrite(
bncce36dca22015-04-21 22:11:232806 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2807 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012808 "Proxy-Connection: keep-alive\r\n"
2809 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2810 };
2811
2812 // The proxy responds to the connect with a 407, using a persistent
2813 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2814 MockRead data_reads1[] = {
2815 // No credentials.
2816 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2817 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2818 MockRead("Proxy-Connection: keep-alive\r\n"),
2819 MockRead("Content-Length: 10\r\n\r\n"),
2820 MockRead("0123456789"),
2821
2822 // Wrong credentials (wrong password).
2823 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2824 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2825 MockRead("Proxy-Connection: keep-alive\r\n"),
2826 MockRead("Content-Length: 10\r\n\r\n"),
2827 // No response body because the test stops reading here.
2828 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2829 };
2830
2831 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2832 data_writes1, arraysize(data_writes1));
2833 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2834
2835 TestCompletionCallback callback1;
2836
2837 int rv = trans->Start(&request, callback1.callback(), log.bound());
2838 EXPECT_EQ(ERR_IO_PENDING, rv);
2839
2840 rv = callback1.WaitForResult();
2841 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462842 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012843 log.GetEntries(&entries);
2844 size_t pos = ExpectLogContainsSomewhere(
2845 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2846 NetLog::PHASE_NONE);
2847 ExpectLogContainsSomewhere(
2848 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2849 NetLog::PHASE_NONE);
2850
2851 const HttpResponseInfo* response = trans->GetResponseInfo();
2852 ASSERT_TRUE(response);
2853 ASSERT_TRUE(response->headers);
2854 EXPECT_TRUE(response->headers->IsKeepAlive());
2855 EXPECT_EQ(407, response->headers->response_code());
2856 EXPECT_EQ(10, response->headers->GetContentLength());
2857 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2858 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2859
2860 TestCompletionCallback callback2;
2861
2862 // Wrong password (should be "bar").
2863 rv =
2864 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2865 EXPECT_EQ(ERR_IO_PENDING, rv);
2866
2867 rv = callback2.WaitForResult();
2868 EXPECT_EQ(OK, rv);
2869
2870 response = trans->GetResponseInfo();
2871 ASSERT_TRUE(response);
2872 ASSERT_TRUE(response->headers);
2873 EXPECT_TRUE(response->headers->IsKeepAlive());
2874 EXPECT_EQ(407, response->headers->response_code());
2875 EXPECT_EQ(10, response->headers->GetContentLength());
2876 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2877 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2878
2879 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2880 // out of scope.
2881 session->CloseAllConnections();
2882}
2883
2884// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2885// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2886TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272887 HttpRequestInfo request;
2888 request.method = "GET";
bncce36dca22015-04-21 22:11:232889 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272890 // Ensure that proxy authentication is attempted even
2891 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292892 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:272893
[email protected]2d2697f92009-02-18 21:00:322894 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032895 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:512896 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072897 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:062898 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322899
[email protected]262eec82013-03-19 21:01:362900 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502901 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322902
[email protected]2d2697f92009-02-18 21:00:322903 // Since we have proxy, should try to establish tunnel.
2904 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232905 MockWrite(
2906 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2907 "Host: www.example.org\r\n"
2908 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322909
bncce36dca22015-04-21 22:11:232910 // After calling trans->RestartWithAuth(), this is the request we should
2911 // be issuing -- the final header line contains the credentials.
2912 MockWrite(
2913 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2914 "Host: www.example.org\r\n"
2915 "Proxy-Connection: keep-alive\r\n"
2916 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322917 };
2918
2919 // The proxy responds to the connect with a 407, using a persistent
2920 // connection.
2921 MockRead data_reads1[] = {
2922 // No credentials.
2923 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2924 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2925 MockRead("Content-Length: 10\r\n\r\n"),
2926 MockRead("0123456789"),
2927
2928 // Wrong credentials (wrong password).
2929 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2930 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2931 MockRead("Content-Length: 10\r\n\r\n"),
2932 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062933 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322934 };
2935
[email protected]31a2bfe2010-02-09 08:03:392936 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2937 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072938 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322939
[email protected]49639fa2011-12-20 23:22:412940 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322941
[email protected]49639fa2011-12-20 23:22:412942 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422943 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322944
2945 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422946 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462947 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402948 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392949 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402950 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392951 NetLog::PHASE_NONE);
2952 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402953 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392954 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2955 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322956
[email protected]1c773ea12009-04-28 19:58:422957 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242958 ASSERT_TRUE(response);
2959 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322960 EXPECT_TRUE(response->headers->IsKeepAlive());
2961 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012962 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422963 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042964 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322965
[email protected]49639fa2011-12-20 23:22:412966 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322967
2968 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412969 rv = trans->RestartWithAuth(
2970 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422971 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322972
2973 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422974 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322975
2976 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242977 ASSERT_TRUE(response);
2978 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322979 EXPECT_TRUE(response->headers->IsKeepAlive());
2980 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012981 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422982 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042983 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132984
[email protected]e60e47a2010-07-14 03:37:182985 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2986 // out of scope.
[email protected]102e27c2011-02-23 01:01:312987 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322988}
2989
[email protected]a8e9b162009-03-12 00:06:442990// Test that we don't read the response body when we fail to establish a tunnel,
2991// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022992TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272993 HttpRequestInfo request;
2994 request.method = "GET";
bncce36dca22015-04-21 22:11:232995 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272996 request.load_flags = 0;
2997
[email protected]a8e9b162009-03-12 00:06:442998 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032999 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443000
mmenke6b3af6e2015-09-12 02:06:063001 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443002
[email protected]262eec82013-03-19 21:01:363003 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503004 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:443005
[email protected]a8e9b162009-03-12 00:06:443006 // Since we have proxy, should try to establish tunnel.
3007 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:233008 MockWrite(
3009 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3010 "Host: www.example.org\r\n"
3011 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443012 };
3013
3014 // The proxy responds to the connect with a 407.
3015 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243016 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3017 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3018 MockRead("Content-Length: 10\r\n\r\n"),
3019 MockRead("0123456789"), // Should not be reached.
3020 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443021 };
3022
[email protected]31a2bfe2010-02-09 08:03:393023 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3024 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073025 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443026
[email protected]49639fa2011-12-20 23:22:413027 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443028
[email protected]49639fa2011-12-20 23:22:413029 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423030 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:443031
3032 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423033 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:443034
[email protected]1c773ea12009-04-28 19:58:423035 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243036 ASSERT_TRUE(response);
3037 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443038 EXPECT_TRUE(response->headers->IsKeepAlive());
3039 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423040 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443041
3042 std::string response_data;
3043 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423044 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:183045
3046 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313047 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443048}
3049
ttuttle7933c112015-01-06 00:55:243050// Test that we don't pass extraneous headers from the proxy's response to the
3051// caller when the proxy responds to CONNECT with 407.
3052TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
3053 HttpRequestInfo request;
3054 request.method = "GET";
bncce36dca22015-04-21 22:11:233055 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243056 request.load_flags = 0;
3057
3058 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033059 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243060
mmenke6b3af6e2015-09-12 02:06:063061 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243062
3063 scoped_ptr<HttpTransaction> trans(
3064 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3065
3066 // Since we have proxy, should try to establish tunnel.
3067 MockWrite data_writes[] = {
3068 MockWrite(
bncce36dca22015-04-21 22:11:233069 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3070 "Host: www.example.org\r\n"
ttuttle7933c112015-01-06 00:55:243071 "Proxy-Connection: keep-alive\r\n\r\n"),
3072 };
3073
3074 // The proxy responds to the connect with a 407.
3075 MockRead data_reads[] = {
3076 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3077 MockRead("X-Foo: bar\r\n"),
3078 MockRead("Set-Cookie: foo=bar\r\n"),
3079 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3080 MockRead("Content-Length: 10\r\n\r\n"),
3081 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
3082 };
3083
3084 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3085 arraysize(data_writes));
3086 session_deps_.socket_factory->AddSocketDataProvider(&data);
3087
3088 TestCompletionCallback callback;
3089
3090 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3091 EXPECT_EQ(ERR_IO_PENDING, rv);
3092
3093 rv = callback.WaitForResult();
3094 EXPECT_EQ(OK, rv);
3095
3096 const HttpResponseInfo* response = trans->GetResponseInfo();
3097 ASSERT_TRUE(response);
3098 ASSERT_TRUE(response->headers);
3099 EXPECT_TRUE(response->headers->IsKeepAlive());
3100 EXPECT_EQ(407, response->headers->response_code());
3101 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3102 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3103 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3104
3105 std::string response_data;
3106 rv = ReadTransaction(trans.get(), &response_data);
3107 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3108
3109 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3110 session->CloseAllConnections();
3111}
3112
[email protected]8fdbcd22010-05-05 02:54:523113// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3114// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:023115TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523116 HttpRequestInfo request;
3117 request.method = "GET";
bncce36dca22015-04-21 22:11:233118 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523119 request.load_flags = 0;
3120
[email protected]cb9bf6ca2011-01-28 13:15:273121 // We are using a DIRECT connection (i.e. no proxy) for this session.
mmenke6b3af6e2015-09-12 02:06:063122 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273123 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:413124 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:273125
[email protected]8fdbcd22010-05-05 02:54:523126 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233127 MockWrite(
3128 "GET / HTTP/1.1\r\n"
3129 "Host: www.example.org\r\n"
3130 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523131 };
3132
3133 MockRead data_reads1[] = {
3134 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3135 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3136 // Large content-length -- won't matter, as connection will be reset.
3137 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063138 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523139 };
3140
3141 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3142 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073143 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523144
[email protected]49639fa2011-12-20 23:22:413145 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523146
[email protected]49639fa2011-12-20 23:22:413147 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523148 EXPECT_EQ(ERR_IO_PENDING, rv);
3149
3150 rv = callback.WaitForResult();
3151 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3152}
3153
[email protected]7a67a8152010-11-05 18:31:103154// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3155// through a non-authenticating proxy. The request should fail with
3156// ERR_UNEXPECTED_PROXY_AUTH.
3157// Note that it is impossible to detect if an HTTP server returns a 407 through
3158// a non-authenticating proxy - there is nothing to indicate whether the
3159// response came from the proxy or the server, so it is treated as if the proxy
3160// issued the challenge.
[email protected]23e482282013-06-14 16:08:023161TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233162 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273163 HttpRequestInfo request;
3164 request.method = "GET";
bncce36dca22015-04-21 22:11:233165 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273166
rdsmith82957ad2015-09-16 19:42:033167 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513168 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073169 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063170 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103171
[email protected]7a67a8152010-11-05 18:31:103172 // Since we have proxy, should try to establish tunnel.
3173 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233174 MockWrite(
3175 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3176 "Host: www.example.org\r\n"
3177 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103178
bncce36dca22015-04-21 22:11:233179 MockWrite(
3180 "GET / HTTP/1.1\r\n"
3181 "Host: www.example.org\r\n"
3182 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103183 };
3184
3185 MockRead data_reads1[] = {
3186 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3187
3188 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3189 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3190 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063191 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103192 };
3193
3194 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3195 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073196 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063197 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073198 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103199
[email protected]49639fa2011-12-20 23:22:413200 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103201
[email protected]262eec82013-03-19 21:01:363202 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503203 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103204
[email protected]49639fa2011-12-20 23:22:413205 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103206 EXPECT_EQ(ERR_IO_PENDING, rv);
3207
3208 rv = callback1.WaitForResult();
3209 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463210 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403211 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103212 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403213 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103214 NetLog::PHASE_NONE);
3215 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403216 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103217 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3218 NetLog::PHASE_NONE);
3219}
[email protected]2df19bb2010-08-25 20:13:463220
[email protected]029c83b62013-01-24 05:28:203221// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023222TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203223 HttpRequestInfo request1;
3224 request1.method = "GET";
bncce36dca22015-04-21 22:11:233225 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203226
3227 HttpRequestInfo request2;
3228 request2.method = "GET";
bncce36dca22015-04-21 22:11:233229 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203230
3231 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033232 session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513233 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073234 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063235 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203236
3237 // Since we have proxy, should try to establish tunnel.
3238 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233239 MockWrite(
3240 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3241 "Host: www.example.org\r\n"
3242 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203243
bncce36dca22015-04-21 22:11:233244 MockWrite(
3245 "GET /1 HTTP/1.1\r\n"
3246 "Host: www.example.org\r\n"
3247 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203248
bncce36dca22015-04-21 22:11:233249 MockWrite(
3250 "GET /2 HTTP/1.1\r\n"
3251 "Host: www.example.org\r\n"
3252 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203253 };
3254
3255 // The proxy responds to the connect with a 407, using a persistent
3256 // connection.
3257 MockRead data_reads1[] = {
3258 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3259
3260 MockRead("HTTP/1.1 200 OK\r\n"),
3261 MockRead("Content-Length: 1\r\n\r\n"),
3262 MockRead(SYNCHRONOUS, "1"),
3263
3264 MockRead("HTTP/1.1 200 OK\r\n"),
3265 MockRead("Content-Length: 2\r\n\r\n"),
3266 MockRead(SYNCHRONOUS, "22"),
3267 };
3268
3269 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3270 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073271 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203272 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073273 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203274
3275 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363276 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503277 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203278
3279 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3280 EXPECT_EQ(ERR_IO_PENDING, rv);
3281
3282 rv = callback1.WaitForResult();
3283 EXPECT_EQ(OK, rv);
3284
3285 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3286 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503287 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203288 EXPECT_EQ(1, response1->headers->GetContentLength());
3289
3290 LoadTimingInfo load_timing_info1;
3291 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3292 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3293
3294 trans1.reset();
3295
3296 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363297 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503298 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203299
3300 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3301 EXPECT_EQ(ERR_IO_PENDING, rv);
3302
3303 rv = callback2.WaitForResult();
3304 EXPECT_EQ(OK, rv);
3305
3306 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3307 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503308 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203309 EXPECT_EQ(2, response2->headers->GetContentLength());
3310
3311 LoadTimingInfo load_timing_info2;
3312 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3313 TestLoadTimingReused(load_timing_info2);
3314
3315 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3316
3317 trans2.reset();
3318 session->CloseAllConnections();
3319}
3320
3321// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023322TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203323 HttpRequestInfo request1;
3324 request1.method = "GET";
bncce36dca22015-04-21 22:11:233325 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203326
3327 HttpRequestInfo request2;
3328 request2.method = "GET";
bncce36dca22015-04-21 22:11:233329 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203330
3331 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033332 session_deps_.proxy_service =
3333 ProxyService::CreateFixedFromPacResult("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 TestLoadTimingNotReusedWithPac(load_timing_info1,
3394 CONNECT_TIMING_HAS_SSL_TIMES);
3395
3396 trans1.reset();
3397
3398 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363399 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503400 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203401
3402 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3403 EXPECT_EQ(ERR_IO_PENDING, rv);
3404
3405 rv = callback2.WaitForResult();
3406 EXPECT_EQ(OK, rv);
3407
3408 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3409 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503410 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203411 EXPECT_EQ(2, response2->headers->GetContentLength());
3412
3413 LoadTimingInfo load_timing_info2;
3414 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3415 TestLoadTimingReusedWithPac(load_timing_info2);
3416
3417 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3418
3419 trans2.reset();
3420 session->CloseAllConnections();
3421}
3422
[email protected]2df19bb2010-08-25 20:13:463423// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023424TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273425 HttpRequestInfo request;
3426 request.method = "GET";
bncce36dca22015-04-21 22:11:233427 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273428
[email protected]2df19bb2010-08-25 20:13:463429 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033430 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513431 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073432 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063433 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463434
[email protected]2df19bb2010-08-25 20:13:463435 // Since we have proxy, should use full url
3436 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233437 MockWrite(
3438 "GET http://www.example.org/ HTTP/1.1\r\n"
3439 "Host: www.example.org\r\n"
3440 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:463441 };
3442
3443 MockRead data_reads1[] = {
3444 MockRead("HTTP/1.1 200 OK\r\n"),
3445 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3446 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063447 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463448 };
3449
3450 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3451 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073452 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063453 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073454 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463455
[email protected]49639fa2011-12-20 23:22:413456 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463457
[email protected]262eec82013-03-19 21:01:363458 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503459 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503460
[email protected]49639fa2011-12-20 23:22:413461 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463462 EXPECT_EQ(ERR_IO_PENDING, rv);
3463
3464 rv = callback1.WaitForResult();
3465 EXPECT_EQ(OK, rv);
3466
[email protected]58e32bb2013-01-21 18:23:253467 LoadTimingInfo load_timing_info;
3468 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3469 TestLoadTimingNotReused(load_timing_info,
3470 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3471
[email protected]2df19bb2010-08-25 20:13:463472 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503473 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463474
3475 EXPECT_TRUE(response->headers->IsKeepAlive());
3476 EXPECT_EQ(200, response->headers->response_code());
3477 EXPECT_EQ(100, response->headers->GetContentLength());
3478 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3479
3480 // The password prompt info should not be set.
3481 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3482}
3483
[email protected]7642b5ae2010-09-01 20:55:173484// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023485TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273486 HttpRequestInfo request;
3487 request.method = "GET";
bncce36dca22015-04-21 22:11:233488 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273489 request.load_flags = 0;
3490
[email protected]7642b5ae2010-09-01 20:55:173491 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033492 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513493 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073494 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063495 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173496
bncce36dca22015-04-21 22:11:233497 // fetch http://www.example.org/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463498 scoped_ptr<SpdyFrame> req(
3499 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133500 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:173501
[email protected]23e482282013-06-14 16:08:023502 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3503 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173504 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133505 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:173506 };
3507
rch8e6c6c42015-05-01 14:05:133508 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3509 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073510 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173511
[email protected]8ddf8322012-02-23 18:08:063512 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023513 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073514 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173515
[email protected]49639fa2011-12-20 23:22:413516 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173517
[email protected]262eec82013-03-19 21:01:363518 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503519 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503520
[email protected]49639fa2011-12-20 23:22:413521 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173522 EXPECT_EQ(ERR_IO_PENDING, rv);
3523
3524 rv = callback1.WaitForResult();
3525 EXPECT_EQ(OK, rv);
3526
[email protected]58e32bb2013-01-21 18:23:253527 LoadTimingInfo load_timing_info;
3528 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3529 TestLoadTimingNotReused(load_timing_info,
3530 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3531
[email protected]7642b5ae2010-09-01 20:55:173532 const HttpResponseInfo* response = trans->GetResponseInfo();
3533 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503534 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173535 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3536
3537 std::string response_data;
3538 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233539 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173540}
3541
[email protected]1c173852014-06-19 12:51:503542// Verifies that a session which races and wins against the owning transaction
3543// (completing prior to host resolution), doesn't fail the transaction.
3544// Regression test for crbug.com/334413.
3545TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3546 HttpRequestInfo request;
3547 request.method = "GET";
bncce36dca22015-04-21 22:11:233548 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:503549 request.load_flags = 0;
3550
3551 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033552 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513553 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:503554 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063555 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:503556
bncce36dca22015-04-21 22:11:233557 // Fetch http://www.example.org/ through the SPDY proxy.
[email protected]1c173852014-06-19 12:51:503558 scoped_ptr<SpdyFrame> req(
3559 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133560 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:503561
3562 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3563 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3564 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133565 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:503566 };
3567
rch8e6c6c42015-05-01 14:05:133568 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3569 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:503570 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3571
3572 SSLSocketDataProvider ssl(ASYNC, OK);
3573 ssl.SetNextProto(GetParam());
3574 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3575
3576 TestCompletionCallback callback1;
3577
3578 scoped_ptr<HttpTransaction> trans(
3579 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3580
3581 // Stall the hostname resolution begun by the transaction.
3582 session_deps_.host_resolver->set_synchronous_mode(false);
3583 session_deps_.host_resolver->set_ondemand_mode(true);
3584
3585 int rv = trans->Start(&request, callback1.callback(), log.bound());
3586 EXPECT_EQ(ERR_IO_PENDING, rv);
3587
3588 // Race a session to the proxy, which completes first.
3589 session_deps_.host_resolver->set_ondemand_mode(false);
3590 SpdySessionKey key(
3591 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3592 base::WeakPtr<SpdySession> spdy_session =
mmenke6b3af6e2015-09-12 02:06:063593 CreateSecureSpdySession(session, key, log.bound());
[email protected]1c173852014-06-19 12:51:503594
3595 // Unstall the resolution begun by the transaction.
3596 session_deps_.host_resolver->set_ondemand_mode(true);
3597 session_deps_.host_resolver->ResolveAllPending();
3598
3599 EXPECT_FALSE(callback1.have_result());
3600 rv = callback1.WaitForResult();
3601 EXPECT_EQ(OK, rv);
3602
3603 const HttpResponseInfo* response = trans->GetResponseInfo();
3604 ASSERT_TRUE(response != NULL);
3605 ASSERT_TRUE(response->headers.get() != NULL);
3606 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3607
3608 std::string response_data;
3609 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3610 EXPECT_EQ(kUploadData, response_data);
3611}
3612
[email protected]dc7bd1c52010-11-12 00:01:133613// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023614TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273615 HttpRequestInfo request;
3616 request.method = "GET";
bncce36dca22015-04-21 22:11:233617 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273618 request.load_flags = 0;
3619
[email protected]79cb5c12011-09-12 13:12:043620 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033621 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:513622 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073623 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063624 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133625
[email protected]dc7bd1c52010-11-12 00:01:133626 // The first request will be a bare GET, the second request will be a
3627 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193628 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463629 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133630 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463631 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133632 };
[email protected]ff98d7f02012-03-22 21:44:193633 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463634 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3635 arraysize(kExtraAuthorizationHeaders) / 2,
3636 false,
3637 3,
3638 LOWEST,
3639 false));
[email protected]dc7bd1c52010-11-12 00:01:133640 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133641 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:133642 };
3643
3644 // The first response is a 407 proxy authentication challenge, and the second
3645 // response will be a 200 response since the second request includes a valid
3646 // Authorization header.
3647 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463648 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133649 };
[email protected]ff98d7f02012-03-22 21:44:193650 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023651 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133652 "407 Proxy Authentication Required",
3653 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3654 1));
[email protected]ff98d7f02012-03-22 21:44:193655 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023656 spdy_util_.ConstructSpdyBodyFrame(1, true));
3657 scoped_ptr<SpdyFrame> resp_data(
3658 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3659 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133660 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133661 CreateMockRead(*resp_authentication, 1),
3662 CreateMockRead(*body_authentication, 2),
3663 CreateMockRead(*resp_data, 4),
3664 CreateMockRead(*body_data, 5),
3665 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:133666 };
3667
rch8e6c6c42015-05-01 14:05:133668 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3669 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073670 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133671
[email protected]8ddf8322012-02-23 18:08:063672 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023673 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073674 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133675
[email protected]49639fa2011-12-20 23:22:413676 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133677
[email protected]262eec82013-03-19 21:01:363678 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503679 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133680
[email protected]49639fa2011-12-20 23:22:413681 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133682 EXPECT_EQ(ERR_IO_PENDING, rv);
3683
3684 rv = callback1.WaitForResult();
3685 EXPECT_EQ(OK, rv);
3686
3687 const HttpResponseInfo* const response = trans->GetResponseInfo();
3688
3689 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503690 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133691 EXPECT_EQ(407, response->headers->response_code());
3692 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043693 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133694
[email protected]49639fa2011-12-20 23:22:413695 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133696
[email protected]49639fa2011-12-20 23:22:413697 rv = trans->RestartWithAuth(
3698 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133699 EXPECT_EQ(ERR_IO_PENDING, rv);
3700
3701 rv = callback2.WaitForResult();
3702 EXPECT_EQ(OK, rv);
3703
3704 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3705
3706 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503707 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133708 EXPECT_EQ(200, response_restart->headers->response_code());
3709 // The password prompt info should not be set.
3710 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3711}
3712
[email protected]d9da5fe2010-10-13 22:37:163713// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023714TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273715 HttpRequestInfo request;
3716 request.method = "GET";
bncce36dca22015-04-21 22:11:233717 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273718 request.load_flags = 0;
3719
[email protected]d9da5fe2010-10-13 22:37:163720 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033721 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513722 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073723 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063724 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163725
[email protected]262eec82013-03-19 21:01:363726 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503727 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163728
bncce36dca22015-04-21 22:11:233729 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343730 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233731 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3732 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:163733
bncce36dca22015-04-21 22:11:233734 const char get[] =
3735 "GET / HTTP/1.1\r\n"
3736 "Host: www.example.org\r\n"
3737 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193738 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023739 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3740 scoped_ptr<SpdyFrame> conn_resp(
3741 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163742 const char resp[] = "HTTP/1.1 200 OK\r\n"
3743 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193744 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023745 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193746 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023747 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193748 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203749 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043750
3751 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133752 CreateMockWrite(*connect, 0),
3753 CreateMockWrite(*wrapped_get, 2),
3754 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:043755 };
3756
[email protected]d9da5fe2010-10-13 22:37:163757 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133758 CreateMockRead(*conn_resp, 1, ASYNC),
3759 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
3760 CreateMockRead(*wrapped_body, 4, ASYNC),
3761 CreateMockRead(*wrapped_body, 5, ASYNC),
3762 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:163763 };
3764
rch8e6c6c42015-05-01 14:05:133765 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3766 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073767 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163768
[email protected]8ddf8322012-02-23 18:08:063769 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023770 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073771 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063772 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163774
[email protected]49639fa2011-12-20 23:22:413775 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163776
[email protected]49639fa2011-12-20 23:22:413777 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163778 EXPECT_EQ(ERR_IO_PENDING, rv);
3779
3780 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:133781 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:163782
[email protected]58e32bb2013-01-21 18:23:253783 LoadTimingInfo load_timing_info;
3784 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3785 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3786
[email protected]d9da5fe2010-10-13 22:37:163787 const HttpResponseInfo* response = trans->GetResponseInfo();
3788 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503789 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163790 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3791
3792 std::string response_data;
3793 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3794 EXPECT_EQ("1234567890", response_data);
3795}
3796
3797// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023798TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273799 HttpRequestInfo request;
3800 request.method = "GET";
bncce36dca22015-04-21 22:11:233801 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273802 request.load_flags = 0;
3803
[email protected]d9da5fe2010-10-13 22:37:163804 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033805 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513806 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073807 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063808 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163809
[email protected]262eec82013-03-19 21:01:363810 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503811 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163812
bncce36dca22015-04-21 22:11:233813 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343814 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233815 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3816 // fetch https://www.example.org/ via SPDY
3817 const char kMyUrl[] = "https://www.example.org/";
[email protected]cdf8f7e72013-05-23 10:56:463818 scoped_ptr<SpdyFrame> get(
3819 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023820 scoped_ptr<SpdyFrame> wrapped_get(
3821 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3822 scoped_ptr<SpdyFrame> conn_resp(
3823 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3824 scoped_ptr<SpdyFrame> get_resp(
3825 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193826 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023827 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3828 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3829 scoped_ptr<SpdyFrame> wrapped_body(
3830 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193831 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203832 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193833 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203834 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043835
3836 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:093837 CreateMockWrite(*connect, 0),
3838 CreateMockWrite(*wrapped_get, 2),
3839 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:043840 CreateMockWrite(*window_update_body, 7),
3841 };
3842
[email protected]d9da5fe2010-10-13 22:37:163843 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:093844 CreateMockRead(*conn_resp, 1, ASYNC),
3845 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:133846 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:093847 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:133848 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163849 };
3850
rch32320842015-05-16 15:57:093851 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3852 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073853 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163854
[email protected]8ddf8322012-02-23 18:08:063855 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023856 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073857 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063858 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023859 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073860 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163861
[email protected]49639fa2011-12-20 23:22:413862 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163863
[email protected]49639fa2011-12-20 23:22:413864 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163865 EXPECT_EQ(ERR_IO_PENDING, rv);
3866
rch32320842015-05-16 15:57:093867 // Allow the SpdyProxyClientSocket's write callback to complete.
3868 base::MessageLoop::current()->RunUntilIdle();
3869 // Now allow the read of the response to complete.
3870 spdy_data.CompleteRead();
[email protected]d9da5fe2010-10-13 22:37:163871 rv = callback1.WaitForResult();
3872 EXPECT_EQ(OK, rv);
3873
[email protected]58e32bb2013-01-21 18:23:253874 LoadTimingInfo load_timing_info;
3875 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3876 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3877
[email protected]d9da5fe2010-10-13 22:37:163878 const HttpResponseInfo* response = trans->GetResponseInfo();
3879 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503880 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163881 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3882
3883 std::string response_data;
3884 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233885 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163886}
3887
3888// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023889TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273890 HttpRequestInfo request;
3891 request.method = "GET";
bncce36dca22015-04-21 22:11:233892 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273893 request.load_flags = 0;
3894
[email protected]d9da5fe2010-10-13 22:37:163895 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033896 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513897 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073898 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063899 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163900
[email protected]262eec82013-03-19 21:01:363901 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503902 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163903
bncce36dca22015-04-21 22:11:233904 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343905 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233906 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:203907 scoped_ptr<SpdyFrame> get(
3908 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163909
3910 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133911 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:163912 };
3913
[email protected]23e482282013-06-14 16:08:023914 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3915 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163916 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133917 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:163918 };
3919
rch8e6c6c42015-05-01 14:05:133920 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3921 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073922 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163923
[email protected]8ddf8322012-02-23 18:08:063924 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023925 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073926 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063927 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023928 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073929 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163930
[email protected]49639fa2011-12-20 23:22:413931 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163932
[email protected]49639fa2011-12-20 23:22:413933 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163934 EXPECT_EQ(ERR_IO_PENDING, rv);
3935
3936 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173937 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163938
[email protected]4eddbc732012-08-09 05:40:173939 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163940}
3941
[email protected]f6c63db52013-02-02 00:35:223942// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3943// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023944TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223945 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3946 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033947 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513948 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073949 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:063950 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:503951 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223952
3953 HttpRequestInfo request1;
3954 request1.method = "GET";
bncce36dca22015-04-21 22:11:233955 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223956 request1.load_flags = 0;
3957
3958 HttpRequestInfo request2;
3959 request2.method = "GET";
bncce36dca22015-04-21 22:11:233960 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:223961 request2.load_flags = 0;
3962
bncce36dca22015-04-21 22:11:233963 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343964 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233965 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023966 scoped_ptr<SpdyFrame> conn_resp1(
3967 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223968
bncce36dca22015-04-21 22:11:233969 // Fetch https://www.example.org/ via HTTP.
3970 const char get1[] =
3971 "GET / HTTP/1.1\r\n"
3972 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223973 "Connection: keep-alive\r\n\r\n";
3974 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023975 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223976 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3977 "Content-Length: 1\r\n\r\n";
3978 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023979 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3980 scoped_ptr<SpdyFrame> wrapped_body1(
3981 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223982 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203983 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223984
bncce36dca22015-04-21 22:11:233985 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293986 SpdyHeaderBlock connect2_block;
bnc7ecc1122015-09-28 13:22:493987 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]745aa9c2014-06-27 02:21:293988 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnc9b79a572015-09-02 12:25:033989 if (GetParam() == kProtoHTTP2) {
bnc6b996d532015-07-29 10:51:323990 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
3991 } else {
bnc6b996d532015-07-29 10:51:323992 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
bnc7ecc1122015-09-28 13:22:493993 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
bnc6b996d532015-07-29 10:51:323994 }
[email protected]f6c63db52013-02-02 00:35:223995 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293996 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393997
[email protected]23e482282013-06-14 16:08:023998 scoped_ptr<SpdyFrame> conn_resp2(
3999 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:224000
bncce36dca22015-04-21 22:11:234001 // Fetch https://mail.example.org/ via HTTP.
4002 const char get2[] =
4003 "GET / HTTP/1.1\r\n"
4004 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224005 "Connection: keep-alive\r\n\r\n";
4006 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024007 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224008 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4009 "Content-Length: 2\r\n\r\n";
4010 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024011 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224012 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024013 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224014
4015 MockWrite spdy_writes[] = {
4016 CreateMockWrite(*connect1, 0),
4017 CreateMockWrite(*wrapped_get1, 2),
4018 CreateMockWrite(*connect2, 5),
4019 CreateMockWrite(*wrapped_get2, 7),
4020 };
4021
4022 MockRead spdy_reads[] = {
4023 CreateMockRead(*conn_resp1, 1, ASYNC),
4024 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4025 CreateMockRead(*wrapped_body1, 4, ASYNC),
4026 CreateMockRead(*conn_resp2, 6, ASYNC),
4027 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
4028 CreateMockRead(*wrapped_body2, 9, ASYNC),
4029 MockRead(ASYNC, 0, 10),
4030 };
4031
mmenke11eb5152015-06-09 14:50:504032 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4033 arraysize(spdy_writes));
4034 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224035
4036 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024037 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224039 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504040 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224041 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504042 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:224043
4044 TestCompletionCallback callback;
4045
[email protected]262eec82013-03-19 21:01:364046 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504047 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224048 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504049 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224050
4051 LoadTimingInfo load_timing_info;
4052 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4053 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4054
4055 const HttpResponseInfo* response = trans->GetResponseInfo();
4056 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504057 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224058 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4059
4060 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294061 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504062 rv = trans->Read(buf.get(), 256, callback.callback());
4063 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224064
[email protected]262eec82013-03-19 21:01:364065 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504066 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224067 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504068 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224069
4070 LoadTimingInfo load_timing_info2;
4071 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4072 // Even though the SPDY connection is reused, a new tunnelled connection has
4073 // to be created, so the socket's load timing looks like a fresh connection.
4074 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
4075
4076 // The requests should have different IDs, since they each are using their own
4077 // separate stream.
4078 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4079
mmenke11eb5152015-06-09 14:50:504080 rv = trans2->Read(buf.get(), 256, callback.callback());
4081 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224082}
4083
4084// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4085// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:024086TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224087 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
4088 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034089 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514090 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074091 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:064092 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504093 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224094
4095 HttpRequestInfo request1;
4096 request1.method = "GET";
bncce36dca22015-04-21 22:11:234097 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224098 request1.load_flags = 0;
4099
4100 HttpRequestInfo request2;
4101 request2.method = "GET";
bncce36dca22015-04-21 22:11:234102 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:224103 request2.load_flags = 0;
4104
bncce36dca22015-04-21 22:11:234105 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:344106 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234107 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:024108 scoped_ptr<SpdyFrame> conn_resp1(
4109 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224110
bncce36dca22015-04-21 22:11:234111 // Fetch https://www.example.org/ via HTTP.
4112 const char get1[] =
4113 "GET / HTTP/1.1\r\n"
4114 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224115 "Connection: keep-alive\r\n\r\n";
4116 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024117 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224118 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4119 "Content-Length: 1\r\n\r\n";
4120 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024121 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
4122 scoped_ptr<SpdyFrame> wrapped_body1(
4123 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:224124 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204125 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224126
bncce36dca22015-04-21 22:11:234127 // Fetch https://www.example.org/2 via HTTP.
4128 const char get2[] =
4129 "GET /2 HTTP/1.1\r\n"
4130 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224131 "Connection: keep-alive\r\n\r\n";
4132 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024133 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224134 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4135 "Content-Length: 2\r\n\r\n";
4136 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024137 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224138 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024139 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224140
4141 MockWrite spdy_writes[] = {
4142 CreateMockWrite(*connect1, 0),
4143 CreateMockWrite(*wrapped_get1, 2),
4144 CreateMockWrite(*wrapped_get2, 5),
4145 };
4146
4147 MockRead spdy_reads[] = {
4148 CreateMockRead(*conn_resp1, 1, ASYNC),
4149 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4150 CreateMockRead(*wrapped_body1, 4, ASYNC),
4151 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4152 CreateMockRead(*wrapped_body2, 7, ASYNC),
4153 MockRead(ASYNC, 0, 8),
4154 };
4155
mmenke11eb5152015-06-09 14:50:504156 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4157 arraysize(spdy_writes));
4158 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224159
4160 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024161 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504162 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224163 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224165
4166 TestCompletionCallback callback;
4167
[email protected]262eec82013-03-19 21:01:364168 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504169 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224170 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4171 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:224172
4173 rv = callback.WaitForResult();
4174 EXPECT_EQ(OK, rv);
4175
4176 LoadTimingInfo load_timing_info;
4177 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4178 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4179
4180 const HttpResponseInfo* response = trans->GetResponseInfo();
4181 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504182 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224183 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4184
4185 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294186 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504187 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224188 trans.reset();
4189
[email protected]262eec82013-03-19 21:01:364190 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504191 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224192 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4193 EXPECT_EQ(ERR_IO_PENDING, rv);
4194
[email protected]f6c63db52013-02-02 00:35:224195 rv = callback.WaitForResult();
4196 EXPECT_EQ(OK, rv);
4197
4198 LoadTimingInfo load_timing_info2;
4199 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4200 TestLoadTimingReused(load_timing_info2);
4201
4202 // The requests should have the same ID.
4203 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4204
[email protected]90499482013-06-01 00:39:504205 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224206}
4207
4208// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4209// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:504210TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:224211 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034212 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514213 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074214 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:064215 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504216 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224217
4218 HttpRequestInfo request1;
4219 request1.method = "GET";
bncce36dca22015-04-21 22:11:234220 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224221 request1.load_flags = 0;
4222
4223 HttpRequestInfo request2;
4224 request2.method = "GET";
bncce36dca22015-04-21 22:11:234225 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224226 request2.load_flags = 0;
4227
bncce36dca22015-04-21 22:11:234228 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024229 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234230 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294231 scoped_ptr<SpdyFrame> get1(
4232 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024233 scoped_ptr<SpdyFrame> get_resp1(
4234 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4235 scoped_ptr<SpdyFrame> body1(
4236 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224237
bncce36dca22015-04-21 22:11:234238 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024239 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234240 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294241 scoped_ptr<SpdyFrame> get2(
4242 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024243 scoped_ptr<SpdyFrame> get_resp2(
4244 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4245 scoped_ptr<SpdyFrame> body2(
4246 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224247
4248 MockWrite spdy_writes[] = {
4249 CreateMockWrite(*get1, 0),
4250 CreateMockWrite(*get2, 3),
4251 };
4252
4253 MockRead spdy_reads[] = {
4254 CreateMockRead(*get_resp1, 1, ASYNC),
4255 CreateMockRead(*body1, 2, ASYNC),
4256 CreateMockRead(*get_resp2, 4, ASYNC),
4257 CreateMockRead(*body2, 5, ASYNC),
4258 MockRead(ASYNC, 0, 6),
4259 };
4260
mmenke11eb5152015-06-09 14:50:504261 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4262 arraysize(spdy_writes));
4263 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224264
4265 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024266 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504267 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224268
4269 TestCompletionCallback callback;
4270
[email protected]262eec82013-03-19 21:01:364271 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504272 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224273 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504274 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224275
4276 LoadTimingInfo load_timing_info;
4277 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4278 TestLoadTimingNotReused(load_timing_info,
4279 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
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));
mmenke11eb5152015-06-09 14:50:504288 rv = trans->Read(buf.get(), 256, callback.callback());
4289 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224290 // Delete the first request, so the second one can reuse the socket.
4291 trans.reset();
4292
[email protected]262eec82013-03-19 21:01:364293 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504294 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224295 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504296 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224297
4298 LoadTimingInfo load_timing_info2;
4299 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4300 TestLoadTimingReused(load_timing_info2);
4301
4302 // The requests should have the same ID.
4303 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4304
mmenke11eb5152015-06-09 14:50:504305 rv = trans2->Read(buf.get(), 256, callback.callback());
4306 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224307}
4308
[email protected]2df19bb2010-08-25 20:13:464309// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024310TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464311 HttpRequestInfo request;
4312 request.method = "GET";
bncce36dca22015-04-21 22:11:234313 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464314 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294315 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464316
[email protected]79cb5c12011-09-12 13:12:044317 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034318 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514319 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074320 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:064321 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274322
[email protected]2df19bb2010-08-25 20:13:464323 // Since we have proxy, should use full url
4324 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234325 MockWrite(
4326 "GET http://www.example.org/ HTTP/1.1\r\n"
4327 "Host: www.example.org\r\n"
4328 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464329
bncce36dca22015-04-21 22:11:234330 // After calling trans->RestartWithAuth(), this is the request we should
4331 // be issuing -- the final header line contains the credentials.
4332 MockWrite(
4333 "GET http://www.example.org/ HTTP/1.1\r\n"
4334 "Host: www.example.org\r\n"
4335 "Proxy-Connection: keep-alive\r\n"
4336 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464337 };
4338
4339 // The proxy responds to the GET with a 407, using a persistent
4340 // connection.
4341 MockRead data_reads1[] = {
4342 // No credentials.
4343 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4344 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4345 MockRead("Proxy-Connection: keep-alive\r\n"),
4346 MockRead("Content-Length: 0\r\n\r\n"),
4347
4348 MockRead("HTTP/1.1 200 OK\r\n"),
4349 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4350 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064351 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464352 };
4353
4354 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4355 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074356 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064357 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464359
[email protected]49639fa2011-12-20 23:22:414360 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464361
[email protected]262eec82013-03-19 21:01:364362 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504363 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504364
[email protected]49639fa2011-12-20 23:22:414365 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464366 EXPECT_EQ(ERR_IO_PENDING, rv);
4367
4368 rv = callback1.WaitForResult();
4369 EXPECT_EQ(OK, rv);
4370
[email protected]58e32bb2013-01-21 18:23:254371 LoadTimingInfo load_timing_info;
4372 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4373 TestLoadTimingNotReused(load_timing_info,
4374 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4375
[email protected]2df19bb2010-08-25 20:13:464376 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504377 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504378 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464379 EXPECT_EQ(407, response->headers->response_code());
4380 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044381 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464382
[email protected]49639fa2011-12-20 23:22:414383 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464384
[email protected]49639fa2011-12-20 23:22:414385 rv = trans->RestartWithAuth(
4386 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464387 EXPECT_EQ(ERR_IO_PENDING, rv);
4388
4389 rv = callback2.WaitForResult();
4390 EXPECT_EQ(OK, rv);
4391
[email protected]58e32bb2013-01-21 18:23:254392 load_timing_info = LoadTimingInfo();
4393 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4394 // Retrying with HTTP AUTH is considered to be reusing a socket.
4395 TestLoadTimingReused(load_timing_info);
4396
[email protected]2df19bb2010-08-25 20:13:464397 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504398 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464399
4400 EXPECT_TRUE(response->headers->IsKeepAlive());
4401 EXPECT_EQ(200, response->headers->response_code());
4402 EXPECT_EQ(100, response->headers->GetContentLength());
4403 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4404
4405 // The password prompt info should not be set.
4406 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4407}
4408
[email protected]23e482282013-06-14 16:08:024409void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084410 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424411 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084412 request.method = "GET";
bncce36dca22015-04-21 22:11:234413 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084414 request.load_flags = 0;
4415
[email protected]cb9bf6ca2011-01-28 13:15:274416 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034417 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenke6b3af6e2015-09-12 02:06:064418 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274419
[email protected]c744cf22009-02-27 07:28:084420 // Since we have proxy, should try to establish tunnel.
4421 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:234422 MockWrite(
4423 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4424 "Host: www.example.org\r\n"
4425 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084426 };
4427
4428 MockRead data_reads[] = {
4429 status,
4430 MockRead("Content-Length: 10\r\n\r\n"),
4431 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064432 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084433 };
4434
[email protected]31a2bfe2010-02-09 08:03:394435 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4436 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074437 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084438
[email protected]49639fa2011-12-20 23:22:414439 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084440
[email protected]262eec82013-03-19 21:01:364441 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504442 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504443
[email protected]49639fa2011-12-20 23:22:414444 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424445 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084446
4447 rv = callback.WaitForResult();
4448 EXPECT_EQ(expected_status, rv);
4449}
4450
[email protected]23e482282013-06-14 16:08:024451void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234452 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084453 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424454 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084455}
4456
[email protected]23e482282013-06-14 16:08:024457TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084458 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4459}
4460
[email protected]23e482282013-06-14 16:08:024461TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084462 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4463}
4464
[email protected]23e482282013-06-14 16:08:024465TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084466 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4467}
4468
[email protected]23e482282013-06-14 16:08:024469TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084470 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4471}
4472
[email protected]23e482282013-06-14 16:08:024473TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084474 ConnectStatusHelper(
4475 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4476}
4477
[email protected]23e482282013-06-14 16:08:024478TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084479 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4480}
4481
[email protected]23e482282013-06-14 16:08:024482TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084483 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4484}
4485
[email protected]23e482282013-06-14 16:08:024486TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084487 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4488}
4489
[email protected]23e482282013-06-14 16:08:024490TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084491 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4492}
4493
[email protected]23e482282013-06-14 16:08:024494TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084495 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4496}
4497
[email protected]23e482282013-06-14 16:08:024498TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084499 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4500}
4501
[email protected]23e482282013-06-14 16:08:024502TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084503 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4504}
4505
[email protected]23e482282013-06-14 16:08:024506TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084507 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4508}
4509
[email protected]23e482282013-06-14 16:08:024510TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084511 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4512}
4513
[email protected]23e482282013-06-14 16:08:024514TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084515 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4516}
4517
[email protected]23e482282013-06-14 16:08:024518TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084519 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4520}
4521
[email protected]0a17aab32014-04-24 03:32:374522TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4523 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4524}
4525
[email protected]23e482282013-06-14 16:08:024526TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084527 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4528}
4529
[email protected]23e482282013-06-14 16:08:024530TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084531 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4532}
4533
[email protected]23e482282013-06-14 16:08:024534TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084535 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4536}
4537
[email protected]23e482282013-06-14 16:08:024538TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084539 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4540}
4541
[email protected]23e482282013-06-14 16:08:024542TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084543 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4544}
4545
[email protected]23e482282013-06-14 16:08:024546TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084547 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4548}
4549
[email protected]23e482282013-06-14 16:08:024550TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084551 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4552}
4553
[email protected]23e482282013-06-14 16:08:024554TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084555 ConnectStatusHelperWithExpectedStatus(
4556 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544557 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084558}
4559
[email protected]23e482282013-06-14 16:08:024560TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084561 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4562}
4563
[email protected]23e482282013-06-14 16:08:024564TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084565 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4566}
4567
[email protected]23e482282013-06-14 16:08:024568TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084569 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4570}
4571
[email protected]23e482282013-06-14 16:08:024572TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084573 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4574}
4575
[email protected]23e482282013-06-14 16:08:024576TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084577 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4578}
4579
[email protected]23e482282013-06-14 16:08:024580TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084581 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4582}
4583
[email protected]23e482282013-06-14 16:08:024584TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084585 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4586}
4587
[email protected]23e482282013-06-14 16:08:024588TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084589 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4590}
4591
[email protected]23e482282013-06-14 16:08:024592TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084593 ConnectStatusHelper(
4594 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4595}
4596
[email protected]23e482282013-06-14 16:08:024597TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084598 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4599}
4600
[email protected]23e482282013-06-14 16:08:024601TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084602 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4603}
4604
[email protected]23e482282013-06-14 16:08:024605TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084606 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4607}
4608
[email protected]23e482282013-06-14 16:08:024609TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084610 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4611}
4612
[email protected]23e482282013-06-14 16:08:024613TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084614 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4615}
4616
[email protected]23e482282013-06-14 16:08:024617TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084618 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4619}
4620
[email protected]23e482282013-06-14 16:08:024621TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084622 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4623}
4624
[email protected]038e9a32008-10-08 22:40:164625// Test the flow when both the proxy server AND origin server require
4626// authentication. Again, this uses basic auth for both since that is
4627// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024628TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274629 HttpRequestInfo request;
4630 request.method = "GET";
bncce36dca22015-04-21 22:11:234631 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274632 request.load_flags = 0;
4633
[email protected]038e9a32008-10-08 22:40:164634 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034635 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenke6b3af6e2015-09-12 02:06:064636 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:074637
4638 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414639 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164640
[email protected]f9ee6b52008-11-08 06:46:234641 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234642 MockWrite(
4643 "GET http://www.example.org/ HTTP/1.1\r\n"
4644 "Host: www.example.org\r\n"
4645 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:234646 };
4647
[email protected]038e9a32008-10-08 22:40:164648 MockRead data_reads1[] = {
4649 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4650 // Give a couple authenticate options (only the middle one is actually
4651 // supported).
[email protected]22927ad2009-09-21 19:56:194652 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164653 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4654 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4655 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4656 // Large content-length -- won't matter, as connection will be reset.
4657 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064658 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164659 };
4660
4661 // After calling trans->RestartWithAuth() the first time, this is the
4662 // request we should be issuing -- the final header line contains the
4663 // proxy's credentials.
4664 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:234665 MockWrite(
4666 "GET http://www.example.org/ HTTP/1.1\r\n"
4667 "Host: www.example.org\r\n"
4668 "Proxy-Connection: keep-alive\r\n"
4669 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164670 };
4671
4672 // Now the proxy server lets the request pass through to origin server.
4673 // The origin server responds with a 401.
4674 MockRead data_reads2[] = {
4675 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4676 // Note: We are using the same realm-name as the proxy server. This is
4677 // completely valid, as realms are unique across hosts.
4678 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4679 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4680 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064681 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164682 };
4683
4684 // After calling trans->RestartWithAuth() the second time, we should send
4685 // the credentials for both the proxy and origin server.
4686 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:234687 MockWrite(
4688 "GET http://www.example.org/ HTTP/1.1\r\n"
4689 "Host: www.example.org\r\n"
4690 "Proxy-Connection: keep-alive\r\n"
4691 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4692 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164693 };
4694
4695 // Lastly we get the desired content.
4696 MockRead data_reads3[] = {
4697 MockRead("HTTP/1.0 200 OK\r\n"),
4698 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4699 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064700 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164701 };
4702
[email protected]31a2bfe2010-02-09 08:03:394703 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4704 data_writes1, arraysize(data_writes1));
4705 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4706 data_writes2, arraysize(data_writes2));
4707 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4708 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074709 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4710 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4711 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164712
[email protected]49639fa2011-12-20 23:22:414713 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164714
[email protected]49639fa2011-12-20 23:22:414715 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424716 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164717
4718 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424719 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164720
[email protected]1c773ea12009-04-28 19:58:424721 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504722 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044723 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164724
[email protected]49639fa2011-12-20 23:22:414725 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164726
[email protected]49639fa2011-12-20 23:22:414727 rv = trans->RestartWithAuth(
4728 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424729 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164730
4731 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424732 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164733
4734 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504735 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044736 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164737
[email protected]49639fa2011-12-20 23:22:414738 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164739
[email protected]49639fa2011-12-20 23:22:414740 rv = trans->RestartWithAuth(
4741 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424742 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164743
4744 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424745 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164746
4747 response = trans->GetResponseInfo();
4748 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4749 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164750}
[email protected]4ddaf2502008-10-23 18:26:194751
[email protected]ea9dc9a2009-09-05 00:43:324752// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4753// can't hook into its internals to cause it to generate predictable NTLM
4754// authorization headers.
4755#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294756// The NTLM authentication unit tests were generated by capturing the HTTP
4757// requests and responses using Fiddler 2 and inspecting the generated random
4758// bytes in the debugger.
4759
4760// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024761TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424762 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244763 request.method = "GET";
4764 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544765
4766 // Ensure load is not disrupted by flags which suppress behaviour specific
4767 // to other auth schemes.
4768 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244769
[email protected]cb9bf6ca2011-01-28 13:15:274770 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4771 MockGetHostName);
mmenke6b3af6e2015-09-12 02:06:064772 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274773
[email protected]3f918782009-02-28 01:29:244774 MockWrite data_writes1[] = {
4775 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4776 "Host: 172.22.68.17\r\n"
4777 "Connection: keep-alive\r\n\r\n"),
4778 };
4779
4780 MockRead data_reads1[] = {
4781 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044782 // Negotiate and NTLM are often requested together. However, we only want
4783 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4784 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244785 MockRead("WWW-Authenticate: NTLM\r\n"),
4786 MockRead("Connection: close\r\n"),
4787 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364788 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244789 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064790 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244791 };
4792
4793 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224794 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244795 // request we should be issuing -- the final header line contains a Type
4796 // 1 message.
4797 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4798 "Host: 172.22.68.17\r\n"
4799 "Connection: keep-alive\r\n"
4800 "Authorization: NTLM "
4801 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4802
4803 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4804 // (the credentials for the origin server). The second request continues
4805 // on the same connection.
4806 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4807 "Host: 172.22.68.17\r\n"
4808 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294809 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4810 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4811 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4812 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4813 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244814 };
4815
4816 MockRead data_reads2[] = {
4817 // The origin server responds with a Type 2 message.
4818 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4819 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294820 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244821 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4822 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4823 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4824 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4825 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4826 "BtAAAAAAA=\r\n"),
4827 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364828 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244829 MockRead("You are not authorized to view this page\r\n"),
4830
4831 // Lastly we get the desired content.
4832 MockRead("HTTP/1.1 200 OK\r\n"),
4833 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4834 MockRead("Content-Length: 13\r\n\r\n"),
4835 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064836 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244837 };
4838
[email protected]31a2bfe2010-02-09 08:03:394839 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4840 data_writes1, arraysize(data_writes1));
4841 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4842 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074843 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4844 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244845
[email protected]49639fa2011-12-20 23:22:414846 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244847
[email protected]262eec82013-03-19 21:01:364848 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504849 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504850
[email protected]49639fa2011-12-20 23:22:414851 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424852 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244853
4854 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424855 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244856
[email protected]0757e7702009-03-27 04:00:224857 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4858
[email protected]1c773ea12009-04-28 19:58:424859 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044860 ASSERT_FALSE(response == NULL);
4861 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244862
[email protected]49639fa2011-12-20 23:22:414863 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254864
[email protected]f3cf9802011-10-28 18:44:584865 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414866 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254867 EXPECT_EQ(ERR_IO_PENDING, rv);
4868
4869 rv = callback2.WaitForResult();
4870 EXPECT_EQ(OK, rv);
4871
4872 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4873
4874 response = trans->GetResponseInfo();
4875 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254876 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4877
[email protected]49639fa2011-12-20 23:22:414878 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244879
[email protected]49639fa2011-12-20 23:22:414880 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424881 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244882
[email protected]0757e7702009-03-27 04:00:224883 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424884 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244885
4886 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504887 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244888 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4889 EXPECT_EQ(13, response->headers->GetContentLength());
4890}
4891
[email protected]385a4672009-03-11 22:21:294892// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024893TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424894 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294895 request.method = "GET";
4896 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4897 request.load_flags = 0;
4898
[email protected]cb9bf6ca2011-01-28 13:15:274899 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4900 MockGetHostName);
mmenke6b3af6e2015-09-12 02:06:064901 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274902
[email protected]385a4672009-03-11 22:21:294903 MockWrite data_writes1[] = {
4904 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4905 "Host: 172.22.68.17\r\n"
4906 "Connection: keep-alive\r\n\r\n"),
4907 };
4908
4909 MockRead data_reads1[] = {
4910 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044911 // Negotiate and NTLM are often requested together. However, we only want
4912 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4913 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294914 MockRead("WWW-Authenticate: NTLM\r\n"),
4915 MockRead("Connection: close\r\n"),
4916 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364917 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294918 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064919 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294920 };
4921
4922 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224923 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294924 // request we should be issuing -- the final header line contains a Type
4925 // 1 message.
4926 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4927 "Host: 172.22.68.17\r\n"
4928 "Connection: keep-alive\r\n"
4929 "Authorization: NTLM "
4930 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4931
4932 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4933 // (the credentials for the origin server). The second request continues
4934 // on the same connection.
4935 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4936 "Host: 172.22.68.17\r\n"
4937 "Connection: keep-alive\r\n"
4938 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4939 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4940 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4941 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4942 "4Ww7b7E=\r\n\r\n"),
4943 };
4944
4945 MockRead data_reads2[] = {
4946 // The origin server responds with a Type 2 message.
4947 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4948 MockRead("WWW-Authenticate: NTLM "
4949 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4950 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4951 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4952 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4953 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4954 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4955 "BtAAAAAAA=\r\n"),
4956 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364957 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294958 MockRead("You are not authorized to view this page\r\n"),
4959
4960 // Wrong password.
4961 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294962 MockRead("WWW-Authenticate: NTLM\r\n"),
4963 MockRead("Connection: close\r\n"),
4964 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364965 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294966 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064967 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294968 };
4969
4970 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224971 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294972 // request we should be issuing -- the final header line contains a Type
4973 // 1 message.
4974 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4975 "Host: 172.22.68.17\r\n"
4976 "Connection: keep-alive\r\n"
4977 "Authorization: NTLM "
4978 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4979
4980 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4981 // (the credentials for the origin server). The second request continues
4982 // on the same connection.
4983 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4984 "Host: 172.22.68.17\r\n"
4985 "Connection: keep-alive\r\n"
4986 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4987 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4988 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4989 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4990 "+4MUm7c=\r\n\r\n"),
4991 };
4992
4993 MockRead data_reads3[] = {
4994 // The origin server responds with a Type 2 message.
4995 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4996 MockRead("WWW-Authenticate: NTLM "
4997 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4998 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4999 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5000 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5001 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5002 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5003 "BtAAAAAAA=\r\n"),
5004 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365005 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295006 MockRead("You are not authorized to view this page\r\n"),
5007
5008 // Lastly we get the desired content.
5009 MockRead("HTTP/1.1 200 OK\r\n"),
5010 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5011 MockRead("Content-Length: 13\r\n\r\n"),
5012 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065013 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:295014 };
5015
[email protected]31a2bfe2010-02-09 08:03:395016 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5017 data_writes1, arraysize(data_writes1));
5018 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5019 data_writes2, arraysize(data_writes2));
5020 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5021 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075022 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5023 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5024 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:295025
[email protected]49639fa2011-12-20 23:22:415026 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:295027
[email protected]262eec82013-03-19 21:01:365028 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505029 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505030
[email protected]49639fa2011-12-20 23:22:415031 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425032 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295033
5034 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425035 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295036
[email protected]0757e7702009-03-27 04:00:225037 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:295038
[email protected]1c773ea12009-04-28 19:58:425039 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505040 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045041 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:295042
[email protected]49639fa2011-12-20 23:22:415043 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:295044
[email protected]0757e7702009-03-27 04:00:225045 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:585046 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:415047 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425048 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295049
[email protected]10af5fe72011-01-31 16:17:255050 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425051 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295052
[email protected]0757e7702009-03-27 04:00:225053 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415054 TestCompletionCallback callback3;
5055 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425056 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:255057 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425058 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225059 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5060
5061 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:045062 ASSERT_FALSE(response == NULL);
5063 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:225064
[email protected]49639fa2011-12-20 23:22:415065 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:225066
5067 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:585068 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415069 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:255070 EXPECT_EQ(ERR_IO_PENDING, rv);
5071
5072 rv = callback4.WaitForResult();
5073 EXPECT_EQ(OK, rv);
5074
5075 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5076
[email protected]49639fa2011-12-20 23:22:415077 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:255078
5079 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:415080 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:425081 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225082
5083 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425084 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225085
[email protected]385a4672009-03-11 22:21:295086 response = trans->GetResponseInfo();
5087 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5088 EXPECT_EQ(13, response->headers->GetContentLength());
5089}
[email protected]ea9dc9a2009-09-05 00:43:325090#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:295091
[email protected]4ddaf2502008-10-23 18:26:195092// Test reading a server response which has only headers, and no body.
5093// After some maximum number of bytes is consumed, the transaction should
5094// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:025095TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:425096 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:195097 request.method = "GET";
bncce36dca22015-04-21 22:11:235098 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:195099 request.load_flags = 0;
5100
mmenke6b3af6e2015-09-12 02:06:065101 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275102 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415103 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275104
[email protected]b75b7b2f2009-10-06 00:54:535105 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:435106 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:535107 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:195108
5109 MockRead data_reads[] = {
5110 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065111 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:195112 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:065113 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:195114 };
[email protected]31a2bfe2010-02-09 08:03:395115 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075116 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:195117
[email protected]49639fa2011-12-20 23:22:415118 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:195119
[email protected]49639fa2011-12-20 23:22:415120 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425121 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:195122
5123 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425124 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:195125}
[email protected]f4e426b2008-11-05 00:24:495126
5127// Make sure that we don't try to reuse a TCPClientSocket when failing to
5128// establish tunnel.
5129// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:025130TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:235131 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275132 HttpRequestInfo request;
5133 request.method = "GET";
bncce36dca22015-04-21 22:11:235134 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275135 request.load_flags = 0;
5136
[email protected]f4e426b2008-11-05 00:24:495137 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035138 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:015139
mmenke6b3af6e2015-09-12 02:06:065140 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495141
[email protected]262eec82013-03-19 21:01:365142 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505143 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495144
[email protected]f4e426b2008-11-05 00:24:495145 // Since we have proxy, should try to establish tunnel.
5146 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235147 MockWrite(
5148 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5149 "Host: www.example.org\r\n"
5150 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495151 };
5152
[email protected]77848d12008-11-14 00:00:225153 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495154 // connection. Usually a proxy would return 501 (not implemented),
5155 // or 200 (tunnel established).
5156 MockRead data_reads1[] = {
5157 MockRead("HTTP/1.1 404 Not Found\r\n"),
5158 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065159 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495160 };
5161
[email protected]31a2bfe2010-02-09 08:03:395162 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5163 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075164 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495165
[email protected]49639fa2011-12-20 23:22:415166 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495167
[email protected]49639fa2011-12-20 23:22:415168 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425169 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495170
5171 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425172 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495173
[email protected]b4404c02009-04-10 16:38:525174 // Empty the current queue. This is necessary because idle sockets are
5175 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345176 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525177
[email protected]f4e426b2008-11-05 00:24:495178 // We now check to make sure the TCPClientSocket was not added back to
5179 // the pool.
[email protected]90499482013-06-01 00:39:505180 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495181 trans.reset();
[email protected]2da659e2013-05-23 20:51:345182 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495183 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505184 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495185}
[email protected]372d34a2008-11-05 21:30:515186
[email protected]1b157c02009-04-21 01:55:405187// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025188TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425189 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405190 request.method = "GET";
bncce36dca22015-04-21 22:11:235191 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405192 request.load_flags = 0;
5193
mmenke6b3af6e2015-09-12 02:06:065194 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275195
[email protected]262eec82013-03-19 21:01:365196 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505197 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275198
[email protected]1b157c02009-04-21 01:55:405199 MockRead data_reads[] = {
5200 // A part of the response body is received with the response headers.
5201 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5202 // The rest of the response body is received in two parts.
5203 MockRead("lo"),
5204 MockRead(" world"),
5205 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065206 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405207 };
5208
[email protected]31a2bfe2010-02-09 08:03:395209 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075210 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405211
[email protected]49639fa2011-12-20 23:22:415212 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405213
[email protected]49639fa2011-12-20 23:22:415214 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425215 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405216
5217 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425218 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405219
[email protected]1c773ea12009-04-28 19:58:425220 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505221 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405222
[email protected]90499482013-06-01 00:39:505223 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405224 std::string status_line = response->headers->GetStatusLine();
5225 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5226
[email protected]90499482013-06-01 00:39:505227 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405228
5229 std::string response_data;
5230 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425231 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405232 EXPECT_EQ("hello world", response_data);
5233
5234 // Empty the current queue. This is necessary because idle sockets are
5235 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345236 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405237
5238 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505239 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405240}
5241
[email protected]76a505b2010-08-25 06:23:005242// Make sure that we recycle a SSL socket after reading all of the response
5243// body.
[email protected]23e482282013-06-14 16:08:025244TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005245 HttpRequestInfo request;
5246 request.method = "GET";
bncce36dca22015-04-21 22:11:235247 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005248 request.load_flags = 0;
5249
5250 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235251 MockWrite(
5252 "GET / HTTP/1.1\r\n"
5253 "Host: www.example.org\r\n"
5254 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005255 };
5256
5257 MockRead data_reads[] = {
5258 MockRead("HTTP/1.1 200 OK\r\n"),
5259 MockRead("Content-Length: 11\r\n\r\n"),
5260 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065261 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005262 };
5263
[email protected]8ddf8322012-02-23 18:08:065264 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075265 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005266
5267 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5268 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075269 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005270
[email protected]49639fa2011-12-20 23:22:415271 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005272
mmenke6b3af6e2015-09-12 02:06:065273 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365274 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505275 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005276
[email protected]49639fa2011-12-20 23:22:415277 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005278
5279 EXPECT_EQ(ERR_IO_PENDING, rv);
5280 EXPECT_EQ(OK, callback.WaitForResult());
5281
5282 const HttpResponseInfo* response = trans->GetResponseInfo();
5283 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505284 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005285 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5286
[email protected]90499482013-06-01 00:39:505287 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005288
5289 std::string response_data;
5290 rv = ReadTransaction(trans.get(), &response_data);
5291 EXPECT_EQ(OK, rv);
5292 EXPECT_EQ("hello world", response_data);
5293
5294 // Empty the current queue. This is necessary because idle sockets are
5295 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345296 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005297
5298 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505299 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005300}
5301
5302// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5303// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025304TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005305 HttpRequestInfo request;
5306 request.method = "GET";
bncce36dca22015-04-21 22:11:235307 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005308 request.load_flags = 0;
5309
5310 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235311 MockWrite(
5312 "GET / HTTP/1.1\r\n"
5313 "Host: www.example.org\r\n"
5314 "Connection: keep-alive\r\n\r\n"),
5315 MockWrite(
5316 "GET / HTTP/1.1\r\n"
5317 "Host: www.example.org\r\n"
5318 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005319 };
5320
5321 MockRead data_reads[] = {
5322 MockRead("HTTP/1.1 200 OK\r\n"),
5323 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065324 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005325 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065326 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005327 };
5328
[email protected]8ddf8322012-02-23 18:08:065329 SSLSocketDataProvider ssl(ASYNC, OK);
5330 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075331 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5332 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005333
5334 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5335 data_writes, arraysize(data_writes));
5336 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5337 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075338 session_deps_.socket_factory->AddSocketDataProvider(&data);
5339 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005340
[email protected]49639fa2011-12-20 23:22:415341 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005342
mmenke6b3af6e2015-09-12 02:06:065343 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365344 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505345 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005346
[email protected]49639fa2011-12-20 23:22:415347 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005348
5349 EXPECT_EQ(ERR_IO_PENDING, rv);
5350 EXPECT_EQ(OK, callback.WaitForResult());
5351
5352 const HttpResponseInfo* response = trans->GetResponseInfo();
5353 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505354 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005355 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5356
[email protected]90499482013-06-01 00:39:505357 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005358
5359 std::string response_data;
5360 rv = ReadTransaction(trans.get(), &response_data);
5361 EXPECT_EQ(OK, rv);
5362 EXPECT_EQ("hello world", response_data);
5363
5364 // Empty the current queue. This is necessary because idle sockets are
5365 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345366 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005367
5368 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505369 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005370
5371 // Now start the second transaction, which should reuse the previous socket.
5372
[email protected]90499482013-06-01 00:39:505373 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005374
[email protected]49639fa2011-12-20 23:22:415375 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005376
5377 EXPECT_EQ(ERR_IO_PENDING, rv);
5378 EXPECT_EQ(OK, callback.WaitForResult());
5379
5380 response = trans->GetResponseInfo();
5381 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505382 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005383 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5384
[email protected]90499482013-06-01 00:39:505385 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005386
5387 rv = ReadTransaction(trans.get(), &response_data);
5388 EXPECT_EQ(OK, rv);
5389 EXPECT_EQ("hello world", response_data);
5390
5391 // Empty the current queue. This is necessary because idle sockets are
5392 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345393 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005394
5395 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505396 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005397}
5398
[email protected]b4404c02009-04-10 16:38:525399// Make sure that we recycle a socket after a zero-length response.
5400// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025401TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425402 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525403 request.method = "GET";
bncce36dca22015-04-21 22:11:235404 request.url = GURL(
5405 "http://www.example.org/csi?v=3&s=web&action=&"
5406 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5407 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5408 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525409 request.load_flags = 0;
5410
mmenke6b3af6e2015-09-12 02:06:065411 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275412
[email protected]262eec82013-03-19 21:01:365413 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505414 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275415
[email protected]b4404c02009-04-10 16:38:525416 MockRead data_reads[] = {
5417 MockRead("HTTP/1.1 204 No Content\r\n"
5418 "Content-Length: 0\r\n"
5419 "Content-Type: text/html\r\n\r\n"),
5420 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065421 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525422 };
5423
[email protected]31a2bfe2010-02-09 08:03:395424 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075425 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525426
[email protected]49639fa2011-12-20 23:22:415427 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525428
[email protected]49639fa2011-12-20 23:22:415429 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425430 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525431
5432 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425433 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525434
[email protected]1c773ea12009-04-28 19:58:425435 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505436 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525437
[email protected]90499482013-06-01 00:39:505438 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525439 std::string status_line = response->headers->GetStatusLine();
5440 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5441
[email protected]90499482013-06-01 00:39:505442 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525443
5444 std::string response_data;
5445 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425446 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525447 EXPECT_EQ("", response_data);
5448
5449 // Empty the current queue. This is necessary because idle sockets are
5450 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345451 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525452
5453 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505454 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525455}
5456
[email protected]23e482282013-06-14 16:08:025457TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065458 ScopedVector<UploadElementReader> element_readers;
5459 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075460 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275461
[email protected]1c773ea12009-04-28 19:58:425462 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515463 // Transaction 1: a GET request that succeeds. The socket is recycled
5464 // after use.
5465 request[0].method = "GET";
5466 request[0].url = GURL("http://www.google.com/");
5467 request[0].load_flags = 0;
5468 // Transaction 2: a POST request. Reuses the socket kept alive from
5469 // transaction 1. The first attempts fails when writing the POST data.
5470 // This causes the transaction to retry with a new socket. The second
5471 // attempt succeeds.
5472 request[1].method = "POST";
5473 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275474 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515475 request[1].load_flags = 0;
5476
mmenke6b3af6e2015-09-12 02:06:065477 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515478
5479 // The first socket is used for transaction 1 and the first attempt of
5480 // transaction 2.
5481
5482 // The response of transaction 1.
5483 MockRead data_reads1[] = {
5484 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5485 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065486 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515487 };
5488 // The mock write results of transaction 1 and the first attempt of
5489 // transaction 2.
5490 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065491 MockWrite(SYNCHRONOUS, 64), // GET
5492 MockWrite(SYNCHRONOUS, 93), // POST
5493 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515494 };
[email protected]31a2bfe2010-02-09 08:03:395495 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5496 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515497
5498 // The second socket is used for the second attempt of transaction 2.
5499
5500 // The response of transaction 2.
5501 MockRead data_reads2[] = {
5502 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5503 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065504 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515505 };
5506 // The mock write results of the second attempt of transaction 2.
5507 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065508 MockWrite(SYNCHRONOUS, 93), // POST
5509 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515510 };
[email protected]31a2bfe2010-02-09 08:03:395511 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5512 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515513
[email protected]bb88e1d32013-05-03 23:11:075514 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5515 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515516
thestig9d3bb0c2015-01-24 00:49:515517 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:515518 "hello world", "welcome"
5519 };
5520
5521 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425522 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505523 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515524
[email protected]49639fa2011-12-20 23:22:415525 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515526
[email protected]49639fa2011-12-20 23:22:415527 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425528 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515529
5530 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425531 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515532
[email protected]1c773ea12009-04-28 19:58:425533 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505534 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515535
[email protected]90499482013-06-01 00:39:505536 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515537 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5538
5539 std::string response_data;
5540 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425541 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515542 EXPECT_EQ(kExpectedResponseData[i], response_data);
5543 }
5544}
[email protected]f9ee6b52008-11-08 06:46:235545
5546// Test the request-challenge-retry sequence for basic auth when there is
5547// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165548// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025549TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425550 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235551 request.method = "GET";
bncce36dca22015-04-21 22:11:235552 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415553 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295554
mmenke6b3af6e2015-09-12 02:06:065555 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275556 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415557 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275558
[email protected]a97cca42009-08-14 01:00:295559 // The password contains an escaped character -- for this test to pass it
5560 // will need to be unescaped by HttpNetworkTransaction.
5561 EXPECT_EQ("b%40r", request.url.password());
5562
[email protected]f9ee6b52008-11-08 06:46:235563 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235564 MockWrite(
5565 "GET / HTTP/1.1\r\n"
5566 "Host: www.example.org\r\n"
5567 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235568 };
5569
5570 MockRead data_reads1[] = {
5571 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5572 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5573 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065574 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235575 };
5576
[email protected]2262e3a2012-05-22 16:08:165577 // After the challenge above, the transaction will be restarted using the
5578 // identity from the url (foo, b@r) to answer the challenge.
5579 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235580 MockWrite(
5581 "GET / HTTP/1.1\r\n"
5582 "Host: www.example.org\r\n"
5583 "Connection: keep-alive\r\n"
5584 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165585 };
5586
5587 MockRead data_reads2[] = {
5588 MockRead("HTTP/1.0 200 OK\r\n"),
5589 MockRead("Content-Length: 100\r\n\r\n"),
5590 MockRead(SYNCHRONOUS, OK),
5591 };
5592
[email protected]31a2bfe2010-02-09 08:03:395593 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5594 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165595 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5596 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075597 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5598 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235599
[email protected]49639fa2011-12-20 23:22:415600 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415601 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425602 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235603 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425604 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165605 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5606
5607 TestCompletionCallback callback2;
5608 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5609 EXPECT_EQ(ERR_IO_PENDING, rv);
5610 rv = callback2.WaitForResult();
5611 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225612 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5613
[email protected]2262e3a2012-05-22 16:08:165614 const HttpResponseInfo* response = trans->GetResponseInfo();
5615 ASSERT_TRUE(response != NULL);
5616
5617 // There is no challenge info, since the identity in URL worked.
5618 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5619
5620 EXPECT_EQ(100, response->headers->GetContentLength());
5621
5622 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345623 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165624}
5625
5626// Test the request-challenge-retry sequence for basic auth when there is an
5627// incorrect identity in the URL. The identity from the URL should be used only
5628// once.
[email protected]23e482282013-06-14 16:08:025629TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165630 HttpRequestInfo request;
5631 request.method = "GET";
5632 // Note: the URL has a username:password in it. The password "baz" is
5633 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:235634 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:165635
5636 request.load_flags = LOAD_NORMAL;
5637
mmenke6b3af6e2015-09-12 02:06:065638 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165639 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415640 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165641
5642 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235643 MockWrite(
5644 "GET / HTTP/1.1\r\n"
5645 "Host: www.example.org\r\n"
5646 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165647 };
5648
5649 MockRead data_reads1[] = {
5650 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5651 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5652 MockRead("Content-Length: 10\r\n\r\n"),
5653 MockRead(SYNCHRONOUS, ERR_FAILED),
5654 };
5655
5656 // After the challenge above, the transaction will be restarted using the
5657 // identity from the url (foo, baz) to answer the challenge.
5658 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235659 MockWrite(
5660 "GET / HTTP/1.1\r\n"
5661 "Host: www.example.org\r\n"
5662 "Connection: keep-alive\r\n"
5663 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165664 };
5665
5666 MockRead data_reads2[] = {
5667 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5668 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5669 MockRead("Content-Length: 10\r\n\r\n"),
5670 MockRead(SYNCHRONOUS, ERR_FAILED),
5671 };
5672
5673 // After the challenge above, the transaction will be restarted using the
5674 // identity supplied by the user (foo, bar) to answer the challenge.
5675 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235676 MockWrite(
5677 "GET / HTTP/1.1\r\n"
5678 "Host: www.example.org\r\n"
5679 "Connection: keep-alive\r\n"
5680 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165681 };
5682
5683 MockRead data_reads3[] = {
5684 MockRead("HTTP/1.0 200 OK\r\n"),
5685 MockRead("Content-Length: 100\r\n\r\n"),
5686 MockRead(SYNCHRONOUS, OK),
5687 };
5688
5689 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5690 data_writes1, arraysize(data_writes1));
5691 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5692 data_writes2, arraysize(data_writes2));
5693 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5694 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075695 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5696 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5697 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165698
5699 TestCompletionCallback callback1;
5700
5701 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5702 EXPECT_EQ(ERR_IO_PENDING, rv);
5703
5704 rv = callback1.WaitForResult();
5705 EXPECT_EQ(OK, rv);
5706
5707 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
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);
5713 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5714
5715 const HttpResponseInfo* response = trans->GetResponseInfo();
5716 ASSERT_TRUE(response != NULL);
5717 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5718
5719 TestCompletionCallback callback3;
5720 rv = trans->RestartWithAuth(
5721 AuthCredentials(kFoo, kBar), callback3.callback());
5722 EXPECT_EQ(ERR_IO_PENDING, rv);
5723 rv = callback3.WaitForResult();
5724 EXPECT_EQ(OK, rv);
5725 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5726
5727 response = trans->GetResponseInfo();
5728 ASSERT_TRUE(response != NULL);
5729
5730 // There is no challenge info, since the identity worked.
5731 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5732
5733 EXPECT_EQ(100, response->headers->GetContentLength());
5734
[email protected]ea9dc9a2009-09-05 00:43:325735 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345736 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325737}
5738
[email protected]2217aa22013-10-11 03:03:545739
5740// Test the request-challenge-retry sequence for basic auth when there is a
5741// correct identity in the URL, but its use is being suppressed. The identity
5742// from the URL should never be used.
5743TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5744 HttpRequestInfo request;
5745 request.method = "GET";
bncce36dca22015-04-21 22:11:235746 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:545747 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5748
mmenke6b3af6e2015-09-12 02:06:065749 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545750 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415751 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545752
5753 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235754 MockWrite(
5755 "GET / HTTP/1.1\r\n"
5756 "Host: www.example.org\r\n"
5757 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545758 };
5759
5760 MockRead data_reads1[] = {
5761 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5762 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5763 MockRead("Content-Length: 10\r\n\r\n"),
5764 MockRead(SYNCHRONOUS, ERR_FAILED),
5765 };
5766
5767 // After the challenge above, the transaction will be restarted using the
5768 // identity supplied by the user, not the one in the URL, to answer the
5769 // challenge.
5770 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235771 MockWrite(
5772 "GET / HTTP/1.1\r\n"
5773 "Host: www.example.org\r\n"
5774 "Connection: keep-alive\r\n"
5775 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545776 };
5777
5778 MockRead data_reads3[] = {
5779 MockRead("HTTP/1.0 200 OK\r\n"),
5780 MockRead("Content-Length: 100\r\n\r\n"),
5781 MockRead(SYNCHRONOUS, OK),
5782 };
5783
5784 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5785 data_writes1, arraysize(data_writes1));
5786 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5787 data_writes3, arraysize(data_writes3));
5788 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5789 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5790
5791 TestCompletionCallback callback1;
5792 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5793 EXPECT_EQ(ERR_IO_PENDING, rv);
5794 rv = callback1.WaitForResult();
5795 EXPECT_EQ(OK, rv);
5796 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5797
5798 const HttpResponseInfo* response = trans->GetResponseInfo();
5799 ASSERT_TRUE(response != NULL);
5800 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5801
5802 TestCompletionCallback callback3;
5803 rv = trans->RestartWithAuth(
5804 AuthCredentials(kFoo, kBar), callback3.callback());
5805 EXPECT_EQ(ERR_IO_PENDING, rv);
5806 rv = callback3.WaitForResult();
5807 EXPECT_EQ(OK, rv);
5808 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5809
5810 response = trans->GetResponseInfo();
5811 ASSERT_TRUE(response != NULL);
5812
5813 // There is no challenge info, since the identity worked.
5814 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5815 EXPECT_EQ(100, response->headers->GetContentLength());
5816
5817 // Empty the current queue.
5818 base::MessageLoop::current()->RunUntilIdle();
5819}
5820
[email protected]f9ee6b52008-11-08 06:46:235821// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025822TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
mmenke6b3af6e2015-09-12 02:06:065823 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235824
5825 // Transaction 1: authenticate (foo, bar) on MyRealm1
5826 {
[email protected]1c773ea12009-04-28 19:58:425827 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235828 request.method = "GET";
bncce36dca22015-04-21 22:11:235829 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:235830 request.load_flags = 0;
5831
[email protected]262eec82013-03-19 21:01:365832 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505833 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275834
[email protected]f9ee6b52008-11-08 06:46:235835 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235836 MockWrite(
5837 "GET /x/y/z HTTP/1.1\r\n"
5838 "Host: www.example.org\r\n"
5839 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235840 };
5841
5842 MockRead data_reads1[] = {
5843 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5844 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5845 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065846 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235847 };
5848
5849 // Resend with authorization (username=foo, password=bar)
5850 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235851 MockWrite(
5852 "GET /x/y/z HTTP/1.1\r\n"
5853 "Host: www.example.org\r\n"
5854 "Connection: keep-alive\r\n"
5855 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235856 };
5857
5858 // Sever accepts the authorization.
5859 MockRead data_reads2[] = {
5860 MockRead("HTTP/1.0 200 OK\r\n"),
5861 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065862 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235863 };
5864
[email protected]31a2bfe2010-02-09 08:03:395865 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5866 data_writes1, arraysize(data_writes1));
5867 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5868 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075869 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5870 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235871
[email protected]49639fa2011-12-20 23:22:415872 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235873
[email protected]49639fa2011-12-20 23:22:415874 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425875 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235876
5877 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425878 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235879
[email protected]1c773ea12009-04-28 19:58:425880 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505881 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045882 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235883
[email protected]49639fa2011-12-20 23:22:415884 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235885
[email protected]49639fa2011-12-20 23:22:415886 rv = trans->RestartWithAuth(
5887 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425888 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235889
5890 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425891 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235892
5893 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505894 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235895 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5896 EXPECT_EQ(100, response->headers->GetContentLength());
5897 }
5898
5899 // ------------------------------------------------------------------------
5900
5901 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5902 {
[email protected]1c773ea12009-04-28 19:58:425903 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235904 request.method = "GET";
5905 // Note that Transaction 1 was at /x/y/z, so this is in the same
5906 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:235907 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:235908 request.load_flags = 0;
5909
[email protected]262eec82013-03-19 21:01:365910 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505911 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275912
[email protected]f9ee6b52008-11-08 06:46:235913 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235914 MockWrite(
5915 "GET /x/y/a/b HTTP/1.1\r\n"
5916 "Host: www.example.org\r\n"
5917 "Connection: keep-alive\r\n"
5918 // Send preemptive authorization for MyRealm1
5919 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235920 };
5921
5922 // The server didn't like the preemptive authorization, and
5923 // challenges us for a different realm (MyRealm2).
5924 MockRead data_reads1[] = {
5925 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5926 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5927 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065928 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235929 };
5930
5931 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5932 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235933 MockWrite(
5934 "GET /x/y/a/b HTTP/1.1\r\n"
5935 "Host: www.example.org\r\n"
5936 "Connection: keep-alive\r\n"
5937 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235938 };
5939
5940 // Sever accepts the authorization.
5941 MockRead data_reads2[] = {
5942 MockRead("HTTP/1.0 200 OK\r\n"),
5943 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065944 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235945 };
5946
[email protected]31a2bfe2010-02-09 08:03:395947 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5948 data_writes1, arraysize(data_writes1));
5949 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5950 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075951 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5952 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235953
[email protected]49639fa2011-12-20 23:22:415954 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235955
[email protected]49639fa2011-12-20 23:22:415956 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425957 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235958
5959 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425960 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235961
[email protected]1c773ea12009-04-28 19:58:425962 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505963 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045964 ASSERT_TRUE(response->auth_challenge.get());
5965 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:235966 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:045967 response->auth_challenge->challenger.ToString());
5968 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5969 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235970
[email protected]49639fa2011-12-20 23:22:415971 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235972
[email protected]49639fa2011-12-20 23:22:415973 rv = trans->RestartWithAuth(
5974 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425975 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235976
5977 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425978 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235979
5980 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505981 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235982 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5983 EXPECT_EQ(100, response->headers->GetContentLength());
5984 }
5985
5986 // ------------------------------------------------------------------------
5987
5988 // Transaction 3: Resend a request in MyRealm's protection space --
5989 // succeed with preemptive authorization.
5990 {
[email protected]1c773ea12009-04-28 19:58:425991 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235992 request.method = "GET";
bncce36dca22015-04-21 22:11:235993 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:235994 request.load_flags = 0;
5995
[email protected]262eec82013-03-19 21:01:365996 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505997 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275998
[email protected]f9ee6b52008-11-08 06:46:235999 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236000 MockWrite(
6001 "GET /x/y/z2 HTTP/1.1\r\n"
6002 "Host: www.example.org\r\n"
6003 "Connection: keep-alive\r\n"
6004 // The authorization for MyRealm1 gets sent preemptively
6005 // (since the url is in the same protection space)
6006 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236007 };
6008
6009 // Sever accepts the preemptive authorization
6010 MockRead data_reads1[] = {
6011 MockRead("HTTP/1.0 200 OK\r\n"),
6012 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066013 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236014 };
6015
[email protected]31a2bfe2010-02-09 08:03:396016 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6017 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076018 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:236019
[email protected]49639fa2011-12-20 23:22:416020 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236021
[email protected]49639fa2011-12-20 23:22:416022 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426023 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236024
6025 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426026 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236027
[email protected]1c773ea12009-04-28 19:58:426028 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506029 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236030
6031 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6032 EXPECT_EQ(100, response->headers->GetContentLength());
6033 }
6034
6035 // ------------------------------------------------------------------------
6036
6037 // Transaction 4: request another URL in MyRealm (however the
6038 // url is not known to belong to the protection space, so no pre-auth).
6039 {
[email protected]1c773ea12009-04-28 19:58:426040 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236041 request.method = "GET";
bncce36dca22015-04-21 22:11:236042 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:236043 request.load_flags = 0;
6044
[email protected]262eec82013-03-19 21:01:366045 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506046 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276047
[email protected]f9ee6b52008-11-08 06:46:236048 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236049 MockWrite(
6050 "GET /x/1 HTTP/1.1\r\n"
6051 "Host: www.example.org\r\n"
6052 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236053 };
6054
6055 MockRead data_reads1[] = {
6056 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6057 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6058 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066059 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236060 };
6061
6062 // Resend with authorization from MyRealm's cache.
6063 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236064 MockWrite(
6065 "GET /x/1 HTTP/1.1\r\n"
6066 "Host: www.example.org\r\n"
6067 "Connection: keep-alive\r\n"
6068 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236069 };
6070
6071 // Sever accepts the authorization.
6072 MockRead data_reads2[] = {
6073 MockRead("HTTP/1.0 200 OK\r\n"),
6074 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066075 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236076 };
6077
[email protected]31a2bfe2010-02-09 08:03:396078 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6079 data_writes1, arraysize(data_writes1));
6080 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6081 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076082 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6083 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236084
[email protected]49639fa2011-12-20 23:22:416085 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236086
[email protected]49639fa2011-12-20 23:22:416087 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426088 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236089
6090 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426091 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236092
[email protected]0757e7702009-03-27 04:00:226093 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416094 TestCompletionCallback callback2;
6095 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426096 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226097 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426098 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226099 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6100
[email protected]1c773ea12009-04-28 19:58:426101 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506102 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236103 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6104 EXPECT_EQ(100, response->headers->GetContentLength());
6105 }
6106
6107 // ------------------------------------------------------------------------
6108
6109 // Transaction 5: request a URL in MyRealm, but the server rejects the
6110 // cached identity. Should invalidate and re-prompt.
6111 {
[email protected]1c773ea12009-04-28 19:58:426112 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236113 request.method = "GET";
bncce36dca22015-04-21 22:11:236114 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:236115 request.load_flags = 0;
6116
[email protected]262eec82013-03-19 21:01:366117 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506118 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276119
[email protected]f9ee6b52008-11-08 06:46:236120 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236121 MockWrite(
6122 "GET /p/q/t HTTP/1.1\r\n"
6123 "Host: www.example.org\r\n"
6124 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236125 };
6126
6127 MockRead data_reads1[] = {
6128 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6129 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6130 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066131 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236132 };
6133
6134 // Resend with authorization from cache for MyRealm.
6135 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236136 MockWrite(
6137 "GET /p/q/t HTTP/1.1\r\n"
6138 "Host: www.example.org\r\n"
6139 "Connection: keep-alive\r\n"
6140 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236141 };
6142
6143 // Sever rejects the authorization.
6144 MockRead data_reads2[] = {
6145 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6146 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6147 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066148 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236149 };
6150
6151 // At this point we should prompt for new credentials for MyRealm.
6152 // Restart with username=foo3, password=foo4.
6153 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236154 MockWrite(
6155 "GET /p/q/t HTTP/1.1\r\n"
6156 "Host: www.example.org\r\n"
6157 "Connection: keep-alive\r\n"
6158 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236159 };
6160
6161 // Sever accepts the authorization.
6162 MockRead data_reads3[] = {
6163 MockRead("HTTP/1.0 200 OK\r\n"),
6164 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066165 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236166 };
6167
[email protected]31a2bfe2010-02-09 08:03:396168 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6169 data_writes1, arraysize(data_writes1));
6170 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6171 data_writes2, arraysize(data_writes2));
6172 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6173 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076174 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6175 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6176 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236177
[email protected]49639fa2011-12-20 23:22:416178 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236179
[email protected]49639fa2011-12-20 23:22:416180 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426181 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236182
6183 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426184 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236185
[email protected]0757e7702009-03-27 04:00:226186 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416187 TestCompletionCallback callback2;
6188 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426189 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226190 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426191 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226192 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6193
[email protected]1c773ea12009-04-28 19:58:426194 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506195 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046196 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236197
[email protected]49639fa2011-12-20 23:22:416198 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236199
[email protected]49639fa2011-12-20 23:22:416200 rv = trans->RestartWithAuth(
6201 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426202 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236203
[email protected]0757e7702009-03-27 04:00:226204 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426205 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236206
6207 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506208 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236209 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6210 EXPECT_EQ(100, response->headers->GetContentLength());
6211 }
6212}
[email protected]89ceba9a2009-03-21 03:46:066213
[email protected]3c32c5f2010-05-18 15:18:126214// Tests that nonce count increments when multiple auth attempts
6215// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026216TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446217 HttpAuthHandlerDigest::Factory* digest_factory =
6218 new HttpAuthHandlerDigest::Factory();
6219 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6220 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6221 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076222 session_deps_.http_auth_handler_factory.reset(digest_factory);
mmenke6b3af6e2015-09-12 02:06:066223 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126224
6225 // Transaction 1: authenticate (foo, bar) on MyRealm1
6226 {
[email protected]3c32c5f2010-05-18 15:18:126227 HttpRequestInfo request;
6228 request.method = "GET";
bncce36dca22015-04-21 22:11:236229 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126230 request.load_flags = 0;
6231
[email protected]262eec82013-03-19 21:01:366232 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506233 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276234
[email protected]3c32c5f2010-05-18 15:18:126235 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236236 MockWrite(
6237 "GET /x/y/z HTTP/1.1\r\n"
6238 "Host: www.example.org\r\n"
6239 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126240 };
6241
6242 MockRead data_reads1[] = {
6243 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6244 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6245 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066246 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126247 };
6248
6249 // Resend with authorization (username=foo, password=bar)
6250 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236251 MockWrite(
6252 "GET /x/y/z HTTP/1.1\r\n"
6253 "Host: www.example.org\r\n"
6254 "Connection: keep-alive\r\n"
6255 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6256 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6257 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6258 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126259 };
6260
6261 // Sever accepts the authorization.
6262 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:086263 MockRead("HTTP/1.0 200 OK\r\n"),
6264 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126265 };
6266
6267 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6268 data_writes1, arraysize(data_writes1));
6269 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6270 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076271 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6272 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126273
[email protected]49639fa2011-12-20 23:22:416274 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126275
[email protected]49639fa2011-12-20 23:22:416276 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126277 EXPECT_EQ(ERR_IO_PENDING, rv);
6278
6279 rv = callback1.WaitForResult();
6280 EXPECT_EQ(OK, rv);
6281
6282 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506283 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046284 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126285
[email protected]49639fa2011-12-20 23:22:416286 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126287
[email protected]49639fa2011-12-20 23:22:416288 rv = trans->RestartWithAuth(
6289 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126290 EXPECT_EQ(ERR_IO_PENDING, rv);
6291
6292 rv = callback2.WaitForResult();
6293 EXPECT_EQ(OK, rv);
6294
6295 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506296 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126297 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6298 }
6299
6300 // ------------------------------------------------------------------------
6301
6302 // Transaction 2: Request another resource in digestive's protection space.
6303 // This will preemptively add an Authorization header which should have an
6304 // "nc" value of 2 (as compared to 1 in the first use.
6305 {
[email protected]3c32c5f2010-05-18 15:18:126306 HttpRequestInfo request;
6307 request.method = "GET";
6308 // Note that Transaction 1 was at /x/y/z, so this is in the same
6309 // protection space as digest.
bncce36dca22015-04-21 22:11:236310 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126311 request.load_flags = 0;
6312
[email protected]262eec82013-03-19 21:01:366313 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506314 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276315
[email protected]3c32c5f2010-05-18 15:18:126316 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236317 MockWrite(
6318 "GET /x/y/a/b HTTP/1.1\r\n"
6319 "Host: www.example.org\r\n"
6320 "Connection: keep-alive\r\n"
6321 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6322 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6323 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6324 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126325 };
6326
6327 // Sever accepts the authorization.
6328 MockRead data_reads1[] = {
6329 MockRead("HTTP/1.0 200 OK\r\n"),
6330 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066331 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126332 };
6333
6334 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6335 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076336 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126337
[email protected]49639fa2011-12-20 23:22:416338 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126339
[email protected]49639fa2011-12-20 23:22:416340 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126341 EXPECT_EQ(ERR_IO_PENDING, rv);
6342
6343 rv = callback1.WaitForResult();
6344 EXPECT_EQ(OK, rv);
6345
6346 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506347 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126348 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6349 }
6350}
6351
[email protected]89ceba9a2009-03-21 03:46:066352// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026353TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066354 // Create a transaction (the dependencies aren't important).
mmenke6b3af6e2015-09-12 02:06:066355 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406356 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416357 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066358
6359 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066360 trans->read_buf_ = new IOBuffer(15);
6361 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206362 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066363
6364 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146365 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576366 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086367 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576368 response->response_time = base::Time::Now();
6369 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066370
6371 { // Setup state for response_.vary_data
6372 HttpRequestInfo request;
6373 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6374 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276375 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436376 request.extra_headers.SetHeader("Foo", "1");
6377 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506378 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066379 }
6380
6381 // Cause the above state to be reset.
6382 trans->ResetStateForRestart();
6383
6384 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076385 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066386 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206387 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576388 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6389 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046390 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086391 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576392 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066393}
6394
[email protected]bacff652009-03-31 17:50:336395// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026396TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336397 HttpRequestInfo request;
6398 request.method = "GET";
bncce36dca22015-04-21 22:11:236399 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336400 request.load_flags = 0;
6401
mmenke6b3af6e2015-09-12 02:06:066402 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276403 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416404 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276405
[email protected]bacff652009-03-31 17:50:336406 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236407 MockWrite(
6408 "GET / HTTP/1.1\r\n"
6409 "Host: www.example.org\r\n"
6410 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336411 };
6412
6413 MockRead data_reads[] = {
6414 MockRead("HTTP/1.0 200 OK\r\n"),
6415 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6416 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066417 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336418 };
6419
[email protected]5ecc992a42009-11-11 01:41:596420 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396421 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6422 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066423 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6424 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336425
[email protected]bb88e1d32013-05-03 23:11:076426 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6427 session_deps_.socket_factory->AddSocketDataProvider(&data);
6428 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6429 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336430
[email protected]49639fa2011-12-20 23:22:416431 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336432
[email protected]49639fa2011-12-20 23:22:416433 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336434 EXPECT_EQ(ERR_IO_PENDING, rv);
6435
6436 rv = callback.WaitForResult();
6437 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6438
[email protected]49639fa2011-12-20 23:22:416439 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336440 EXPECT_EQ(ERR_IO_PENDING, rv);
6441
6442 rv = callback.WaitForResult();
6443 EXPECT_EQ(OK, rv);
6444
6445 const HttpResponseInfo* response = trans->GetResponseInfo();
6446
[email protected]fe2255a2011-09-20 19:37:506447 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336448 EXPECT_EQ(100, response->headers->GetContentLength());
6449}
6450
6451// Test HTTPS connections to a site with a bad certificate, going through a
6452// proxy
[email protected]23e482282013-06-14 16:08:026453TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:036454 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:336455
6456 HttpRequestInfo request;
6457 request.method = "GET";
bncce36dca22015-04-21 22:11:236458 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336459 request.load_flags = 0;
6460
6461 MockWrite proxy_writes[] = {
bncce36dca22015-04-21 22:11:236462 MockWrite(
6463 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6464 "Host: www.example.org\r\n"
6465 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336466 };
6467
6468 MockRead proxy_reads[] = {
6469 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066470 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336471 };
6472
6473 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236474 MockWrite(
6475 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6476 "Host: www.example.org\r\n"
6477 "Proxy-Connection: keep-alive\r\n\r\n"),
6478 MockWrite(
6479 "GET / HTTP/1.1\r\n"
6480 "Host: www.example.org\r\n"
6481 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336482 };
6483
6484 MockRead data_reads[] = {
6485 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6486 MockRead("HTTP/1.0 200 OK\r\n"),
6487 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6488 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066489 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336490 };
6491
[email protected]31a2bfe2010-02-09 08:03:396492 StaticSocketDataProvider ssl_bad_certificate(
6493 proxy_reads, arraysize(proxy_reads),
6494 proxy_writes, arraysize(proxy_writes));
6495 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6496 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066497 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6498 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336499
[email protected]bb88e1d32013-05-03 23:11:076500 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6501 session_deps_.socket_factory->AddSocketDataProvider(&data);
6502 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6503 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336504
[email protected]49639fa2011-12-20 23:22:416505 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336506
6507 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076508 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336509
mmenke6b3af6e2015-09-12 02:06:066510 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406511 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416512 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336513
[email protected]49639fa2011-12-20 23:22:416514 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336515 EXPECT_EQ(ERR_IO_PENDING, rv);
6516
6517 rv = callback.WaitForResult();
6518 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6519
[email protected]49639fa2011-12-20 23:22:416520 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336521 EXPECT_EQ(ERR_IO_PENDING, rv);
6522
6523 rv = callback.WaitForResult();
6524 EXPECT_EQ(OK, rv);
6525
6526 const HttpResponseInfo* response = trans->GetResponseInfo();
6527
[email protected]fe2255a2011-09-20 19:37:506528 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336529 EXPECT_EQ(100, response->headers->GetContentLength());
6530 }
6531}
6532
[email protected]2df19bb2010-08-25 20:13:466533
6534// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026535TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:036536 session_deps_.proxy_service =
6537 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:516538 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076539 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466540
6541 HttpRequestInfo request;
6542 request.method = "GET";
bncce36dca22015-04-21 22:11:236543 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466544 request.load_flags = 0;
6545
6546 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236547 MockWrite(
6548 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6549 "Host: www.example.org\r\n"
6550 "Proxy-Connection: keep-alive\r\n\r\n"),
6551 MockWrite(
6552 "GET / HTTP/1.1\r\n"
6553 "Host: www.example.org\r\n"
6554 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466555 };
6556
6557 MockRead data_reads[] = {
6558 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6559 MockRead("HTTP/1.1 200 OK\r\n"),
6560 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6561 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066562 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466563 };
6564
6565 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6566 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066567 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6568 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466569
[email protected]bb88e1d32013-05-03 23:11:076570 session_deps_.socket_factory->AddSocketDataProvider(&data);
6571 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6572 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466573
[email protected]49639fa2011-12-20 23:22:416574 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466575
mmenke6b3af6e2015-09-12 02:06:066576 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466577 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416578 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466579
[email protected]49639fa2011-12-20 23:22:416580 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466581 EXPECT_EQ(ERR_IO_PENDING, rv);
6582
6583 rv = callback.WaitForResult();
6584 EXPECT_EQ(OK, rv);
6585 const HttpResponseInfo* response = trans->GetResponseInfo();
6586
[email protected]fe2255a2011-09-20 19:37:506587 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466588
6589 EXPECT_TRUE(response->headers->IsKeepAlive());
6590 EXPECT_EQ(200, response->headers->response_code());
6591 EXPECT_EQ(100, response->headers->GetContentLength());
6592 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206593
6594 LoadTimingInfo load_timing_info;
6595 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6596 TestLoadTimingNotReusedWithPac(load_timing_info,
6597 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466598}
6599
[email protected]511f6f52010-12-17 03:58:296600// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026601TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:036602 session_deps_.proxy_service =
6603 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:516604 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076605 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296606
6607 HttpRequestInfo request;
6608 request.method = "GET";
bncce36dca22015-04-21 22:11:236609 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296610 request.load_flags = 0;
6611
6612 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236613 MockWrite(
6614 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6615 "Host: www.example.org\r\n"
6616 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296617 };
6618
6619 MockRead data_reads[] = {
6620 MockRead("HTTP/1.1 302 Redirect\r\n"),
6621 MockRead("Location: http://login.example.com/\r\n"),
6622 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066623 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296624 };
6625
6626 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6627 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066628 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296629
[email protected]bb88e1d32013-05-03 23:11:076630 session_deps_.socket_factory->AddSocketDataProvider(&data);
6631 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296632
[email protected]49639fa2011-12-20 23:22:416633 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296634
mmenke6b3af6e2015-09-12 02:06:066635 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296636 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416637 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296638
[email protected]49639fa2011-12-20 23:22:416639 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296640 EXPECT_EQ(ERR_IO_PENDING, rv);
6641
6642 rv = callback.WaitForResult();
6643 EXPECT_EQ(OK, rv);
6644 const HttpResponseInfo* response = trans->GetResponseInfo();
6645
[email protected]fe2255a2011-09-20 19:37:506646 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296647
6648 EXPECT_EQ(302, response->headers->response_code());
6649 std::string url;
6650 EXPECT_TRUE(response->headers->IsRedirect(&url));
6651 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206652
6653 // In the case of redirects from proxies, HttpNetworkTransaction returns
6654 // timing for the proxy connection instead of the connection to the host,
6655 // and no send / receive times.
6656 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6657 LoadTimingInfo load_timing_info;
6658 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6659
6660 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:296661 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:206662
6663 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6664 EXPECT_LE(load_timing_info.proxy_resolve_start,
6665 load_timing_info.proxy_resolve_end);
6666 EXPECT_LE(load_timing_info.proxy_resolve_end,
6667 load_timing_info.connect_timing.connect_start);
6668 ExpectConnectTimingHasTimes(
6669 load_timing_info.connect_timing,
6670 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6671
6672 EXPECT_TRUE(load_timing_info.send_start.is_null());
6673 EXPECT_TRUE(load_timing_info.send_end.is_null());
6674 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296675}
6676
6677// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026678TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:036679 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:296680
6681 HttpRequestInfo request;
6682 request.method = "GET";
bncce36dca22015-04-21 22:11:236683 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296684 request.load_flags = 0;
6685
lgarrona91df87f2014-12-05 00:51:346686 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236687 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206688 scoped_ptr<SpdyFrame> goaway(
6689 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296690 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136691 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6692 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296693 };
6694
6695 static const char* const kExtraHeaders[] = {
6696 "location",
6697 "http://login.example.com/",
6698 };
[email protected]ff98d7f02012-03-22 21:44:196699 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026700 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296701 arraysize(kExtraHeaders)/2, 1));
6702 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136703 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:296704 };
6705
rch8e6c6c42015-05-01 14:05:136706 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6707 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066708 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026709 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296710
[email protected]bb88e1d32013-05-03 23:11:076711 session_deps_.socket_factory->AddSocketDataProvider(&data);
6712 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296713
[email protected]49639fa2011-12-20 23:22:416714 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296715
mmenke6b3af6e2015-09-12 02:06:066716 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296717 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416718 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296719
[email protected]49639fa2011-12-20 23:22:416720 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296721 EXPECT_EQ(ERR_IO_PENDING, rv);
6722
6723 rv = callback.WaitForResult();
6724 EXPECT_EQ(OK, rv);
6725 const HttpResponseInfo* response = trans->GetResponseInfo();
6726
[email protected]fe2255a2011-09-20 19:37:506727 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296728
6729 EXPECT_EQ(302, response->headers->response_code());
6730 std::string url;
6731 EXPECT_TRUE(response->headers->IsRedirect(&url));
6732 EXPECT_EQ("http://login.example.com/", url);
6733}
6734
[email protected]4eddbc732012-08-09 05:40:176735// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026736TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176737 ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:036738 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:296739
6740 HttpRequestInfo request;
6741 request.method = "GET";
bncce36dca22015-04-21 22:11:236742 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296743 request.load_flags = 0;
6744
6745 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236746 MockWrite(
6747 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6748 "Host: www.example.org\r\n"
6749 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296750 };
6751
6752 MockRead data_reads[] = {
6753 MockRead("HTTP/1.1 404 Not Found\r\n"),
6754 MockRead("Content-Length: 23\r\n\r\n"),
6755 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066756 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296757 };
6758
6759 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6760 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066761 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296762
[email protected]bb88e1d32013-05-03 23:11:076763 session_deps_.socket_factory->AddSocketDataProvider(&data);
6764 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296765
[email protected]49639fa2011-12-20 23:22:416766 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296767
mmenke6b3af6e2015-09-12 02:06:066768 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296769 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416770 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296771
[email protected]49639fa2011-12-20 23:22:416772 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296773 EXPECT_EQ(ERR_IO_PENDING, rv);
6774
6775 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176776 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296777
[email protected]4eddbc732012-08-09 05:40:176778 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296779}
6780
[email protected]4eddbc732012-08-09 05:40:176781// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026782TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176783 ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:036784 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:296785
6786 HttpRequestInfo request;
6787 request.method = "GET";
bncce36dca22015-04-21 22:11:236788 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296789 request.load_flags = 0;
6790
lgarrona91df87f2014-12-05 00:51:346791 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236792 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206793 scoped_ptr<SpdyFrame> rst(
6794 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296795 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136796 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:296797 };
6798
6799 static const char* const kExtraHeaders[] = {
6800 "location",
6801 "http://login.example.com/",
6802 };
[email protected]ff98d7f02012-03-22 21:44:196803 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026804 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296805 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196806 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026807 spdy_util_.ConstructSpdyBodyFrame(
6808 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296809 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136810 CreateMockRead(*resp.get(), 1),
6811 CreateMockRead(*body.get(), 2),
6812 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296813 };
6814
rch8e6c6c42015-05-01 14:05:136815 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6816 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066817 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026818 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296819
[email protected]bb88e1d32013-05-03 23:11:076820 session_deps_.socket_factory->AddSocketDataProvider(&data);
6821 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296822
[email protected]49639fa2011-12-20 23:22:416823 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296824
mmenke6b3af6e2015-09-12 02:06:066825 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296826 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416827 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296828
[email protected]49639fa2011-12-20 23:22:416829 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296830 EXPECT_EQ(ERR_IO_PENDING, rv);
6831
6832 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176833 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296834
[email protected]4eddbc732012-08-09 05:40:176835 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296836}
6837
[email protected]0c5fb722012-02-28 11:50:356838// Test the request-challenge-retry sequence for basic auth, through
6839// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026840TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356841 HttpRequestInfo request;
6842 request.method = "GET";
bncce36dca22015-04-21 22:11:236843 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:356844 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296845 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:356846
6847 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036848 session_deps_.proxy_service =
6849 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:516850 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076851 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:066852 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356853
6854 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346855 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236856 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206857 scoped_ptr<SpdyFrame> rst(
6858 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356859
6860 // After calling trans->RestartWithAuth(), this is the request we should
6861 // be issuing -- the final header line contains the credentials.
6862 const char* const kAuthCredentials[] = {
6863 "proxy-authorization", "Basic Zm9vOmJhcg==",
6864 };
[email protected]fba2dbde2013-05-24 16:09:016865 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346866 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:236867 HostPortPair("www.example.org", 443)));
6868 // fetch https://www.example.org/ via HTTP
6869 const char get[] =
6870 "GET / HTTP/1.1\r\n"
6871 "Host: www.example.org\r\n"
6872 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196873 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026874 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356875
6876 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136877 CreateMockWrite(*req, 0, ASYNC),
6878 CreateMockWrite(*rst, 2, ASYNC),
6879 CreateMockWrite(*connect2, 3),
6880 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:356881 };
6882
6883 // The proxy responds to the connect with a 407, using a persistent
6884 // connection.
thestig9d3bb0c2015-01-24 00:49:516885 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:356886 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356887 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6888 };
[email protected]745aa9c2014-06-27 02:21:296889 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6890 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356891
[email protected]23e482282013-06-14 16:08:026892 scoped_ptr<SpdyFrame> conn_resp(
6893 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356894 const char resp[] = "HTTP/1.1 200 OK\r\n"
6895 "Content-Length: 5\r\n\r\n";
6896
[email protected]ff98d7f02012-03-22 21:44:196897 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026898 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196899 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026900 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356901 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136902 CreateMockRead(*conn_auth_resp, 1, ASYNC),
6903 CreateMockRead(*conn_resp, 4, ASYNC),
6904 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
6905 CreateMockRead(*wrapped_body, 7, ASYNC),
6906 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356907 };
6908
rch8e6c6c42015-05-01 14:05:136909 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6910 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076911 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356912 // Negotiate SPDY to the proxy
6913 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026914 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076915 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356916 // Vanilla SSL to the server
6917 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076918 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356919
6920 TestCompletionCallback callback1;
6921
[email protected]262eec82013-03-19 21:01:366922 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506923 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356924
6925 int rv = trans->Start(&request, callback1.callback(), log.bound());
6926 EXPECT_EQ(ERR_IO_PENDING, rv);
6927
6928 rv = callback1.WaitForResult();
6929 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:466930 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:356931 log.GetEntries(&entries);
6932 size_t pos = ExpectLogContainsSomewhere(
6933 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6934 NetLog::PHASE_NONE);
6935 ExpectLogContainsSomewhere(
6936 entries, pos,
6937 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6938 NetLog::PHASE_NONE);
6939
6940 const HttpResponseInfo* response = trans->GetResponseInfo();
6941 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506942 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356943 EXPECT_EQ(407, response->headers->response_code());
6944 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6945 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6946 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6947
6948 TestCompletionCallback callback2;
6949
6950 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6951 callback2.callback());
6952 EXPECT_EQ(ERR_IO_PENDING, rv);
6953
6954 rv = callback2.WaitForResult();
6955 EXPECT_EQ(OK, rv);
6956
6957 response = trans->GetResponseInfo();
6958 ASSERT_TRUE(response != NULL);
6959
6960 EXPECT_TRUE(response->headers->IsKeepAlive());
6961 EXPECT_EQ(200, response->headers->response_code());
6962 EXPECT_EQ(5, response->headers->GetContentLength());
6963 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6964
6965 // The password prompt info should not be set.
6966 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6967
[email protected]029c83b62013-01-24 05:28:206968 LoadTimingInfo load_timing_info;
6969 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6970 TestLoadTimingNotReusedWithPac(load_timing_info,
6971 CONNECT_TIMING_HAS_SSL_TIMES);
6972
[email protected]0c5fb722012-02-28 11:50:356973 trans.reset();
6974 session->CloseAllConnections();
6975}
6976
[email protected]7c6f7ba2012-04-03 04:09:296977// Test that an explicitly trusted SPDY proxy can push a resource from an
6978// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026979TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296980 HttpRequestInfo request;
6981 HttpRequestInfo push_request;
6982
[email protected]7c6f7ba2012-04-03 04:09:296983 request.method = "GET";
bncce36dca22015-04-21 22:11:236984 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:296985 push_request.method = "GET";
6986 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6987
[email protected]7c6f7ba2012-04-03 04:09:296988 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036989 session_deps_.proxy_service =
6990 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:516991 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076992 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506993
6994 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076995 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506996
mmenke6b3af6e2015-09-12 02:06:066997 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296998
[email protected]cdf8f7e72013-05-23 10:56:466999 scoped_ptr<SpdyFrame> stream1_syn(
7000 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:297001
7002 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137003 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:297004 };
7005
7006 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027007 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:297008
7009 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027010 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:297011
7012 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027013 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:297014 0,
7015 2,
7016 1,
7017 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:437018 const char kPushedData[] = "pushed";
7019 scoped_ptr<SpdyFrame> stream2_body(
7020 spdy_util_.ConstructSpdyBodyFrame(
7021 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:297022
7023 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137024 CreateMockRead(*stream1_reply, 1, ASYNC),
7025 CreateMockRead(*stream2_syn, 2, ASYNC),
7026 CreateMockRead(*stream1_body, 3, ASYNC),
7027 CreateMockRead(*stream2_body, 4, ASYNC),
7028 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:297029 };
7030
rch8e6c6c42015-05-01 14:05:137031 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7032 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077033 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:297034 // Negotiate SPDY to the proxy
7035 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027036 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077037 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:297038
[email protected]262eec82013-03-19 21:01:367039 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507040 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:297041 TestCompletionCallback callback;
7042 int rv = trans->Start(&request, callback.callback(), log.bound());
7043 EXPECT_EQ(ERR_IO_PENDING, rv);
7044
7045 rv = callback.WaitForResult();
7046 EXPECT_EQ(OK, rv);
7047 const HttpResponseInfo* response = trans->GetResponseInfo();
7048
[email protected]262eec82013-03-19 21:01:367049 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:507050 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7051 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:297052 EXPECT_EQ(ERR_IO_PENDING, rv);
7053
7054 rv = callback.WaitForResult();
7055 EXPECT_EQ(OK, rv);
7056 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
7057
7058 ASSERT_TRUE(response != NULL);
7059 EXPECT_TRUE(response->headers->IsKeepAlive());
7060
7061 EXPECT_EQ(200, response->headers->response_code());
7062 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7063
7064 std::string response_data;
7065 rv = ReadTransaction(trans.get(), &response_data);
7066 EXPECT_EQ(OK, rv);
7067 EXPECT_EQ("hello!", response_data);
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_CONNECT_TIMES_ONLY);
7073
[email protected]7c6f7ba2012-04-03 04:09:297074 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:507075 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:297076 EXPECT_EQ(200, push_response->headers->response_code());
7077
7078 rv = ReadTransaction(push_trans.get(), &response_data);
7079 EXPECT_EQ(OK, rv);
7080 EXPECT_EQ("pushed", response_data);
7081
[email protected]029c83b62013-01-24 05:28:207082 LoadTimingInfo push_load_timing_info;
7083 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
7084 TestLoadTimingReusedWithPac(push_load_timing_info);
7085 // The transactions should share a socket ID, despite being for different
7086 // origins.
7087 EXPECT_EQ(load_timing_info.socket_log_id,
7088 push_load_timing_info.socket_log_id);
7089
[email protected]7c6f7ba2012-04-03 04:09:297090 trans.reset();
7091 push_trans.reset();
7092 session->CloseAllConnections();
7093}
7094
[email protected]8c843192012-04-05 07:15:007095// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:027096TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:007097 HttpRequestInfo request;
7098
7099 request.method = "GET";
bncce36dca22015-04-21 22:11:237100 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:007101
[email protected]8c843192012-04-05 07:15:007102 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037103 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:517104 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077105 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507106
7107 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:077108 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:507109
mmenke6b3af6e2015-09-12 02:06:067110 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:007111
[email protected]cdf8f7e72013-05-23 10:56:467112 scoped_ptr<SpdyFrame> stream1_syn(
7113 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:007114
7115 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:207116 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:007117
7118 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137119 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:007120 };
7121
7122 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027123 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:007124
7125 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027126 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:007127
7128 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027129 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:007130 0,
7131 2,
7132 1,
7133 "https://www.another-origin.com/foo.dat"));
7134
7135 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137136 CreateMockRead(*stream1_reply, 1, ASYNC),
7137 CreateMockRead(*stream2_syn, 2, ASYNC),
7138 CreateMockRead(*stream1_body, 4, ASYNC),
7139 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:007140 };
7141
rch8e6c6c42015-05-01 14:05:137142 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7143 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077144 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007145 // Negotiate SPDY to the proxy
7146 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027147 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077148 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007149
[email protected]262eec82013-03-19 21:01:367150 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507151 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007152 TestCompletionCallback callback;
7153 int rv = trans->Start(&request, callback.callback(), log.bound());
7154 EXPECT_EQ(ERR_IO_PENDING, rv);
7155
7156 rv = callback.WaitForResult();
7157 EXPECT_EQ(OK, rv);
7158 const HttpResponseInfo* response = trans->GetResponseInfo();
7159
7160 ASSERT_TRUE(response != NULL);
7161 EXPECT_TRUE(response->headers->IsKeepAlive());
7162
7163 EXPECT_EQ(200, response->headers->response_code());
7164 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7165
7166 std::string response_data;
7167 rv = ReadTransaction(trans.get(), &response_data);
7168 EXPECT_EQ(OK, rv);
7169 EXPECT_EQ("hello!", response_data);
7170
7171 trans.reset();
7172 session->CloseAllConnections();
7173}
7174
[email protected]2df19bb2010-08-25 20:13:467175// Test HTTPS connections to a site with a bad certificate, going through an
7176// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027177TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037178 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:467179
7180 HttpRequestInfo request;
7181 request.method = "GET";
bncce36dca22015-04-21 22:11:237182 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467183 request.load_flags = 0;
7184
7185 // Attempt to fetch the URL from a server with a bad cert
7186 MockWrite bad_cert_writes[] = {
bncce36dca22015-04-21 22:11:237187 MockWrite(
7188 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7189 "Host: www.example.org\r\n"
7190 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467191 };
7192
7193 MockRead bad_cert_reads[] = {
7194 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067195 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467196 };
7197
7198 // Attempt to fetch the URL with a good cert
7199 MockWrite good_data_writes[] = {
bncce36dca22015-04-21 22:11:237200 MockWrite(
7201 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7202 "Host: www.example.org\r\n"
7203 "Proxy-Connection: keep-alive\r\n\r\n"),
7204 MockWrite(
7205 "GET / HTTP/1.1\r\n"
7206 "Host: www.example.org\r\n"
7207 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467208 };
7209
7210 MockRead good_cert_reads[] = {
7211 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7212 MockRead("HTTP/1.0 200 OK\r\n"),
7213 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7214 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067215 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467216 };
7217
7218 StaticSocketDataProvider ssl_bad_certificate(
7219 bad_cert_reads, arraysize(bad_cert_reads),
7220 bad_cert_writes, arraysize(bad_cert_writes));
7221 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7222 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067223 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7224 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467225
7226 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077227 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7228 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7229 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467230
7231 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077232 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7233 session_deps_.socket_factory->AddSocketDataProvider(&data);
7234 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467235
[email protected]49639fa2011-12-20 23:22:417236 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467237
mmenke6b3af6e2015-09-12 02:06:067238 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467239 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417240 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467241
[email protected]49639fa2011-12-20 23:22:417242 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467243 EXPECT_EQ(ERR_IO_PENDING, rv);
7244
7245 rv = callback.WaitForResult();
7246 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7247
[email protected]49639fa2011-12-20 23:22:417248 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467249 EXPECT_EQ(ERR_IO_PENDING, rv);
7250
7251 rv = callback.WaitForResult();
7252 EXPECT_EQ(OK, rv);
7253
7254 const HttpResponseInfo* response = trans->GetResponseInfo();
7255
[email protected]fe2255a2011-09-20 19:37:507256 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467257 EXPECT_EQ(100, response->headers->GetContentLength());
7258}
7259
[email protected]23e482282013-06-14 16:08:027260TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427261 HttpRequestInfo request;
7262 request.method = "GET";
bncce36dca22015-04-21 22:11:237263 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437264 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7265 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427266
mmenke6b3af6e2015-09-12 02:06:067267 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277268 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277270
[email protected]1c773ea12009-04-28 19:58:427271 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237272 MockWrite(
7273 "GET / HTTP/1.1\r\n"
7274 "Host: www.example.org\r\n"
7275 "Connection: keep-alive\r\n"
7276 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427277 };
7278
7279 // Lastly, the server responds with the actual content.
7280 MockRead data_reads[] = {
7281 MockRead("HTTP/1.0 200 OK\r\n"),
7282 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7283 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067284 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427285 };
7286
[email protected]31a2bfe2010-02-09 08:03:397287 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7288 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077289 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427290
[email protected]49639fa2011-12-20 23:22:417291 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427292
[email protected]49639fa2011-12-20 23:22:417293 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427294 EXPECT_EQ(ERR_IO_PENDING, rv);
7295
7296 rv = callback.WaitForResult();
7297 EXPECT_EQ(OK, rv);
7298}
7299
[email protected]23e482282013-06-14 16:08:027300TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297301 HttpRequestInfo request;
7302 request.method = "GET";
bncce36dca22015-04-21 22:11:237303 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297304 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7305 "Chromium Ultra Awesome X Edition");
7306
rdsmith82957ad2015-09-16 19:42:037307 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenke6b3af6e2015-09-12 02:06:067308 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277309 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417310 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277311
[email protected]da81f132010-08-18 23:39:297312 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237313 MockWrite(
7314 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7315 "Host: www.example.org\r\n"
7316 "Proxy-Connection: keep-alive\r\n"
7317 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297318 };
7319 MockRead data_reads[] = {
7320 // Return an error, so the transaction stops here (this test isn't
7321 // interested in the rest).
7322 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7323 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7324 MockRead("Proxy-Connection: close\r\n\r\n"),
7325 };
7326
7327 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7328 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077329 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297330
[email protected]49639fa2011-12-20 23:22:417331 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297332
[email protected]49639fa2011-12-20 23:22:417333 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297334 EXPECT_EQ(ERR_IO_PENDING, rv);
7335
7336 rv = callback.WaitForResult();
7337 EXPECT_EQ(OK, rv);
7338}
7339
[email protected]23e482282013-06-14 16:08:027340TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427341 HttpRequestInfo request;
7342 request.method = "GET";
bncce36dca22015-04-21 22:11:237343 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427344 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167345 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7346 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427347
mmenke6b3af6e2015-09-12 02:06:067348 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277349 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417350 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277351
[email protected]1c773ea12009-04-28 19:58:427352 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237353 MockWrite(
7354 "GET / HTTP/1.1\r\n"
7355 "Host: www.example.org\r\n"
7356 "Connection: keep-alive\r\n"
7357 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427358 };
7359
7360 // Lastly, the server responds with the actual content.
7361 MockRead data_reads[] = {
7362 MockRead("HTTP/1.0 200 OK\r\n"),
7363 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7364 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067365 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427366 };
7367
[email protected]31a2bfe2010-02-09 08:03:397368 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7369 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077370 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427371
[email protected]49639fa2011-12-20 23:22:417372 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427373
[email protected]49639fa2011-12-20 23:22:417374 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427375 EXPECT_EQ(ERR_IO_PENDING, rv);
7376
7377 rv = callback.WaitForResult();
7378 EXPECT_EQ(OK, rv);
7379}
7380
[email protected]23e482282013-06-14 16:08:027381TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427382 HttpRequestInfo request;
7383 request.method = "POST";
bncce36dca22015-04-21 22:11:237384 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427385
mmenke6b3af6e2015-09-12 02:06:067386 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277387 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417388 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277389
[email protected]1c773ea12009-04-28 19:58:427390 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237391 MockWrite(
7392 "POST / HTTP/1.1\r\n"
7393 "Host: www.example.org\r\n"
7394 "Connection: keep-alive\r\n"
7395 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427396 };
7397
7398 // Lastly, the server responds with the actual content.
7399 MockRead data_reads[] = {
7400 MockRead("HTTP/1.0 200 OK\r\n"),
7401 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7402 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067403 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427404 };
7405
[email protected]31a2bfe2010-02-09 08:03:397406 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7407 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077408 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427409
[email protected]49639fa2011-12-20 23:22:417410 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427411
[email protected]49639fa2011-12-20 23:22:417412 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427413 EXPECT_EQ(ERR_IO_PENDING, rv);
7414
7415 rv = callback.WaitForResult();
7416 EXPECT_EQ(OK, rv);
7417}
7418
[email protected]23e482282013-06-14 16:08:027419TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427420 HttpRequestInfo request;
7421 request.method = "PUT";
bncce36dca22015-04-21 22:11:237422 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427423
mmenke6b3af6e2015-09-12 02:06:067424 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277425 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417426 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277427
[email protected]1c773ea12009-04-28 19:58:427428 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237429 MockWrite(
7430 "PUT / HTTP/1.1\r\n"
7431 "Host: www.example.org\r\n"
7432 "Connection: keep-alive\r\n"
7433 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427434 };
7435
7436 // Lastly, the server responds with the actual content.
7437 MockRead data_reads[] = {
7438 MockRead("HTTP/1.0 200 OK\r\n"),
7439 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7440 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067441 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427442 };
7443
[email protected]31a2bfe2010-02-09 08:03:397444 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7445 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077446 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427447
[email protected]49639fa2011-12-20 23:22:417448 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427449
[email protected]49639fa2011-12-20 23:22:417450 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427451 EXPECT_EQ(ERR_IO_PENDING, rv);
7452
7453 rv = callback.WaitForResult();
7454 EXPECT_EQ(OK, rv);
7455}
7456
[email protected]23e482282013-06-14 16:08:027457TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427458 HttpRequestInfo request;
7459 request.method = "HEAD";
bncce36dca22015-04-21 22:11:237460 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427461
mmenke6b3af6e2015-09-12 02:06:067462 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277463 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417464 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277465
[email protected]1c773ea12009-04-28 19:58:427466 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:137467 MockWrite("HEAD / HTTP/1.1\r\n"
7468 "Host: www.example.org\r\n"
7469 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427470 };
7471
7472 // Lastly, the server responds with the actual content.
7473 MockRead data_reads[] = {
7474 MockRead("HTTP/1.0 200 OK\r\n"),
7475 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7476 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067477 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427478 };
7479
[email protected]31a2bfe2010-02-09 08:03:397480 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7481 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077482 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427483
[email protected]49639fa2011-12-20 23:22:417484 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427485
[email protected]49639fa2011-12-20 23:22:417486 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427487 EXPECT_EQ(ERR_IO_PENDING, rv);
7488
7489 rv = callback.WaitForResult();
7490 EXPECT_EQ(OK, rv);
7491}
7492
[email protected]23e482282013-06-14 16:08:027493TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427494 HttpRequestInfo request;
7495 request.method = "GET";
bncce36dca22015-04-21 22:11:237496 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427497 request.load_flags = LOAD_BYPASS_CACHE;
7498
mmenke6b3af6e2015-09-12 02:06:067499 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277500 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417501 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277502
[email protected]1c773ea12009-04-28 19:58:427503 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237504 MockWrite(
7505 "GET / HTTP/1.1\r\n"
7506 "Host: www.example.org\r\n"
7507 "Connection: keep-alive\r\n"
7508 "Pragma: no-cache\r\n"
7509 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427510 };
7511
7512 // Lastly, the server responds with the actual content.
7513 MockRead data_reads[] = {
7514 MockRead("HTTP/1.0 200 OK\r\n"),
7515 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7516 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067517 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427518 };
7519
[email protected]31a2bfe2010-02-09 08:03:397520 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7521 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077522 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427523
[email protected]49639fa2011-12-20 23:22:417524 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427525
[email protected]49639fa2011-12-20 23:22:417526 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427527 EXPECT_EQ(ERR_IO_PENDING, rv);
7528
7529 rv = callback.WaitForResult();
7530 EXPECT_EQ(OK, rv);
7531}
7532
[email protected]23e482282013-06-14 16:08:027533TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427534 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427535 HttpRequestInfo request;
7536 request.method = "GET";
bncce36dca22015-04-21 22:11:237537 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427538 request.load_flags = LOAD_VALIDATE_CACHE;
7539
mmenke6b3af6e2015-09-12 02:06:067540 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277541 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417542 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277543
[email protected]1c773ea12009-04-28 19:58:427544 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237545 MockWrite(
7546 "GET / HTTP/1.1\r\n"
7547 "Host: www.example.org\r\n"
7548 "Connection: keep-alive\r\n"
7549 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427550 };
7551
7552 // Lastly, the server responds with the actual content.
7553 MockRead data_reads[] = {
7554 MockRead("HTTP/1.0 200 OK\r\n"),
7555 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7556 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067557 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427558 };
7559
[email protected]31a2bfe2010-02-09 08:03:397560 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7561 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077562 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427563
[email protected]49639fa2011-12-20 23:22:417564 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427565
[email protected]49639fa2011-12-20 23:22:417566 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427567 EXPECT_EQ(ERR_IO_PENDING, rv);
7568
7569 rv = callback.WaitForResult();
7570 EXPECT_EQ(OK, rv);
7571}
7572
[email protected]23e482282013-06-14 16:08:027573TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427574 HttpRequestInfo request;
7575 request.method = "GET";
bncce36dca22015-04-21 22:11:237576 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437577 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427578
mmenke6b3af6e2015-09-12 02:06:067579 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277580 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417581 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277582
[email protected]1c773ea12009-04-28 19:58:427583 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237584 MockWrite(
7585 "GET / HTTP/1.1\r\n"
7586 "Host: www.example.org\r\n"
7587 "Connection: keep-alive\r\n"
7588 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427589 };
7590
7591 // Lastly, the server responds with the actual content.
7592 MockRead data_reads[] = {
7593 MockRead("HTTP/1.0 200 OK\r\n"),
7594 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7595 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067596 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427597 };
7598
[email protected]31a2bfe2010-02-09 08:03:397599 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7600 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077601 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427602
[email protected]49639fa2011-12-20 23:22:417603 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427604
[email protected]49639fa2011-12-20 23:22:417605 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427606 EXPECT_EQ(ERR_IO_PENDING, rv);
7607
7608 rv = callback.WaitForResult();
7609 EXPECT_EQ(OK, rv);
7610}
7611
[email protected]23e482282013-06-14 16:08:027612TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477613 HttpRequestInfo request;
7614 request.method = "GET";
bncce36dca22015-04-21 22:11:237615 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437616 request.extra_headers.SetHeader("referer", "www.foo.com");
7617 request.extra_headers.SetHeader("hEllo", "Kitty");
7618 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477619
mmenke6b3af6e2015-09-12 02:06:067620 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277621 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417622 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277623
[email protected]270c6412010-03-29 22:02:477624 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237625 MockWrite(
7626 "GET / HTTP/1.1\r\n"
7627 "Host: www.example.org\r\n"
7628 "Connection: keep-alive\r\n"
7629 "referer: www.foo.com\r\n"
7630 "hEllo: Kitty\r\n"
7631 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:477632 };
7633
7634 // Lastly, the server responds with the actual content.
7635 MockRead data_reads[] = {
7636 MockRead("HTTP/1.0 200 OK\r\n"),
7637 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7638 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067639 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477640 };
7641
7642 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7643 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077644 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477645
[email protected]49639fa2011-12-20 23:22:417646 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477647
[email protected]49639fa2011-12-20 23:22:417648 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477649 EXPECT_EQ(ERR_IO_PENDING, rv);
7650
7651 rv = callback.WaitForResult();
7652 EXPECT_EQ(OK, rv);
7653}
7654
[email protected]23e482282013-06-14 16:08:027655TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277656 HttpRequestInfo request;
7657 request.method = "GET";
bncce36dca22015-04-21 22:11:237658 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277659 request.load_flags = 0;
7660
rdsmith82957ad2015-09-16 19:42:037661 session_deps_.proxy_service =
7662 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:517663 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077664 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027665
mmenke6b3af6e2015-09-12 02:06:067666 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027667 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417668 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027669
[email protected]3cd17242009-06-23 02:59:027670 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7671 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7672
7673 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237674 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7675 MockWrite(
7676 "GET / HTTP/1.1\r\n"
7677 "Host: www.example.org\r\n"
7678 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027679
7680 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067681 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027682 MockRead("HTTP/1.0 200 OK\r\n"),
7683 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7684 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067685 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027686 };
7687
[email protected]31a2bfe2010-02-09 08:03:397688 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7689 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077690 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027691
[email protected]49639fa2011-12-20 23:22:417692 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027693
[email protected]49639fa2011-12-20 23:22:417694 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027695 EXPECT_EQ(ERR_IO_PENDING, rv);
7696
7697 rv = callback.WaitForResult();
7698 EXPECT_EQ(OK, rv);
7699
7700 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507701 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027702
[email protected]029c83b62013-01-24 05:28:207703 LoadTimingInfo load_timing_info;
7704 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7705 TestLoadTimingNotReusedWithPac(load_timing_info,
7706 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7707
[email protected]3cd17242009-06-23 02:59:027708 std::string response_text;
7709 rv = ReadTransaction(trans.get(), &response_text);
7710 EXPECT_EQ(OK, rv);
7711 EXPECT_EQ("Payload", response_text);
7712}
7713
[email protected]23e482282013-06-14 16:08:027714TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277715 HttpRequestInfo request;
7716 request.method = "GET";
bncce36dca22015-04-21 22:11:237717 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277718 request.load_flags = 0;
7719
rdsmith82957ad2015-09-16 19:42:037720 session_deps_.proxy_service =
7721 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:517722 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077723 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027724
mmenke6b3af6e2015-09-12 02:06:067725 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027726 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417727 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027728
[email protected]3cd17242009-06-23 02:59:027729 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7730 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7731
7732 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237733 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7734 arraysize(write_buffer)),
7735 MockWrite(
7736 "GET / HTTP/1.1\r\n"
7737 "Host: www.example.org\r\n"
7738 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027739
7740 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017741 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7742 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357743 MockRead("HTTP/1.0 200 OK\r\n"),
7744 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7745 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067746 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357747 };
7748
[email protected]31a2bfe2010-02-09 08:03:397749 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7750 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077751 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357752
[email protected]8ddf8322012-02-23 18:08:067753 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077754 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357755
[email protected]49639fa2011-12-20 23:22:417756 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357757
[email protected]49639fa2011-12-20 23:22:417758 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357759 EXPECT_EQ(ERR_IO_PENDING, rv);
7760
7761 rv = callback.WaitForResult();
7762 EXPECT_EQ(OK, rv);
7763
[email protected]029c83b62013-01-24 05:28:207764 LoadTimingInfo load_timing_info;
7765 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7766 TestLoadTimingNotReusedWithPac(load_timing_info,
7767 CONNECT_TIMING_HAS_SSL_TIMES);
7768
[email protected]e0c27be2009-07-15 13:09:357769 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507770 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357771
7772 std::string response_text;
7773 rv = ReadTransaction(trans.get(), &response_text);
7774 EXPECT_EQ(OK, rv);
7775 EXPECT_EQ("Payload", response_text);
7776}
7777
[email protected]23e482282013-06-14 16:08:027778TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207779 HttpRequestInfo request;
7780 request.method = "GET";
bncce36dca22015-04-21 22:11:237781 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:207782 request.load_flags = 0;
7783
rdsmith82957ad2015-09-16 19:42:037784 session_deps_.proxy_service =
7785 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:517786 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077787 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207788
mmenke6b3af6e2015-09-12 02:06:067789 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207790 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417791 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207792
7793 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7794 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7795
7796 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237797 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7798 MockWrite(
7799 "GET / HTTP/1.1\r\n"
7800 "Host: www.example.org\r\n"
7801 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:207802
7803 MockRead data_reads[] = {
7804 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7805 MockRead("HTTP/1.0 200 OK\r\n"),
7806 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7807 MockRead("Payload"),
7808 MockRead(SYNCHRONOUS, OK)
7809 };
7810
7811 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7812 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077813 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207814
7815 TestCompletionCallback callback;
7816
7817 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7818 EXPECT_EQ(ERR_IO_PENDING, rv);
7819
7820 rv = callback.WaitForResult();
7821 EXPECT_EQ(OK, rv);
7822
7823 const HttpResponseInfo* response = trans->GetResponseInfo();
7824 ASSERT_TRUE(response != NULL);
7825
7826 LoadTimingInfo load_timing_info;
7827 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7828 TestLoadTimingNotReused(load_timing_info,
7829 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7830
7831 std::string response_text;
7832 rv = ReadTransaction(trans.get(), &response_text);
7833 EXPECT_EQ(OK, rv);
7834 EXPECT_EQ("Payload", response_text);
7835}
7836
[email protected]23e482282013-06-14 16:08:027837TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277838 HttpRequestInfo request;
7839 request.method = "GET";
bncce36dca22015-04-21 22:11:237840 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277841 request.load_flags = 0;
7842
rdsmith82957ad2015-09-16 19:42:037843 session_deps_.proxy_service =
7844 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:517845 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077846 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357847
mmenke6b3af6e2015-09-12 02:06:067848 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357849 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417850 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357851
[email protected]e0c27be2009-07-15 13:09:357852 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7853 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377854 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237855 0x05, // Version
7856 0x01, // Command (CONNECT)
7857 0x00, // Reserved.
7858 0x03, // Address type (DOMAINNAME).
7859 0x0F, // Length of domain (15)
7860 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7861 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:377862 };
[email protected]e0c27be2009-07-15 13:09:357863 const char kSOCKS5OkResponse[] =
7864 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7865
7866 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237867 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7868 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7869 MockWrite(
7870 "GET / HTTP/1.1\r\n"
7871 "Host: www.example.org\r\n"
7872 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357873
7874 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017875 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7876 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357877 MockRead("HTTP/1.0 200 OK\r\n"),
7878 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7879 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067880 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357881 };
7882
[email protected]31a2bfe2010-02-09 08:03:397883 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7884 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077885 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357886
[email protected]49639fa2011-12-20 23:22:417887 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357888
[email protected]49639fa2011-12-20 23:22:417889 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357890 EXPECT_EQ(ERR_IO_PENDING, rv);
7891
7892 rv = callback.WaitForResult();
7893 EXPECT_EQ(OK, rv);
7894
7895 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507896 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357897
[email protected]029c83b62013-01-24 05:28:207898 LoadTimingInfo load_timing_info;
7899 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7900 TestLoadTimingNotReusedWithPac(load_timing_info,
7901 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7902
[email protected]e0c27be2009-07-15 13:09:357903 std::string response_text;
7904 rv = ReadTransaction(trans.get(), &response_text);
7905 EXPECT_EQ(OK, rv);
7906 EXPECT_EQ("Payload", response_text);
7907}
7908
[email protected]23e482282013-06-14 16:08:027909TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277910 HttpRequestInfo request;
7911 request.method = "GET";
bncce36dca22015-04-21 22:11:237912 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277913 request.load_flags = 0;
7914
rdsmith82957ad2015-09-16 19:42:037915 session_deps_.proxy_service =
7916 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:517917 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077918 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357919
mmenke6b3af6e2015-09-12 02:06:067920 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357921 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357923
[email protected]e0c27be2009-07-15 13:09:357924 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7925 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377926 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237927 0x05, // Version
7928 0x01, // Command (CONNECT)
7929 0x00, // Reserved.
7930 0x03, // Address type (DOMAINNAME).
7931 0x0F, // Length of domain (15)
7932 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7933 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:377934 };
7935
[email protected]e0c27be2009-07-15 13:09:357936 const char kSOCKS5OkResponse[] =
7937 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7938
7939 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237940 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7941 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7942 arraysize(kSOCKS5OkRequest)),
7943 MockWrite(
7944 "GET / HTTP/1.1\r\n"
7945 "Host: www.example.org\r\n"
7946 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357947
7948 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017949 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7950 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027951 MockRead("HTTP/1.0 200 OK\r\n"),
7952 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7953 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067954 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027955 };
7956
[email protected]31a2bfe2010-02-09 08:03:397957 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7958 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077959 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027960
[email protected]8ddf8322012-02-23 18:08:067961 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077962 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027963
[email protected]49639fa2011-12-20 23:22:417964 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027965
[email protected]49639fa2011-12-20 23:22:417966 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027967 EXPECT_EQ(ERR_IO_PENDING, rv);
7968
7969 rv = callback.WaitForResult();
7970 EXPECT_EQ(OK, rv);
7971
7972 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507973 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027974
[email protected]029c83b62013-01-24 05:28:207975 LoadTimingInfo load_timing_info;
7976 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7977 TestLoadTimingNotReusedWithPac(load_timing_info,
7978 CONNECT_TIMING_HAS_SSL_TIMES);
7979
[email protected]3cd17242009-06-23 02:59:027980 std::string response_text;
7981 rv = ReadTransaction(trans.get(), &response_text);
7982 EXPECT_EQ(OK, rv);
7983 EXPECT_EQ("Payload", response_text);
7984}
7985
[email protected]448d4ca52012-03-04 04:12:237986namespace {
7987
[email protected]04e5be32009-06-26 20:00:317988// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067989
7990struct GroupNameTest {
7991 std::string proxy_server;
7992 std::string url;
7993 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187994 bool ssl;
[email protected]2d731a32010-04-29 01:04:067995};
7996
mmenke6b3af6e2015-09-12 02:06:067997scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437998 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077999 SpdySessionDependencies* session_deps_) {
mmenke6b3af6e2015-09-12 02:06:068000 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:068001
[email protected]30d4c022013-07-18 22:58:168002 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538003 session->http_server_properties();
bnccacc0992015-03-20 20:22:228004 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:258005 AlternateProtocolFromNextProto(next_proto), "", 443);
bnc7dc7e1b42015-07-28 14:43:128006 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:228007 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:128008 HostPortPair("host.with.alternate", 80), alternative_service, 1.0,
8009 expiration);
[email protected]2d731a32010-04-29 01:04:068010
8011 return session;
8012}
8013
mmenke6b3af6e2015-09-12 02:06:068014int GroupNameTransactionHelper(
8015 const std::string& url,
8016 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:068017 HttpRequestInfo request;
8018 request.method = "GET";
8019 request.url = GURL(url);
8020 request.load_flags = 0;
8021
[email protected]262eec82013-03-19 21:01:368022 scoped_ptr<HttpTransaction> trans(
mmenke6b3af6e2015-09-12 02:06:068023 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278024
[email protected]49639fa2011-12-20 23:22:418025 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:068026
8027 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:418028 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:068029}
8030
[email protected]448d4ca52012-03-04 04:12:238031} // namespace
8032
[email protected]23e482282013-06-14 16:08:028033TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:068034 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238035 {
8036 "", // unused
8037 "http://www.example.org/direct",
8038 "www.example.org:80",
8039 false,
8040 },
8041 {
8042 "", // unused
8043 "http://[2001:1418:13:1::25]/direct",
8044 "[2001:1418:13:1::25]:80",
8045 false,
8046 },
[email protected]04e5be32009-06-26 20:00:318047
bncce36dca22015-04-21 22:11:238048 // SSL Tests
8049 {
8050 "", // unused
8051 "https://www.example.org/direct_ssl",
8052 "ssl/www.example.org:443",
8053 true,
8054 },
8055 {
8056 "", // unused
8057 "https://[2001:1418:13:1::25]/direct",
8058 "ssl/[2001:1418:13:1::25]:443",
8059 true,
8060 },
8061 {
8062 "", // unused
8063 "http://host.with.alternate/direct",
8064 "ssl/host.with.alternate:443",
8065 true,
8066 },
[email protected]2d731a32010-04-29 01:04:068067 };
[email protected]2ff8b312010-04-26 22:20:548068
bnc55ff9da2015-08-19 18:42:358069 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068070
viettrungluue4a8b882014-10-16 06:17:388071 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038072 session_deps_.proxy_service =
8073 ProxyService::CreateFixed(tests[i].proxy_server);
mmenke6b3af6e2015-09-12 02:06:068074 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438075 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068076
mmenke6b3af6e2015-09-12 02:06:068077 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:288078 CaptureGroupNameTransportSocketPool* transport_conn_pool =
8079 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138080 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348081 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:448082 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8083 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028084 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
8085 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518086 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068087
8088 EXPECT_EQ(ERR_IO_PENDING,
mmenke6b3af6e2015-09-12 02:06:068089 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188090 if (tests[i].ssl)
8091 EXPECT_EQ(tests[i].expected_group_name,
8092 ssl_conn_pool->last_group_name_received());
8093 else
8094 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:288095 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068096 }
[email protected]2d731a32010-04-29 01:04:068097}
8098
[email protected]23e482282013-06-14 16:08:028099TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:068100 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238101 {
8102 "http_proxy",
8103 "http://www.example.org/http_proxy_normal",
8104 "www.example.org:80",
8105 false,
8106 },
[email protected]2d731a32010-04-29 01:04:068107
bncce36dca22015-04-21 22:11:238108 // SSL Tests
8109 {
8110 "http_proxy",
8111 "https://www.example.org/http_connect_ssl",
8112 "ssl/www.example.org:443",
8113 true,
8114 },
[email protected]af3490e2010-10-16 21:02:298115
bncce36dca22015-04-21 22:11:238116 {
8117 "http_proxy",
8118 "http://host.with.alternate/direct",
8119 "ssl/host.with.alternate:443",
8120 true,
8121 },
[email protected]45499252013-01-23 17:12:568122
bncce36dca22015-04-21 22:11:238123 {
8124 "http_proxy",
8125 "ftp://ftp.google.com/http_proxy_normal",
8126 "ftp/ftp.google.com:21",
8127 false,
8128 },
[email protected]2d731a32010-04-29 01:04:068129 };
8130
bnc55ff9da2015-08-19 18:42:358131 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068132
viettrungluue4a8b882014-10-16 06:17:388133 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038134 session_deps_.proxy_service =
8135 ProxyService::CreateFixed(tests[i].proxy_server);
mmenke6b3af6e2015-09-12 02:06:068136 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438137 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068138
mmenke6b3af6e2015-09-12 02:06:068139 HttpNetworkSessionPeer peer(session);
[email protected]2d731a32010-04-29 01:04:068140
[email protected]e60e47a2010-07-14 03:37:188141 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138142 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348143 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138144 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348145 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028146
[email protected]831e4a32013-11-14 02:14:448147 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8148 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028149 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8150 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518151 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068152
8153 EXPECT_EQ(ERR_IO_PENDING,
mmenke6b3af6e2015-09-12 02:06:068154 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188155 if (tests[i].ssl)
8156 EXPECT_EQ(tests[i].expected_group_name,
8157 ssl_conn_pool->last_group_name_received());
8158 else
8159 EXPECT_EQ(tests[i].expected_group_name,
8160 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068161 }
[email protected]2d731a32010-04-29 01:04:068162}
8163
[email protected]23e482282013-06-14 16:08:028164TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068165 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238166 {
8167 "socks4://socks_proxy:1080",
8168 "http://www.example.org/socks4_direct",
8169 "socks4/www.example.org:80",
8170 false,
8171 },
8172 {
8173 "socks5://socks_proxy:1080",
8174 "http://www.example.org/socks5_direct",
8175 "socks5/www.example.org:80",
8176 false,
8177 },
[email protected]2d731a32010-04-29 01:04:068178
bncce36dca22015-04-21 22:11:238179 // SSL Tests
8180 {
8181 "socks4://socks_proxy:1080",
8182 "https://www.example.org/socks4_ssl",
8183 "socks4/ssl/www.example.org:443",
8184 true,
8185 },
8186 {
8187 "socks5://socks_proxy:1080",
8188 "https://www.example.org/socks5_ssl",
8189 "socks5/ssl/www.example.org:443",
8190 true,
8191 },
[email protected]af3490e2010-10-16 21:02:298192
bncce36dca22015-04-21 22:11:238193 {
8194 "socks4://socks_proxy:1080",
8195 "http://host.with.alternate/direct",
8196 "socks4/ssl/host.with.alternate:443",
8197 true,
8198 },
[email protected]04e5be32009-06-26 20:00:318199 };
8200
bnc55ff9da2015-08-19 18:42:358201 session_deps_.use_alternative_services = true;
[email protected]2ff8b312010-04-26 22:20:548202
viettrungluue4a8b882014-10-16 06:17:388203 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038204 session_deps_.proxy_service =
8205 ProxyService::CreateFixed(tests[i].proxy_server);
mmenke6b3af6e2015-09-12 02:06:068206 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438207 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028208
mmenke6b3af6e2015-09-12 02:06:068209 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318210
[email protected]e60e47a2010-07-14 03:37:188211 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138212 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348213 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138214 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348215 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028216
[email protected]831e4a32013-11-14 02:14:448217 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8218 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028219 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8220 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518221 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318222
[email protected]262eec82013-03-19 21:01:368223 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508224 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318225
[email protected]2d731a32010-04-29 01:04:068226 EXPECT_EQ(ERR_IO_PENDING,
mmenke6b3af6e2015-09-12 02:06:068227 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188228 if (tests[i].ssl)
8229 EXPECT_EQ(tests[i].expected_group_name,
8230 ssl_conn_pool->last_group_name_received());
8231 else
8232 EXPECT_EQ(tests[i].expected_group_name,
8233 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318234 }
8235}
8236
[email protected]23e482282013-06-14 16:08:028237TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278238 HttpRequestInfo request;
8239 request.method = "GET";
bncce36dca22015-04-21 22:11:238240 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278241
rdsmith82957ad2015-09-16 19:42:038242 session_deps_.proxy_service =
8243 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:328244
[email protected]69719062010-01-05 20:09:218245 // This simulates failure resolving all hostnames; that means we will fail
8246 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078247 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328248
mmenke6b3af6e2015-09-12 02:06:068249 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258250 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418251 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258252
[email protected]49639fa2011-12-20 23:22:418253 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258254
[email protected]49639fa2011-12-20 23:22:418255 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258256 EXPECT_EQ(ERR_IO_PENDING, rv);
8257
[email protected]9172a982009-06-06 00:30:258258 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018259 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258260}
8261
[email protected]685af592010-05-11 19:31:248262// Base test to make sure that when the load flags for a request specify to
8263// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028264void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078265 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278266 // Issue a request, asking to bypass the cache(s).
8267 HttpRequestInfo request;
8268 request.method = "GET";
8269 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238270 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278271
[email protected]a2c2fb92009-07-18 07:31:048272 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078273 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328274
mmenke6b3af6e2015-09-12 02:06:068275 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:078276 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418277 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288278
bncce36dca22015-04-21 22:11:238279 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288280 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298281 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078282 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238283 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8284 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478285 EXPECT_EQ(ERR_IO_PENDING, rv);
8286 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288287 EXPECT_EQ(OK, rv);
8288
8289 // Verify that it was added to host cache, by doing a subsequent async lookup
8290 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078291 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238292 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8293 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328294 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288295
bncce36dca22015-04-21 22:11:238296 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288297 // we can tell if the next lookup hit the cache, or the "network".
8298 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238299 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288300
8301 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8302 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068303 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398304 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078305 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288306
[email protected]3b9cca42009-06-16 01:08:288307 // Run the request.
[email protected]49639fa2011-12-20 23:22:418308 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288309 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418310 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288311
8312 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238313 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288314 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8315}
8316
[email protected]685af592010-05-11 19:31:248317// There are multiple load flags that should trigger the host cache bypass.
8318// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028319TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248320 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8321}
8322
[email protected]23e482282013-06-14 16:08:028323TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248324 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8325}
8326
[email protected]23e482282013-06-14 16:08:028327TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248328 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8329}
8330
[email protected]0877e3d2009-10-17 22:29:578331// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028332TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578333 HttpRequestInfo request;
8334 request.method = "GET";
8335 request.url = GURL("http://www.foo.com/");
8336 request.load_flags = 0;
8337
8338 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068339 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578340 };
[email protected]31a2bfe2010-02-09 08:03:398341 StaticSocketDataProvider data(NULL, 0,
8342 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078343 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenke6b3af6e2015-09-12 02:06:068344 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578345
[email protected]49639fa2011-12-20 23:22:418346 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578347
8348 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418349 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578350
[email protected]49639fa2011-12-20 23:22:418351 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578352 EXPECT_EQ(ERR_IO_PENDING, rv);
8353
8354 rv = callback.WaitForResult();
8355 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:598356
8357 IPEndPoint endpoint;
8358 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
8359 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:578360}
8361
zmo9528c9f42015-08-04 22:12:088362// Check that a connection closed after the start of the headers finishes ok.
8363TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578364 HttpRequestInfo request;
8365 request.method = "GET";
8366 request.url = GURL("http://www.foo.com/");
8367 request.load_flags = 0;
8368
8369 MockRead data_reads[] = {
8370 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068371 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578372 };
8373
[email protected]31a2bfe2010-02-09 08:03:398374 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078375 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenke6b3af6e2015-09-12 02:06:068376 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578377
[email protected]49639fa2011-12-20 23:22:418378 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578379
8380 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418381 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578382
[email protected]49639fa2011-12-20 23:22:418383 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578384 EXPECT_EQ(ERR_IO_PENDING, rv);
8385
8386 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:088387 EXPECT_EQ(OK, rv);
8388
8389 const HttpResponseInfo* response = trans->GetResponseInfo();
8390 ASSERT_TRUE(response != NULL);
8391
8392 EXPECT_TRUE(response->headers.get() != NULL);
8393 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8394
8395 std::string response_data;
8396 rv = ReadTransaction(trans.get(), &response_data);
8397 EXPECT_EQ(OK, rv);
8398 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:598399
8400 IPEndPoint endpoint;
8401 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
8402 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:578403}
8404
8405// Make sure that a dropped connection while draining the body for auth
8406// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028407TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578408 HttpRequestInfo request;
8409 request.method = "GET";
bncce36dca22015-04-21 22:11:238410 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578411 request.load_flags = 0;
8412
8413 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238414 MockWrite(
8415 "GET / HTTP/1.1\r\n"
8416 "Host: www.example.org\r\n"
8417 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578418 };
8419
8420 MockRead data_reads1[] = {
8421 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8422 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8423 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8424 MockRead("Content-Length: 14\r\n\r\n"),
8425 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068426 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578427 };
8428
[email protected]31a2bfe2010-02-09 08:03:398429 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8430 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078431 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578432
8433 // After calling trans->RestartWithAuth(), this is the request we should
8434 // be issuing -- the final header line contains the credentials.
8435 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238436 MockWrite(
8437 "GET / HTTP/1.1\r\n"
8438 "Host: www.example.org\r\n"
8439 "Connection: keep-alive\r\n"
8440 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578441 };
8442
8443 // Lastly, the server responds with the actual content.
8444 MockRead data_reads2[] = {
8445 MockRead("HTTP/1.1 200 OK\r\n"),
8446 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8447 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068448 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578449 };
8450
[email protected]31a2bfe2010-02-09 08:03:398451 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8452 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078453 session_deps_.socket_factory->AddSocketDataProvider(&data2);
mmenke6b3af6e2015-09-12 02:06:068454 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578455
[email protected]49639fa2011-12-20 23:22:418456 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578457
[email protected]262eec82013-03-19 21:01:368458 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508459 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508460
[email protected]49639fa2011-12-20 23:22:418461 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578462 EXPECT_EQ(ERR_IO_PENDING, rv);
8463
8464 rv = callback1.WaitForResult();
8465 EXPECT_EQ(OK, rv);
8466
8467 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508468 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048469 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578470
[email protected]49639fa2011-12-20 23:22:418471 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578472
[email protected]49639fa2011-12-20 23:22:418473 rv = trans->RestartWithAuth(
8474 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578475 EXPECT_EQ(ERR_IO_PENDING, rv);
8476
8477 rv = callback2.WaitForResult();
8478 EXPECT_EQ(OK, rv);
8479
8480 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508481 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578482 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8483 EXPECT_EQ(100, response->headers->GetContentLength());
8484}
8485
8486// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028487TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:038488 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:578489
8490 HttpRequestInfo request;
8491 request.method = "GET";
bncce36dca22015-04-21 22:11:238492 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578493 request.load_flags = 0;
8494
8495 MockRead proxy_reads[] = {
8496 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068497 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578498 };
8499
[email protected]31a2bfe2010-02-09 08:03:398500 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068501 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578502
[email protected]bb88e1d32013-05-03 23:11:078503 session_deps_.socket_factory->AddSocketDataProvider(&data);
8504 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578505
[email protected]49639fa2011-12-20 23:22:418506 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578507
[email protected]bb88e1d32013-05-03 23:11:078508 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578509
mmenke6b3af6e2015-09-12 02:06:068510 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578511 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418512 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578513
[email protected]49639fa2011-12-20 23:22:418514 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578515 EXPECT_EQ(ERR_IO_PENDING, rv);
8516
8517 rv = callback.WaitForResult();
8518 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8519}
8520
[email protected]23e482282013-06-14 16:08:028521TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468522 HttpRequestInfo request;
8523 request.method = "GET";
bncce36dca22015-04-21 22:11:238524 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:468525 request.load_flags = 0;
8526
mmenke6b3af6e2015-09-12 02:06:068527 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278528 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418529 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278530
[email protected]e22e1362009-11-23 21:31:128531 MockRead data_reads[] = {
8532 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068533 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128534 };
[email protected]9492e4a2010-02-24 00:58:468535
8536 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078537 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468538
[email protected]49639fa2011-12-20 23:22:418539 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468540
[email protected]49639fa2011-12-20 23:22:418541 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468542 EXPECT_EQ(ERR_IO_PENDING, rv);
8543
8544 EXPECT_EQ(OK, callback.WaitForResult());
8545
8546 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508547 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468548
[email protected]90499482013-06-01 00:39:508549 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468550 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8551
8552 std::string response_data;
8553 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238554 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128555}
8556
[email protected]23e482282013-06-14 16:08:028557TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158558 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528559 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338560 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218561 UploadFileElementReader::ScopedOverridingContentLengthForTests
8562 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338563
[email protected]b2d26cfd2012-12-11 10:36:068564 ScopedVector<UploadElementReader> element_readers;
8565 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458566 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8567 temp_file_path, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078568 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278569
8570 HttpRequestInfo request;
8571 request.method = "POST";
bncce36dca22015-04-21 22:11:238572 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278573 request.upload_data_stream = &upload_data_stream;
8574 request.load_flags = 0;
8575
mmenke6b3af6e2015-09-12 02:06:068576 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278577 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418578 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338579
8580 MockRead data_reads[] = {
8581 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8582 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068583 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338584 };
[email protected]31a2bfe2010-02-09 08:03:398585 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078586 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338587
[email protected]49639fa2011-12-20 23:22:418588 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338589
[email protected]49639fa2011-12-20 23:22:418590 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338591 EXPECT_EQ(ERR_IO_PENDING, rv);
8592
8593 rv = callback.WaitForResult();
8594 EXPECT_EQ(OK, rv);
8595
8596 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508597 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338598
[email protected]90499482013-06-01 00:39:508599 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338600 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8601
8602 std::string response_data;
8603 rv = ReadTransaction(trans.get(), &response_data);
8604 EXPECT_EQ(OK, rv);
8605 EXPECT_EQ("hello world", response_data);
8606
[email protected]dd3aa792013-07-16 19:10:238607 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338608}
8609
[email protected]23e482282013-06-14 16:08:028610TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158611 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528612 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368613 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308614 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368615 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118616 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368617
[email protected]b2d26cfd2012-12-11 10:36:068618 ScopedVector<UploadElementReader> element_readers;
8619 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458620 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8621 temp_file, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078622 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278623
8624 HttpRequestInfo request;
8625 request.method = "POST";
bncce36dca22015-04-21 22:11:238626 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278627 request.upload_data_stream = &upload_data_stream;
8628 request.load_flags = 0;
8629
[email protected]999dd8c2013-11-12 06:45:548630 // If we try to upload an unreadable file, the transaction should fail.
mmenke6b3af6e2015-09-12 02:06:068631 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278632 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418633 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368634
[email protected]999dd8c2013-11-12 06:45:548635 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078636 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368637
[email protected]49639fa2011-12-20 23:22:418638 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368639
[email protected]49639fa2011-12-20 23:22:418640 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368641 EXPECT_EQ(ERR_IO_PENDING, rv);
8642
8643 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548644 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368645
[email protected]dd3aa792013-07-16 19:10:238646 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368647}
8648
[email protected]02cad5d2013-10-02 08:14:038649TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8650 class FakeUploadElementReader : public UploadElementReader {
8651 public:
8652 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208653 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038654
8655 const CompletionCallback& callback() const { return callback_; }
8656
8657 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208658 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038659 callback_ = callback;
8660 return ERR_IO_PENDING;
8661 }
dchengb03027d2014-10-21 12:00:208662 uint64 GetContentLength() const override { return 0; }
8663 uint64 BytesRemaining() const override { return 0; }
8664 int Read(IOBuffer* buf,
8665 int buf_length,
8666 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038667 return ERR_FAILED;
8668 }
8669
8670 private:
8671 CompletionCallback callback_;
8672 };
8673
8674 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8675 ScopedVector<UploadElementReader> element_readers;
8676 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078677 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038678
8679 HttpRequestInfo request;
8680 request.method = "POST";
bncce36dca22015-04-21 22:11:238681 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:038682 request.upload_data_stream = &upload_data_stream;
8683 request.load_flags = 0;
8684
mmenke6b3af6e2015-09-12 02:06:068685 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038686 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418687 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038688
8689 StaticSocketDataProvider data;
8690 session_deps_.socket_factory->AddSocketDataProvider(&data);
8691
8692 TestCompletionCallback callback;
8693 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8694 EXPECT_EQ(ERR_IO_PENDING, rv);
8695 base::MessageLoop::current()->RunUntilIdle();
8696
8697 // Transaction is pending on request body initialization.
8698 ASSERT_FALSE(fake_reader->callback().is_null());
8699
8700 // Return Init()'s result after the transaction gets destroyed.
8701 trans.reset();
8702 fake_reader->callback().Run(OK); // Should not crash.
8703}
8704
[email protected]aeefc9e82010-02-19 16:18:278705// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028706TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278707 HttpRequestInfo request;
8708 request.method = "GET";
bncce36dca22015-04-21 22:11:238709 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:278710 request.load_flags = 0;
8711
8712 // First transaction will request a resource and receive a Basic challenge
8713 // with realm="first_realm".
8714 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238715 MockWrite(
8716 "GET / HTTP/1.1\r\n"
8717 "Host: www.example.org\r\n"
8718 "Connection: keep-alive\r\n"
8719 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278720 };
8721 MockRead data_reads1[] = {
8722 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8723 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8724 "\r\n"),
8725 };
8726
8727 // After calling trans->RestartWithAuth(), provide an Authentication header
8728 // for first_realm. The server will reject and provide a challenge with
8729 // second_realm.
8730 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238731 MockWrite(
8732 "GET / HTTP/1.1\r\n"
8733 "Host: www.example.org\r\n"
8734 "Connection: keep-alive\r\n"
8735 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8736 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278737 };
8738 MockRead data_reads2[] = {
8739 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8740 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8741 "\r\n"),
8742 };
8743
8744 // This again fails, and goes back to first_realm. Make sure that the
8745 // entry is removed from cache.
8746 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238747 MockWrite(
8748 "GET / HTTP/1.1\r\n"
8749 "Host: www.example.org\r\n"
8750 "Connection: keep-alive\r\n"
8751 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8752 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278753 };
8754 MockRead data_reads3[] = {
8755 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8756 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8757 "\r\n"),
8758 };
8759
8760 // Try one last time (with the correct password) and get the resource.
8761 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:238762 MockWrite(
8763 "GET / HTTP/1.1\r\n"
8764 "Host: www.example.org\r\n"
8765 "Connection: keep-alive\r\n"
8766 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8767 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278768 };
8769 MockRead data_reads4[] = {
8770 MockRead("HTTP/1.1 200 OK\r\n"
8771 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508772 "Content-Length: 5\r\n"
8773 "\r\n"
8774 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278775 };
8776
8777 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8778 data_writes1, arraysize(data_writes1));
8779 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8780 data_writes2, arraysize(data_writes2));
8781 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8782 data_writes3, arraysize(data_writes3));
8783 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8784 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078785 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8786 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8787 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8788 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278789
[email protected]49639fa2011-12-20 23:22:418790 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278791
mmenke6b3af6e2015-09-12 02:06:068792 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508793 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418794 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508795
[email protected]aeefc9e82010-02-19 16:18:278796 // Issue the first request with Authorize headers. There should be a
8797 // password prompt for first_realm waiting to be filled in after the
8798 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418799 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278800 EXPECT_EQ(ERR_IO_PENDING, rv);
8801 rv = callback1.WaitForResult();
8802 EXPECT_EQ(OK, rv);
8803 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508804 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048805 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8806 ASSERT_FALSE(challenge == NULL);
8807 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238808 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048809 EXPECT_EQ("first_realm", challenge->realm);
8810 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278811
8812 // Issue the second request with an incorrect password. There should be a
8813 // password prompt for second_realm waiting to be filled in after the
8814 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418815 TestCompletionCallback callback2;
8816 rv = trans->RestartWithAuth(
8817 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278818 EXPECT_EQ(ERR_IO_PENDING, rv);
8819 rv = callback2.WaitForResult();
8820 EXPECT_EQ(OK, rv);
8821 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508822 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048823 challenge = response->auth_challenge.get();
8824 ASSERT_FALSE(challenge == NULL);
8825 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238826 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048827 EXPECT_EQ("second_realm", challenge->realm);
8828 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278829
8830 // Issue the third request with another incorrect password. There should be
8831 // a password prompt for first_realm waiting to be filled in. If the password
8832 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8833 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418834 TestCompletionCallback callback3;
8835 rv = trans->RestartWithAuth(
8836 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278837 EXPECT_EQ(ERR_IO_PENDING, rv);
8838 rv = callback3.WaitForResult();
8839 EXPECT_EQ(OK, rv);
8840 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508841 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048842 challenge = response->auth_challenge.get();
8843 ASSERT_FALSE(challenge == NULL);
8844 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238845 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048846 EXPECT_EQ("first_realm", challenge->realm);
8847 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278848
8849 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418850 TestCompletionCallback callback4;
8851 rv = trans->RestartWithAuth(
8852 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278853 EXPECT_EQ(ERR_IO_PENDING, rv);
8854 rv = callback4.WaitForResult();
8855 EXPECT_EQ(OK, rv);
8856 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508857 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278858 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8859}
8860
bncc958faa2015-07-31 18:14:528861TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
8862 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:358863 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:528864
8865 std::string alternative_service_http_header =
8866 GetAlternativeServiceHttpHeader();
8867
8868 MockRead data_reads[] = {
8869 MockRead("HTTP/1.1 200 OK\r\n"),
8870 MockRead(alternative_service_http_header.c_str()),
8871 MockRead("\r\n"),
8872 MockRead("hello world"),
8873 MockRead(SYNCHRONOUS, OK),
8874 };
8875
8876 HttpRequestInfo request;
8877 request.method = "GET";
8878 request.url = GURL("http://www.example.org/");
8879 request.load_flags = 0;
8880
8881 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8882
8883 session_deps_.socket_factory->AddSocketDataProvider(&data);
8884
8885 TestCompletionCallback callback;
8886
mmenke6b3af6e2015-09-12 02:06:068887 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:528888 scoped_ptr<HttpTransaction> trans(
8889 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8890
8891 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8892 EXPECT_EQ(ERR_IO_PENDING, rv);
8893
8894 HostPortPair http_host_port_pair("www.example.org", 80);
8895 HttpServerProperties& http_server_properties =
8896 *session->http_server_properties();
8897 AlternativeServiceVector alternative_service_vector =
8898 http_server_properties.GetAlternativeServices(http_host_port_pair);
8899 EXPECT_TRUE(alternative_service_vector.empty());
8900
8901 EXPECT_EQ(OK, callback.WaitForResult());
8902
8903 const HttpResponseInfo* response = trans->GetResponseInfo();
8904 ASSERT_TRUE(response != NULL);
8905 ASSERT_TRUE(response->headers.get() != NULL);
8906 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8907 EXPECT_FALSE(response->was_fetched_via_spdy);
8908 EXPECT_FALSE(response->was_npn_negotiated);
8909
8910 std::string response_data;
8911 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8912 EXPECT_EQ("hello world", response_data);
8913
8914 alternative_service_vector =
8915 http_server_properties.GetAlternativeServices(http_host_port_pair);
8916 ASSERT_EQ(1u, alternative_service_vector.size());
8917 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
8918 alternative_service_vector[0].protocol);
8919 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
8920 EXPECT_EQ(443, alternative_service_vector[0].port);
8921}
8922
bnc54ec34b72015-08-26 19:34:568923// Alternative Service headers must be ignored when |use_alternative_services|
8924// is false.
8925TEST_P(HttpNetworkTransactionTest, DoNotHonorAlternativeServiceHeader) {
8926 session_deps_.next_protos = SpdyNextProtos();
8927 session_deps_.use_alternative_services = false;
8928
8929 std::string alternative_service_http_header =
8930 GetAlternativeServiceHttpHeader();
8931
8932 MockRead data_reads[] = {
8933 MockRead("HTTP/1.1 200 OK\r\n"),
8934 MockRead(alternative_service_http_header.c_str()),
8935 MockRead("\r\n"),
8936 MockRead("hello world"),
8937 MockRead(SYNCHRONOUS, OK),
8938 };
8939
8940 HttpRequestInfo request;
8941 request.method = "GET";
8942 request.url = GURL("http://www.example.org/");
8943 request.load_flags = 0;
8944
8945 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
8946
8947 session_deps_.socket_factory->AddSocketDataProvider(&data);
8948
8949 TestCompletionCallback callback;
8950
mmenke6b3af6e2015-09-12 02:06:068951 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc54ec34b72015-08-26 19:34:568952 scoped_ptr<HttpTransaction> trans(
8953 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8954
8955 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8956 EXPECT_EQ(ERR_IO_PENDING, rv);
8957
8958 HostPortPair http_host_port_pair("www.example.org", 80);
8959 HttpServerProperties& http_server_properties =
8960 *session->http_server_properties();
8961 AlternativeServiceVector alternative_service_vector =
8962 http_server_properties.GetAlternativeServices(http_host_port_pair);
8963 EXPECT_TRUE(alternative_service_vector.empty());
8964
8965 EXPECT_EQ(OK, callback.WaitForResult());
8966
8967 const HttpResponseInfo* response = trans->GetResponseInfo();
8968 ASSERT_TRUE(response != nullptr);
8969 ASSERT_TRUE(response->headers.get() != nullptr);
8970 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8971 EXPECT_FALSE(response->was_fetched_via_spdy);
8972 EXPECT_FALSE(response->was_npn_negotiated);
8973
8974 std::string response_data;
8975 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8976 EXPECT_EQ("hello world", response_data);
8977
8978 alternative_service_vector =
8979 http_server_properties.GetAlternativeServices(http_host_port_pair);
8980 EXPECT_TRUE(alternative_service_vector.empty());
8981}
8982
bncc958faa2015-07-31 18:14:528983TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
8984 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:358985 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:528986
8987 MockRead data_reads[] = {
8988 MockRead("HTTP/1.1 200 OK\r\n"),
8989 MockRead("Alt-Svc: "),
8990 MockRead(GetAlternateProtocolFromParam()),
8991 MockRead("=\"www.example.com:443\";p=1.0,"),
8992 MockRead("quic=\":1234\"\r\n\r\n"),
8993 MockRead("hello world"),
8994 MockRead(SYNCHRONOUS, OK),
8995 };
8996
8997 HttpRequestInfo request;
8998 request.method = "GET";
8999 request.url = GURL("http://www.example.org/");
9000 request.load_flags = 0;
9001
9002 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9003
9004 session_deps_.socket_factory->AddSocketDataProvider(&data);
9005
9006 TestCompletionCallback callback;
9007
mmenke6b3af6e2015-09-12 02:06:069008 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529009 scoped_ptr<HttpTransaction> trans(
9010 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9011
9012 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9013 EXPECT_EQ(ERR_IO_PENDING, rv);
9014
9015 HostPortPair http_host_port_pair("www.example.org", 80);
9016 HttpServerProperties& http_server_properties =
9017 *session->http_server_properties();
9018 AlternativeServiceVector alternative_service_vector =
9019 http_server_properties.GetAlternativeServices(http_host_port_pair);
9020 EXPECT_TRUE(alternative_service_vector.empty());
9021
9022 EXPECT_EQ(OK, callback.WaitForResult());
9023
9024 const HttpResponseInfo* response = trans->GetResponseInfo();
9025 ASSERT_TRUE(response != NULL);
9026 ASSERT_TRUE(response->headers.get() != NULL);
9027 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9028 EXPECT_FALSE(response->was_fetched_via_spdy);
9029 EXPECT_FALSE(response->was_npn_negotiated);
9030
9031 std::string response_data;
9032 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9033 EXPECT_EQ("hello world", response_data);
9034
9035 alternative_service_vector =
9036 http_server_properties.GetAlternativeServices(http_host_port_pair);
9037 ASSERT_EQ(2u, alternative_service_vector.size());
9038 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9039 alternative_service_vector[0].protocol);
9040 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9041 EXPECT_EQ(443, alternative_service_vector[0].port);
9042 EXPECT_EQ(QUIC, alternative_service_vector[1].protocol);
9043 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
9044 EXPECT_EQ(1234, alternative_service_vector[1].port);
9045}
9046
bnc54ec34b72015-08-26 19:34:569047// Alternate Protocol headers must be honored even if |use_alternative_services|
9048// is false.
[email protected]23e482282013-06-14 16:08:029049TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:239050 session_deps_.next_protos = SpdyNextProtos();
bnc54ec34b72015-08-26 19:34:569051 session_deps_.use_alternative_services = false;
[email protected]a2cb8122010-03-10 17:22:429052
[email protected]8a0fc822013-06-27 20:52:439053 std::string alternate_protocol_http_header =
9054 GetAlternateProtocolHttpHeader();
9055
[email protected]564b4912010-03-09 16:30:429056 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529057 MockRead("HTTP/1.1 200 OK\r\n"),
9058 MockRead(alternate_protocol_http_header.c_str()),
9059 MockRead("\r\n"),
9060 MockRead("hello world"),
9061 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:429062 };
9063
9064 HttpRequestInfo request;
9065 request.method = "GET";
bncce36dca22015-04-21 22:11:239066 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429067 request.load_flags = 0;
9068
9069 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9070
[email protected]bb88e1d32013-05-03 23:11:079071 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:429072
[email protected]49639fa2011-12-20 23:22:419073 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429074
mmenke6b3af6e2015-09-12 02:06:069075 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369076 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509077 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:429078
[email protected]49639fa2011-12-20 23:22:419079 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429080 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:539081
bncce36dca22015-04-21 22:11:239082 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:559083 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:539084 *session->http_server_properties();
bncd9b132e2015-07-08 05:16:109085 AlternativeServiceVector alternative_service_vector =
9086 http_server_properties.GetAlternativeServices(http_host_port_pair);
9087 EXPECT_TRUE(alternative_service_vector.empty());
[email protected]564b4912010-03-09 16:30:429088
9089 EXPECT_EQ(OK, callback.WaitForResult());
9090
9091 const HttpResponseInfo* response = trans->GetResponseInfo();
9092 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509093 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429094 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539095 EXPECT_FALSE(response->was_fetched_via_spdy);
9096 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:429097
9098 std::string response_data;
9099 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9100 EXPECT_EQ("hello world", response_data);
9101
bncd9b132e2015-07-08 05:16:109102 alternative_service_vector =
9103 http_server_properties.GetAlternativeServices(http_host_port_pair);
9104 ASSERT_EQ(1u, alternative_service_vector.size());
9105 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc181b39a2015-03-17 21:36:479106 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
bncd9b132e2015-07-08 05:16:109107 alternative_service_vector[0].protocol);
[email protected]564b4912010-03-09 16:30:429108}
9109
rch89c6e102015-03-18 18:56:529110TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
9111 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359112 session_deps_.use_alternative_services = true;
rch89c6e102015-03-18 18:56:529113
9114 MockRead data_reads[] = {
9115 MockRead("HTTP/1.1 200 OK\r\n"),
9116 MockRead("Alternate-Protocol: \r\n\r\n"),
9117 MockRead("hello world"),
9118 MockRead(SYNCHRONOUS, OK),
9119 };
9120
9121 HttpRequestInfo request;
9122 request.method = "GET";
bncce36dca22015-04-21 22:11:239123 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:529124 request.load_flags = 0;
9125
9126 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9127
9128 session_deps_.socket_factory->AddSocketDataProvider(&data);
9129
9130 TestCompletionCallback callback;
9131
mmenke6b3af6e2015-09-12 02:06:069132 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rch89c6e102015-03-18 18:56:529133
bncce36dca22015-04-21 22:11:239134 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:529135 HttpServerProperties& http_server_properties =
9136 *session->http_server_properties();
bnccacc0992015-03-20 20:22:229137 AlternativeService alternative_service(QUIC, "", 80);
bnc7dc7e1b42015-07-28 14:43:129138 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9139 http_server_properties.SetAlternativeService(
9140 http_host_port_pair, alternative_service, 1.0, expiration);
bnccacc0992015-03-20 20:22:229141
bncd9b132e2015-07-08 05:16:109142 AlternativeServiceVector alternative_service_vector =
9143 http_server_properties.GetAlternativeServices(http_host_port_pair);
9144 ASSERT_EQ(1u, alternative_service_vector.size());
9145 EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
rch89c6e102015-03-18 18:56:529146
9147 scoped_ptr<HttpTransaction> trans(
9148 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9149
9150 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9151 EXPECT_EQ(ERR_IO_PENDING, rv);
9152
9153 EXPECT_EQ(OK, callback.WaitForResult());
9154
9155 const HttpResponseInfo* response = trans->GetResponseInfo();
9156 ASSERT_TRUE(response != NULL);
9157 ASSERT_TRUE(response->headers.get() != NULL);
9158 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9159 EXPECT_FALSE(response->was_fetched_via_spdy);
9160 EXPECT_FALSE(response->was_npn_negotiated);
9161
9162 std::string response_data;
9163 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9164 EXPECT_EQ("hello world", response_data);
9165
bncd9b132e2015-07-08 05:16:109166 alternative_service_vector =
9167 http_server_properties.GetAlternativeServices(http_host_port_pair);
9168 EXPECT_TRUE(alternative_service_vector.empty());
rch89c6e102015-03-18 18:56:529169}
9170
bncc958faa2015-07-31 18:14:529171TEST_P(HttpNetworkTransactionTest, AltSvcOverwritesAlternateProtocol) {
9172 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359173 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529174
9175 std::string alternative_service_http_header =
9176 GetAlternativeServiceHttpHeader();
9177 std::string alternate_protocol_http_header = GetAlternateProtocolHttpHeader();
9178
9179 MockRead data_reads[] = {
9180 MockRead("HTTP/1.1 200 OK\r\n"),
9181 MockRead(alternative_service_http_header.c_str()),
9182 MockRead(alternate_protocol_http_header.c_str()),
9183 MockRead("\r\n"),
9184 MockRead("hello world"),
9185 MockRead(SYNCHRONOUS, OK),
9186 };
9187
9188 HttpRequestInfo request;
9189 request.method = "GET";
9190 request.url = GURL("http://www.example.org/");
9191 request.load_flags = 0;
9192
9193 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9194
9195 session_deps_.socket_factory->AddSocketDataProvider(&data);
9196
9197 TestCompletionCallback callback;
9198
mmenke6b3af6e2015-09-12 02:06:069199 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529200 scoped_ptr<HttpTransaction> trans(
9201 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9202
9203 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9204 EXPECT_EQ(ERR_IO_PENDING, rv);
9205
9206 HostPortPair http_host_port_pair("www.example.org", 80);
9207 HttpServerProperties& http_server_properties =
9208 *session->http_server_properties();
9209 AlternativeServiceVector alternative_service_vector =
9210 http_server_properties.GetAlternativeServices(http_host_port_pair);
9211 EXPECT_TRUE(alternative_service_vector.empty());
9212
9213 EXPECT_EQ(OK, callback.WaitForResult());
9214
9215 const HttpResponseInfo* response = trans->GetResponseInfo();
9216 ASSERT_TRUE(response != NULL);
9217 ASSERT_TRUE(response->headers.get() != NULL);
9218 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9219 EXPECT_FALSE(response->was_fetched_via_spdy);
9220 EXPECT_FALSE(response->was_npn_negotiated);
9221
9222 std::string response_data;
9223 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9224 EXPECT_EQ("hello world", response_data);
9225
9226 alternative_service_vector =
9227 http_server_properties.GetAlternativeServices(http_host_port_pair);
9228 ASSERT_EQ(1u, alternative_service_vector.size());
9229 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9230 alternative_service_vector[0].protocol);
9231 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9232 EXPECT_EQ(443, alternative_service_vector[0].port);
9233}
9234
bnc54ec34b72015-08-26 19:34:569235// When |use_alternative_services| is false, do not observe alternative service
9236// entries that point to a different host.
9237TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
9238 session_deps_.use_alternative_services = false;
9239
9240 HttpRequestInfo request;
9241 request.method = "GET";
9242 request.url = GURL("http://www.example.org/");
9243 request.load_flags = 0;
9244
9245 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9246 StaticSocketDataProvider first_data;
9247 first_data.set_connect_data(mock_connect);
9248 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
9249
9250 MockRead data_reads[] = {
9251 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
9252 MockRead(ASYNC, OK),
9253 };
9254 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
9255 nullptr, 0);
9256 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
9257
mmenke6b3af6e2015-09-12 02:06:069258 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc54ec34b72015-08-26 19:34:569259
9260 base::WeakPtr<HttpServerProperties> http_server_properties =
9261 session->http_server_properties();
9262 AlternativeService alternative_service(
9263 AlternateProtocolFromNextProto(GetParam()), "different.example.org", 80);
9264 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9265 http_server_properties->SetAlternativeService(
9266 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
9267
9268 scoped_ptr<HttpTransaction> trans(
9269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9270 TestCompletionCallback callback;
9271
9272 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9273 // The connetion to origin was refused, and the alternative service should not
9274 // be used (even though mock data are there), therefore the request should
9275 // fail.
9276 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
9277}
9278
[email protected]23e482282013-06-14 16:08:029279TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239280 MarkBrokenAlternateProtocolAndFallback) {
bnc55ff9da2015-08-19 18:42:359281 session_deps_.use_alternative_services = true;
[email protected]564b4912010-03-09 16:30:429282
9283 HttpRequestInfo request;
9284 request.method = "GET";
bncce36dca22015-04-21 22:11:239285 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429286 request.load_flags = 0;
9287
[email protected]d973e99a2012-02-17 21:02:369288 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:429289 StaticSocketDataProvider first_data;
9290 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079291 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:429292
9293 MockRead data_reads[] = {
9294 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9295 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069296 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:429297 };
9298 StaticSocketDataProvider second_data(
9299 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079300 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:429301
mmenke6b3af6e2015-09-12 02:06:069302 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:429303
[email protected]30d4c022013-07-18 22:58:169304 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539305 session->http_server_properties();
bnc8445b3002015-03-13 01:57:099306 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:119307 // Port must be < 1024, or the header will be ignored (since initial port was
9308 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:109309 const AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239310 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bncd9b132e2015-07-08 05:16:109311 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:129312 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9313 http_server_properties->SetAlternativeService(
9314 host_port_pair, alternative_service, 1.0, expiration);
[email protected]564b4912010-03-09 16:30:429315
[email protected]262eec82013-03-19 21:01:369316 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509317 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419318 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429319
[email protected]49639fa2011-12-20 23:22:419320 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429321 EXPECT_EQ(ERR_IO_PENDING, rv);
9322 EXPECT_EQ(OK, callback.WaitForResult());
9323
9324 const HttpResponseInfo* response = trans->GetResponseInfo();
9325 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509326 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429327 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9328
9329 std::string response_data;
9330 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9331 EXPECT_EQ("hello world", response_data);
9332
bncd9b132e2015-07-08 05:16:109333 const AlternativeServiceVector alternative_service_vector =
9334 http_server_properties->GetAlternativeServices(host_port_pair);
9335 ASSERT_EQ(1u, alternative_service_vector.size());
9336 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
9337 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
9338 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:429339}
9340
bnc55ff9da2015-08-19 18:42:359341// Ensure that we are not allowed to redirect traffic via an alternate protocol
9342// to an unrestricted (port >= 1024) when the original traffic was on a
9343// restricted port (port < 1024). Ensure that we can redirect in all other
9344// cases.
[email protected]23e482282013-06-14 16:08:029345TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239346 AlternateProtocolPortRestrictedBlocked) {
bnc55ff9da2015-08-19 18:42:359347 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119348
9349 HttpRequestInfo restricted_port_request;
9350 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239351 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119352 restricted_port_request.load_flags = 0;
9353
[email protected]d973e99a2012-02-17 21:02:369354 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119355 StaticSocketDataProvider first_data;
9356 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079357 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119358
9359 MockRead data_reads[] = {
9360 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9361 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069362 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119363 };
9364 StaticSocketDataProvider second_data(
9365 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079366 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119367
mmenke6b3af6e2015-09-12 02:06:069368 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119369
[email protected]30d4c022013-07-18 22:58:169370 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539371 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119372 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229373 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239374 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229375 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129376 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229377 http_server_properties->SetAlternativeService(
9378 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129379 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119380
[email protected]262eec82013-03-19 21:01:369381 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509382 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419383 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119384
[email protected]49639fa2011-12-20 23:22:419385 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369386 &restricted_port_request,
9387 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119388 EXPECT_EQ(ERR_IO_PENDING, rv);
9389 // Invalid change to unrestricted port should fail.
9390 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:199391}
[email protected]3912662a32011-10-04 00:51:119392
bnc55ff9da2015-08-19 18:42:359393// Ensure that we are allowed to redirect traffic via an alternate protocol to
9394// an unrestricted (port >= 1024) when the original traffic was on a restricted
9395// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:029396TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:199397 AlternateProtocolPortRestrictedPermitted) {
bnc55ff9da2015-08-19 18:42:359398 session_deps_.use_alternative_services = true;
[email protected]bb88e1d32013-05-03 23:11:079399 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:199400
9401 HttpRequestInfo restricted_port_request;
9402 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239403 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:199404 restricted_port_request.load_flags = 0;
9405
9406 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9407 StaticSocketDataProvider first_data;
9408 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079409 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:199410
9411 MockRead data_reads[] = {
9412 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9413 MockRead("hello world"),
9414 MockRead(ASYNC, OK),
9415 };
9416 StaticSocketDataProvider second_data(
9417 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079418 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:199419
mmenke6b3af6e2015-09-12 02:06:069420 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:199421
[email protected]30d4c022013-07-18 22:58:169422 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:199423 session->http_server_properties();
9424 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229425 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239426 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229427 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129428 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229429 http_server_properties->SetAlternativeService(
9430 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129431 1.0, expiration);
[email protected]c54c6962013-02-01 04:53:199432
[email protected]262eec82013-03-19 21:01:369433 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509434 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:199435 TestCompletionCallback callback;
9436
9437 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:369438 &restricted_port_request,
9439 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:199440 // Change to unrestricted port should succeed.
9441 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119442}
9443
bnc55ff9da2015-08-19 18:42:359444// Ensure that we are not allowed to redirect traffic via an alternate protocol
9445// to an unrestricted (port >= 1024) when the original traffic was on a
9446// restricted port (port < 1024). Ensure that we can redirect in all other
9447// cases.
[email protected]23e482282013-06-14 16:08:029448TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239449 AlternateProtocolPortRestrictedAllowed) {
bnc55ff9da2015-08-19 18:42:359450 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119451
9452 HttpRequestInfo restricted_port_request;
9453 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239454 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119455 restricted_port_request.load_flags = 0;
9456
[email protected]d973e99a2012-02-17 21:02:369457 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119458 StaticSocketDataProvider first_data;
9459 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079460 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119461
9462 MockRead data_reads[] = {
9463 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9464 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069465 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119466 };
9467 StaticSocketDataProvider second_data(
9468 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079469 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119470
mmenke6b3af6e2015-09-12 02:06:069471 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119472
[email protected]30d4c022013-07-18 22:58:169473 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539474 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119475 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229476 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239477 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229478 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129479 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229480 http_server_properties->SetAlternativeService(
9481 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129482 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119483
[email protected]262eec82013-03-19 21:01:369484 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509485 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419486 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119487
[email protected]49639fa2011-12-20 23:22:419488 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369489 &restricted_port_request,
9490 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119491 EXPECT_EQ(ERR_IO_PENDING, rv);
9492 // Valid change to restricted port should pass.
9493 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119494}
9495
bnc55ff9da2015-08-19 18:42:359496// Ensure that we are not allowed to redirect traffic via an alternate protocol
9497// to an unrestricted (port >= 1024) when the original traffic was on a
9498// restricted port (port < 1024). Ensure that we can redirect in all other
9499// cases.
[email protected]23e482282013-06-14 16:08:029500TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239501 AlternateProtocolPortUnrestrictedAllowed1) {
bnc55ff9da2015-08-19 18:42:359502 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119503
9504 HttpRequestInfo unrestricted_port_request;
9505 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239506 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119507 unrestricted_port_request.load_flags = 0;
9508
[email protected]d973e99a2012-02-17 21:02:369509 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119510 StaticSocketDataProvider first_data;
9511 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079512 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119513
9514 MockRead data_reads[] = {
9515 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9516 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069517 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119518 };
9519 StaticSocketDataProvider second_data(
9520 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079521 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119522
mmenke6b3af6e2015-09-12 02:06:069523 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119524
[email protected]30d4c022013-07-18 22:58:169525 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539526 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119527 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229528 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239529 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229530 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129531 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229532 http_server_properties->SetAlternativeService(
9533 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129534 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119535
[email protected]262eec82013-03-19 21:01:369536 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509537 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419538 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119539
[email protected]49639fa2011-12-20 23:22:419540 int rv = trans->Start(
9541 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119542 EXPECT_EQ(ERR_IO_PENDING, rv);
9543 // Valid change to restricted port should pass.
9544 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119545}
9546
bnc55ff9da2015-08-19 18:42:359547// Ensure that we are not allowed to redirect traffic via an alternate protocol
9548// to an unrestricted (port >= 1024) when the original traffic was on a
9549// restricted port (port < 1024). Ensure that we can redirect in all other
9550// cases.
[email protected]23e482282013-06-14 16:08:029551TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239552 AlternateProtocolPortUnrestrictedAllowed2) {
bnc55ff9da2015-08-19 18:42:359553 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119554
9555 HttpRequestInfo unrestricted_port_request;
9556 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239557 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119558 unrestricted_port_request.load_flags = 0;
9559
[email protected]d973e99a2012-02-17 21:02:369560 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119561 StaticSocketDataProvider first_data;
9562 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079563 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119564
9565 MockRead data_reads[] = {
9566 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9567 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069568 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119569 };
9570 StaticSocketDataProvider second_data(
9571 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079572 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119573
mmenke6b3af6e2015-09-12 02:06:069574 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119575
[email protected]30d4c022013-07-18 22:58:169576 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539577 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:229578 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:229579 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239580 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229581 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129582 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229583 http_server_properties->SetAlternativeService(
9584 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129585 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119586
[email protected]262eec82013-03-19 21:01:369587 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509588 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419589 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119590
[email protected]49639fa2011-12-20 23:22:419591 int rv = trans->Start(
9592 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119593 EXPECT_EQ(ERR_IO_PENDING, rv);
9594 // Valid change to an unrestricted port should pass.
9595 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119596}
9597
bnc55ff9da2015-08-19 18:42:359598// Ensure that we are not allowed to redirect traffic via an alternate protocol
9599// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
9600// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239601TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bnc55ff9da2015-08-19 18:42:359602 session_deps_.use_alternative_services = true;
[email protected]eb6234e2012-01-19 01:50:029603
9604 HttpRequestInfo request;
9605 request.method = "GET";
bncce36dca22015-04-21 22:11:239606 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:029607 request.load_flags = 0;
9608
9609 // The alternate protocol request will error out before we attempt to connect,
9610 // so only the standard HTTP request will try to connect.
9611 MockRead data_reads[] = {
9612 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9613 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069614 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029615 };
9616 StaticSocketDataProvider data(
9617 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079618 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029619
mmenke6b3af6e2015-09-12 02:06:069620 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029621
[email protected]30d4c022013-07-18 22:58:169622 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029623 session->http_server_properties();
9624 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:229625 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239626 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229627 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:129628 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229629 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:129630 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
[email protected]eb6234e2012-01-19 01:50:029631
[email protected]262eec82013-03-19 21:01:369632 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509633 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029634 TestCompletionCallback callback;
9635
9636 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9637 EXPECT_EQ(ERR_IO_PENDING, rv);
9638 // The HTTP request should succeed.
9639 EXPECT_EQ(OK, callback.WaitForResult());
9640
[email protected]eb6234e2012-01-19 01:50:029641 const HttpResponseInfo* response = trans->GetResponseInfo();
9642 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509643 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029644 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9645
9646 std::string response_data;
9647 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9648 EXPECT_EQ("hello world", response_data);
9649}
9650
[email protected]23e482282013-06-14 16:08:029651TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359652 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239653 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549654
9655 HttpRequestInfo request;
9656 request.method = "GET";
bncce36dca22015-04-21 22:11:239657 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549658 request.load_flags = 0;
9659
[email protected]8a0fc822013-06-27 20:52:439660 std::string alternate_protocol_http_header =
9661 GetAlternateProtocolHttpHeader();
9662
[email protected]2ff8b312010-04-26 22:20:549663 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529664 MockRead("HTTP/1.1 200 OK\r\n"),
9665 MockRead(alternate_protocol_http_header.c_str()),
9666 MockRead("\r\n"),
9667 MockRead("hello world"),
9668 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9669 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:549670
9671 StaticSocketDataProvider first_transaction(
9672 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079673 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549674
[email protected]8ddf8322012-02-23 18:08:069675 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029676 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239677 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9678 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079679 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549680
[email protected]cdf8f7e72013-05-23 10:56:469681 scoped_ptr<SpdyFrame> req(
9682 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139683 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549684
[email protected]23e482282013-06-14 16:08:029685 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9686 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549687 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139688 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549689 };
9690
rch8e6c6c42015-05-01 14:05:139691 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9692 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079693 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549694
[email protected]d973e99a2012-02-17 21:02:369695 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559696 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9697 NULL, 0, NULL, 0);
9698 hanging_non_alternate_protocol_socket.set_connect_data(
9699 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079700 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559701 &hanging_non_alternate_protocol_socket);
9702
[email protected]49639fa2011-12-20 23:22:419703 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549704
mmenke6b3af6e2015-09-12 02:06:069705 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369706 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509707 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549708
[email protected]49639fa2011-12-20 23:22:419709 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549710 EXPECT_EQ(ERR_IO_PENDING, rv);
9711 EXPECT_EQ(OK, callback.WaitForResult());
9712
9713 const HttpResponseInfo* response = trans->GetResponseInfo();
9714 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509715 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549716 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9717
9718 std::string response_data;
9719 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9720 EXPECT_EQ("hello world", response_data);
9721
[email protected]90499482013-06-01 00:39:509722 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549723
[email protected]49639fa2011-12-20 23:22:419724 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549725 EXPECT_EQ(ERR_IO_PENDING, rv);
9726 EXPECT_EQ(OK, callback.WaitForResult());
9727
9728 response = trans->GetResponseInfo();
9729 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509730 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549731 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539732 EXPECT_TRUE(response->was_fetched_via_spdy);
9733 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549734
9735 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9736 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549737}
9738
[email protected]23e482282013-06-14 16:08:029739TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
bnc55ff9da2015-08-19 18:42:359740 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239741 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559742
9743 HttpRequestInfo request;
9744 request.method = "GET";
bncce36dca22015-04-21 22:11:239745 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559746 request.load_flags = 0;
9747
[email protected]8a0fc822013-06-27 20:52:439748 std::string alternate_protocol_http_header =
9749 GetAlternateProtocolHttpHeader();
9750
[email protected]2d6728692011-03-12 01:39:559751 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529752 MockRead("HTTP/1.1 200 OK\r\n"),
9753 MockRead(alternate_protocol_http_header.c_str()),
9754 MockRead("\r\n"),
9755 MockRead("hello world"),
9756 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9757 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559758 };
9759
9760 StaticSocketDataProvider first_transaction(
9761 data_reads, arraysize(data_reads), NULL, 0);
9762 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079763 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559764
[email protected]d973e99a2012-02-17 21:02:369765 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559766 StaticSocketDataProvider hanging_socket(
9767 NULL, 0, NULL, 0);
9768 hanging_socket.set_connect_data(never_finishing_connect);
9769 // Socket 2 and 3 are the hanging Alternate-Protocol and
9770 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079771 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9772 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559773
[email protected]8ddf8322012-02-23 18:08:069774 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029775 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239776 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9777 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079778 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559779
[email protected]cdf8f7e72013-05-23 10:56:469780 scoped_ptr<SpdyFrame> req1(
9781 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9782 scoped_ptr<SpdyFrame> req2(
9783 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559784 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139785 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:559786 };
[email protected]23e482282013-06-14 16:08:029787 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9788 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9789 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9790 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559791 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139792 CreateMockRead(*resp1, 2),
9793 CreateMockRead(*data1, 3),
9794 CreateMockRead(*resp2, 4),
9795 CreateMockRead(*data2, 5),
9796 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:559797 };
9798
rch8e6c6c42015-05-01 14:05:139799 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9800 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559801 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079802 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559803
9804 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079805 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559806
mmenke6b3af6e2015-09-12 02:06:069807 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419808 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509809 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559810
[email protected]49639fa2011-12-20 23:22:419811 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559812 EXPECT_EQ(ERR_IO_PENDING, rv);
9813 EXPECT_EQ(OK, callback1.WaitForResult());
9814
9815 const HttpResponseInfo* response = trans1.GetResponseInfo();
9816 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509817 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559818 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9819
9820 std::string response_data;
9821 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9822 EXPECT_EQ("hello world", response_data);
9823
[email protected]49639fa2011-12-20 23:22:419824 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509825 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419826 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559827 EXPECT_EQ(ERR_IO_PENDING, rv);
9828
[email protected]49639fa2011-12-20 23:22:419829 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509830 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419831 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559832 EXPECT_EQ(ERR_IO_PENDING, rv);
9833
9834 EXPECT_EQ(OK, callback2.WaitForResult());
9835 EXPECT_EQ(OK, callback3.WaitForResult());
9836
9837 response = trans2.GetResponseInfo();
9838 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509839 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559840 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9841 EXPECT_TRUE(response->was_fetched_via_spdy);
9842 EXPECT_TRUE(response->was_npn_negotiated);
9843 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9844 EXPECT_EQ("hello!", response_data);
9845
9846 response = trans3.GetResponseInfo();
9847 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509848 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559849 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9850 EXPECT_TRUE(response->was_fetched_via_spdy);
9851 EXPECT_TRUE(response->was_npn_negotiated);
9852 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9853 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559854}
9855
[email protected]23e482282013-06-14 16:08:029856TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359857 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239858 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559859
9860 HttpRequestInfo request;
9861 request.method = "GET";
bncce36dca22015-04-21 22:11:239862 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559863 request.load_flags = 0;
9864
[email protected]8a0fc822013-06-27 20:52:439865 std::string alternate_protocol_http_header =
9866 GetAlternateProtocolHttpHeader();
9867
[email protected]2d6728692011-03-12 01:39:559868 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529869 MockRead("HTTP/1.1 200 OK\r\n"),
9870 MockRead(alternate_protocol_http_header.c_str()),
9871 MockRead("\r\n"),
9872 MockRead("hello world"),
9873 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9874 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559875 };
9876
9877 StaticSocketDataProvider first_transaction(
9878 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079879 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559880
[email protected]8ddf8322012-02-23 18:08:069881 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029882 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079883 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559884
[email protected]d973e99a2012-02-17 21:02:369885 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559886 StaticSocketDataProvider hanging_alternate_protocol_socket(
9887 NULL, 0, NULL, 0);
9888 hanging_alternate_protocol_socket.set_connect_data(
9889 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079890 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559891 &hanging_alternate_protocol_socket);
9892
9893 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079894 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559895
[email protected]49639fa2011-12-20 23:22:419896 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559897
mmenke6b3af6e2015-09-12 02:06:069898 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369899 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509900 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559901
[email protected]49639fa2011-12-20 23:22:419902 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559903 EXPECT_EQ(ERR_IO_PENDING, rv);
9904 EXPECT_EQ(OK, callback.WaitForResult());
9905
9906 const HttpResponseInfo* response = trans->GetResponseInfo();
9907 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509908 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559909 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9910
9911 std::string response_data;
9912 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9913 EXPECT_EQ("hello world", response_data);
9914
[email protected]90499482013-06-01 00:39:509915 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559916
[email protected]49639fa2011-12-20 23:22:419917 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559918 EXPECT_EQ(ERR_IO_PENDING, rv);
9919 EXPECT_EQ(OK, callback.WaitForResult());
9920
9921 response = trans->GetResponseInfo();
9922 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509923 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559924 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9925 EXPECT_FALSE(response->was_fetched_via_spdy);
9926 EXPECT_FALSE(response->was_npn_negotiated);
9927
9928 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9929 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559930}
9931
[email protected]631f1322010-04-30 17:59:119932class CapturingProxyResolver : public ProxyResolver {
9933 public:
sammce90c9212015-05-27 23:43:359934 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:209935 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119936
dchengb03027d2014-10-21 12:00:209937 int GetProxyForURL(const GURL& url,
9938 ProxyInfo* results,
9939 const CompletionCallback& callback,
9940 RequestHandle* request,
9941 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409942 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9943 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429944 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119945 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429946 return OK;
[email protected]631f1322010-04-30 17:59:119947 }
9948
dchengb03027d2014-10-21 12:00:209949 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119950
dchengb03027d2014-10-21 12:00:209951 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179952 NOTREACHED();
9953 return LOAD_STATE_IDLE;
9954 }
9955
[email protected]24476402010-07-20 20:55:179956 const std::vector<GURL>& resolved() const { return resolved_; }
9957
9958 private:
[email protected]631f1322010-04-30 17:59:119959 std::vector<GURL> resolved_;
9960
9961 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9962};
9963
sammce64b2362015-04-29 03:50:239964class CapturingProxyResolverFactory : public ProxyResolverFactory {
9965 public:
9966 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
9967 : ProxyResolverFactory(false), resolver_(resolver) {}
9968
9969 int CreateProxyResolver(
9970 const scoped_refptr<ProxyResolverScriptData>& pac_script,
9971 scoped_ptr<ProxyResolver>* resolver,
9972 const net::CompletionCallback& callback,
9973 scoped_ptr<Request>* request) override {
9974 resolver->reset(new ForwardingProxyResolver(resolver_));
9975 return OK;
9976 }
9977
9978 private:
9979 ProxyResolver* resolver_;
9980};
9981
[email protected]23e482282013-06-14 16:08:029982TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239983 UseAlternateProtocolForTunneledNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359984 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239985 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119986
9987 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429988 proxy_config.set_auto_detect(true);
9989 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119990
sammc5dd160c2015-04-02 02:43:139991 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:079992 session_deps_.proxy_service.reset(new ProxyService(
csharrisonb7e3a082015-09-22 19:13:049993 make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)),
sammc5dd160c2015-04-02 02:43:139994 make_scoped_ptr(
sammce64b2362015-04-29 03:50:239995 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:389996 NULL));
vishal.b62985ca92015-04-17 08:45:519997 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079998 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119999
10000 HttpRequestInfo request;
10001 request.method = "GET";
bncce36dca22015-04-21 22:11:2310002 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:1110003 request.load_flags = 0;
10004
[email protected]8a0fc822013-06-27 20:52:4310005 std::string alternate_protocol_http_header =
10006 GetAlternateProtocolHttpHeader();
10007
[email protected]631f1322010-04-30 17:59:1110008 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210009 MockRead("HTTP/1.1 200 OK\r\n"),
10010 MockRead(alternate_protocol_http_header.c_str()),
10011 MockRead("\r\n"),
10012 MockRead("hello world"),
10013 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10014 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1110015 };
10016
10017 StaticSocketDataProvider first_transaction(
10018 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710019 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:1110020
[email protected]8ddf8322012-02-23 18:08:0610021 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210022 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310023 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10024 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710025 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:1110026
[email protected]cdf8f7e72013-05-23 10:56:4610027 scoped_ptr<SpdyFrame> req(
10028 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:1110029 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310030 MockWrite(ASYNC, 0,
10031 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10032 "Host: www.example.org\r\n"
10033 "Proxy-Connection: keep-alive\r\n\r\n"),
10034 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:1110035 };
10036
[email protected]d911f1b2010-05-05 22:39:4210037 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10038
[email protected]23e482282013-06-14 16:08:0210039 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10040 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1110041 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310042 MockRead(ASYNC, 1, kCONNECTResponse),
10043 CreateMockRead(*resp.get(), 3),
10044 CreateMockRead(*data.get(), 4),
10045 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1110046 };
10047
rch8e6c6c42015-05-01 14:05:1310048 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10049 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710050 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1110051
[email protected]d973e99a2012-02-17 21:02:3610052 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510053 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10054 NULL, 0, NULL, 0);
10055 hanging_non_alternate_protocol_socket.set_connect_data(
10056 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710057 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510058 &hanging_non_alternate_protocol_socket);
10059
[email protected]49639fa2011-12-20 23:22:4110060 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1110061
mmenke6b3af6e2015-09-12 02:06:0610062 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610063 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010064 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110065
[email protected]49639fa2011-12-20 23:22:4110066 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110067 EXPECT_EQ(ERR_IO_PENDING, rv);
10068 EXPECT_EQ(OK, callback.WaitForResult());
10069
10070 const HttpResponseInfo* response = trans->GetResponseInfo();
10071 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010072 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110073 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310074 EXPECT_FALSE(response->was_fetched_via_spdy);
10075 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110076
10077 std::string response_data;
10078 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10079 EXPECT_EQ("hello world", response_data);
10080
[email protected]90499482013-06-01 00:39:5010081 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110082
[email protected]49639fa2011-12-20 23:22:4110083 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110084 EXPECT_EQ(ERR_IO_PENDING, rv);
10085 EXPECT_EQ(OK, callback.WaitForResult());
10086
10087 response = trans->GetResponseInfo();
10088 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010089 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110090 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310091 EXPECT_TRUE(response->was_fetched_via_spdy);
10092 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110093
10094 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10095 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1310096 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2310097 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310098 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2310099 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310100 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1110101
[email protected]029c83b62013-01-24 05:28:2010102 LoadTimingInfo load_timing_info;
10103 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10104 TestLoadTimingNotReusedWithPac(load_timing_info,
10105 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1110106}
[email protected]631f1322010-04-30 17:59:1110107
[email protected]23e482282013-06-14 16:08:0210108TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:5410109 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
bnc55ff9da2015-08-19 18:42:3510110 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310111 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:5410112
10113 HttpRequestInfo request;
10114 request.method = "GET";
bncce36dca22015-04-21 22:11:2310115 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410116 request.load_flags = 0;
10117
[email protected]8a0fc822013-06-27 20:52:4310118 std::string alternate_protocol_http_header =
10119 GetAlternateProtocolHttpHeader();
10120
[email protected]2ff8b312010-04-26 22:20:5410121 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210122 MockRead("HTTP/1.1 200 OK\r\n"),
10123 MockRead(alternate_protocol_http_header.c_str()),
10124 MockRead("\r\n"),
10125 MockRead("hello world"),
10126 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5410127 };
10128
10129 StaticSocketDataProvider first_transaction(
10130 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710131 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410132
[email protected]8ddf8322012-02-23 18:08:0610133 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210134 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310135 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10136 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710137 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410138
[email protected]cdf8f7e72013-05-23 10:56:4610139 scoped_ptr<SpdyFrame> req(
10140 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310141 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410142
[email protected]23e482282013-06-14 16:08:0210143 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10144 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410145 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310146 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410147 };
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]2ff8b312010-04-26 22:20:5410152
[email protected]83039bb2011-12-09 18:43:5510153 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410154
mmenke6b3af6e2015-09-12 02:06:0610155 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5410156
[email protected]262eec82013-03-19 21:01:3610157 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010158 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410159
[email protected]49639fa2011-12-20 23:22:4110160 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410161 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110162 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410163
10164 const HttpResponseInfo* response = trans->GetResponseInfo();
10165 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010166 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410167 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10168
10169 std::string response_data;
10170 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10171 EXPECT_EQ("hello world", response_data);
10172
10173 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310174 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010175 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310176 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710177 base::WeakPtr<SpdySession> spdy_session =
mmenke6b3af6e2015-09-12 02:06:0610178 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3810179
[email protected]90499482013-06-01 00:39:5010180 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410181
[email protected]49639fa2011-12-20 23:22:4110182 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410183 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110184 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410185
10186 response = trans->GetResponseInfo();
10187 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010188 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410189 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310190 EXPECT_TRUE(response->was_fetched_via_spdy);
10191 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410192
10193 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10194 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4210195}
10196
[email protected]044de0642010-06-17 10:42:1510197// GenerateAuthToken is a mighty big test.
10198// It tests all permutation of GenerateAuthToken behavior:
10199// - Synchronous and Asynchronous completion.
10200// - OK or error on completion.
10201// - Direct connection, non-authenticating proxy, and authenticating proxy.
10202// - HTTP or HTTPS backend (to include proxy tunneling).
10203// - Non-authenticating and authenticating backend.
10204//
[email protected]fe3b7dc2012-02-03 19:52:0910205// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1510206// problems generating an auth token for an authenticating proxy, we don't
10207// need to test all permutations of the backend server).
10208//
10209// The test proceeds by going over each of the configuration cases, and
10210// potentially running up to three rounds in each of the tests. The TestConfig
10211// specifies both the configuration for the test as well as the expectations
10212// for the results.
[email protected]23e482282013-06-14 16:08:0210213TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5010214 static const char kServer[] = "http://www.example.com";
10215 static const char kSecureServer[] = "https://www.example.com";
10216 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1510217 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
10218
10219 enum AuthTiming {
10220 AUTH_NONE,
10221 AUTH_SYNC,
10222 AUTH_ASYNC,
10223 };
10224
10225 const MockWrite kGet(
10226 "GET / HTTP/1.1\r\n"
10227 "Host: www.example.com\r\n"
10228 "Connection: keep-alive\r\n\r\n");
10229 const MockWrite kGetProxy(
10230 "GET http://www.example.com/ HTTP/1.1\r\n"
10231 "Host: www.example.com\r\n"
10232 "Proxy-Connection: keep-alive\r\n\r\n");
10233 const MockWrite kGetAuth(
10234 "GET / HTTP/1.1\r\n"
10235 "Host: www.example.com\r\n"
10236 "Connection: keep-alive\r\n"
10237 "Authorization: auth_token\r\n\r\n");
10238 const MockWrite kGetProxyAuth(
10239 "GET http://www.example.com/ HTTP/1.1\r\n"
10240 "Host: www.example.com\r\n"
10241 "Proxy-Connection: keep-alive\r\n"
10242 "Proxy-Authorization: auth_token\r\n\r\n");
10243 const MockWrite kGetAuthThroughProxy(
10244 "GET http://www.example.com/ HTTP/1.1\r\n"
10245 "Host: www.example.com\r\n"
10246 "Proxy-Connection: keep-alive\r\n"
10247 "Authorization: auth_token\r\n\r\n");
10248 const MockWrite kGetAuthWithProxyAuth(
10249 "GET http://www.example.com/ HTTP/1.1\r\n"
10250 "Host: www.example.com\r\n"
10251 "Proxy-Connection: keep-alive\r\n"
10252 "Proxy-Authorization: auth_token\r\n"
10253 "Authorization: auth_token\r\n\r\n");
10254 const MockWrite kConnect(
10255 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10256 "Host: www.example.com\r\n"
10257 "Proxy-Connection: keep-alive\r\n\r\n");
10258 const MockWrite kConnectProxyAuth(
10259 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10260 "Host: www.example.com\r\n"
10261 "Proxy-Connection: keep-alive\r\n"
10262 "Proxy-Authorization: auth_token\r\n\r\n");
10263
10264 const MockRead kSuccess(
10265 "HTTP/1.1 200 OK\r\n"
10266 "Content-Type: text/html; charset=iso-8859-1\r\n"
10267 "Content-Length: 3\r\n\r\n"
10268 "Yes");
10269 const MockRead kFailure(
10270 "Should not be called.");
10271 const MockRead kServerChallenge(
10272 "HTTP/1.1 401 Unauthorized\r\n"
10273 "WWW-Authenticate: Mock realm=server\r\n"
10274 "Content-Type: text/html; charset=iso-8859-1\r\n"
10275 "Content-Length: 14\r\n\r\n"
10276 "Unauthorized\r\n");
10277 const MockRead kProxyChallenge(
10278 "HTTP/1.1 407 Unauthorized\r\n"
10279 "Proxy-Authenticate: Mock realm=proxy\r\n"
10280 "Proxy-Connection: close\r\n"
10281 "Content-Type: text/html; charset=iso-8859-1\r\n"
10282 "Content-Length: 14\r\n\r\n"
10283 "Unauthorized\r\n");
10284 const MockRead kProxyConnected(
10285 "HTTP/1.1 200 Connection Established\r\n\r\n");
10286
10287 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
10288 // no constructors, but the C++ compiler on Windows warns about
10289 // unspecified data in compound literals. So, moved to using constructors,
10290 // and TestRound's created with the default constructor should not be used.
10291 struct TestRound {
10292 TestRound()
10293 : expected_rv(ERR_UNEXPECTED),
10294 extra_write(NULL),
10295 extra_read(NULL) {
10296 }
10297 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10298 int expected_rv_arg)
10299 : write(write_arg),
10300 read(read_arg),
10301 expected_rv(expected_rv_arg),
10302 extra_write(NULL),
10303 extra_read(NULL) {
10304 }
10305 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10306 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0110307 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1510308 : write(write_arg),
10309 read(read_arg),
10310 expected_rv(expected_rv_arg),
10311 extra_write(extra_write_arg),
10312 extra_read(extra_read_arg) {
10313 }
10314 MockWrite write;
10315 MockRead read;
10316 int expected_rv;
10317 const MockWrite* extra_write;
10318 const MockRead* extra_read;
10319 };
10320
10321 static const int kNoSSL = 500;
10322
10323 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5110324 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1510325 AuthTiming proxy_auth_timing;
10326 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5110327 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1510328 AuthTiming server_auth_timing;
10329 int server_auth_rv;
10330 int num_auth_rounds;
10331 int first_ssl_round;
10332 TestRound rounds[3];
10333 } test_configs[] = {
10334 // Non-authenticating HTTP server with a direct connection.
10335 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10336 { TestRound(kGet, kSuccess, OK)}},
10337 // Authenticating HTTP server with a direct connection.
10338 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10339 { TestRound(kGet, kServerChallenge, OK),
10340 TestRound(kGetAuth, kSuccess, OK)}},
10341 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10342 { TestRound(kGet, kServerChallenge, OK),
10343 TestRound(kGetAuth, kFailure, kAuthErr)}},
10344 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10345 { TestRound(kGet, kServerChallenge, OK),
10346 TestRound(kGetAuth, kSuccess, OK)}},
10347 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10348 { TestRound(kGet, kServerChallenge, OK),
10349 TestRound(kGetAuth, kFailure, kAuthErr)}},
10350 // Non-authenticating HTTP server through a non-authenticating proxy.
10351 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10352 { TestRound(kGetProxy, kSuccess, OK)}},
10353 // Authenticating HTTP server through a non-authenticating proxy.
10354 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10355 { TestRound(kGetProxy, kServerChallenge, OK),
10356 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10357 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10358 { TestRound(kGetProxy, kServerChallenge, OK),
10359 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10360 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10361 { TestRound(kGetProxy, kServerChallenge, OK),
10362 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10363 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10364 { TestRound(kGetProxy, kServerChallenge, OK),
10365 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10366 // Non-authenticating HTTP server through an authenticating proxy.
10367 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10368 { TestRound(kGetProxy, kProxyChallenge, OK),
10369 TestRound(kGetProxyAuth, kSuccess, OK)}},
10370 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10371 { TestRound(kGetProxy, kProxyChallenge, OK),
10372 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10373 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10374 { TestRound(kGetProxy, kProxyChallenge, OK),
10375 TestRound(kGetProxyAuth, kSuccess, OK)}},
10376 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10377 { TestRound(kGetProxy, kProxyChallenge, OK),
10378 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10379 // Authenticating HTTP server through an authenticating proxy.
10380 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10381 { TestRound(kGetProxy, kProxyChallenge, OK),
10382 TestRound(kGetProxyAuth, kServerChallenge, OK),
10383 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10384 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10385 { TestRound(kGetProxy, kProxyChallenge, OK),
10386 TestRound(kGetProxyAuth, kServerChallenge, OK),
10387 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10388 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10389 { TestRound(kGetProxy, kProxyChallenge, OK),
10390 TestRound(kGetProxyAuth, kServerChallenge, OK),
10391 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10392 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10393 { TestRound(kGetProxy, kProxyChallenge, OK),
10394 TestRound(kGetProxyAuth, kServerChallenge, OK),
10395 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10396 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10397 { TestRound(kGetProxy, kProxyChallenge, OK),
10398 TestRound(kGetProxyAuth, kServerChallenge, OK),
10399 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10400 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10401 { TestRound(kGetProxy, kProxyChallenge, OK),
10402 TestRound(kGetProxyAuth, kServerChallenge, OK),
10403 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10404 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10405 { TestRound(kGetProxy, kProxyChallenge, OK),
10406 TestRound(kGetProxyAuth, kServerChallenge, OK),
10407 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10408 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10409 { TestRound(kGetProxy, kProxyChallenge, OK),
10410 TestRound(kGetProxyAuth, kServerChallenge, OK),
10411 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10412 // Non-authenticating HTTPS server with a direct connection.
10413 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10414 { TestRound(kGet, kSuccess, OK)}},
10415 // Authenticating HTTPS server with a direct connection.
10416 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10417 { TestRound(kGet, kServerChallenge, OK),
10418 TestRound(kGetAuth, kSuccess, OK)}},
10419 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10420 { TestRound(kGet, kServerChallenge, OK),
10421 TestRound(kGetAuth, kFailure, kAuthErr)}},
10422 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10423 { TestRound(kGet, kServerChallenge, OK),
10424 TestRound(kGetAuth, kSuccess, OK)}},
10425 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10426 { TestRound(kGet, kServerChallenge, OK),
10427 TestRound(kGetAuth, kFailure, kAuthErr)}},
10428 // Non-authenticating HTTPS server with a non-authenticating proxy.
10429 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10430 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
10431 // Authenticating HTTPS server through a non-authenticating proxy.
10432 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10433 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10434 TestRound(kGetAuth, kSuccess, OK)}},
10435 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10436 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10437 TestRound(kGetAuth, kFailure, kAuthErr)}},
10438 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10439 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10440 TestRound(kGetAuth, kSuccess, OK)}},
10441 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10442 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10443 TestRound(kGetAuth, kFailure, kAuthErr)}},
10444 // Non-Authenticating HTTPS server through an authenticating proxy.
10445 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10446 { TestRound(kConnect, kProxyChallenge, OK),
10447 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10448 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10449 { TestRound(kConnect, kProxyChallenge, OK),
10450 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10451 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10452 { TestRound(kConnect, kProxyChallenge, OK),
10453 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10454 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10455 { TestRound(kConnect, kProxyChallenge, OK),
10456 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10457 // Authenticating HTTPS server through an authenticating proxy.
10458 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10459 { TestRound(kConnect, kProxyChallenge, OK),
10460 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10461 &kGet, &kServerChallenge),
10462 TestRound(kGetAuth, kSuccess, OK)}},
10463 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10464 { TestRound(kConnect, kProxyChallenge, OK),
10465 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10466 &kGet, &kServerChallenge),
10467 TestRound(kGetAuth, kFailure, kAuthErr)}},
10468 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10469 { TestRound(kConnect, kProxyChallenge, OK),
10470 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10471 &kGet, &kServerChallenge),
10472 TestRound(kGetAuth, kSuccess, OK)}},
10473 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10474 { TestRound(kConnect, kProxyChallenge, OK),
10475 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10476 &kGet, &kServerChallenge),
10477 TestRound(kGetAuth, kFailure, kAuthErr)}},
10478 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10479 { TestRound(kConnect, kProxyChallenge, OK),
10480 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10481 &kGet, &kServerChallenge),
10482 TestRound(kGetAuth, kSuccess, OK)}},
10483 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10484 { TestRound(kConnect, kProxyChallenge, OK),
10485 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10486 &kGet, &kServerChallenge),
10487 TestRound(kGetAuth, kFailure, kAuthErr)}},
10488 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10489 { TestRound(kConnect, kProxyChallenge, OK),
10490 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10491 &kGet, &kServerChallenge),
10492 TestRound(kGetAuth, kSuccess, OK)}},
10493 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10494 { TestRound(kConnect, kProxyChallenge, OK),
10495 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10496 &kGet, &kServerChallenge),
10497 TestRound(kGetAuth, kFailure, kAuthErr)}},
10498 };
10499
viettrungluue4a8b882014-10-16 06:17:3810500 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0810501 HttpAuthHandlerMock::Factory* auth_factory(
10502 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710503 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1510504 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2610505
10506 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1510507 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0810508 for (int n = 0; n < 2; n++) {
10509 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10510 std::string auth_challenge = "Mock realm=proxy";
10511 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2410512 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10513 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0810514 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
10515 origin, BoundNetLog());
10516 auth_handler->SetGenerateExpectation(
10517 test_config.proxy_auth_timing == AUTH_ASYNC,
10518 test_config.proxy_auth_rv);
10519 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10520 }
[email protected]044de0642010-06-17 10:42:1510521 }
10522 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0010523 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1510524 std::string auth_challenge = "Mock realm=server";
10525 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2410526 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10527 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1510528 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10529 origin, BoundNetLog());
10530 auth_handler->SetGenerateExpectation(
10531 test_config.server_auth_timing == AUTH_ASYNC,
10532 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0810533 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1510534 }
10535 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0310536 session_deps_.proxy_service =
10537 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1510538 } else {
rdsmith82957ad2015-09-16 19:42:0310539 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1510540 }
10541
10542 HttpRequestInfo request;
10543 request.method = "GET";
10544 request.url = GURL(test_config.server_url);
10545 request.load_flags = 0;
10546
mmenke6b3af6e2015-09-12 02:06:0610547 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4110548 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510549
rchcb68dc62015-05-21 04:45:3610550 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
10551
10552 std::vector<std::vector<MockRead>> mock_reads(1);
10553 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1510554 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10555 const TestRound& read_write_round = test_config.rounds[round];
10556
10557 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3610558 mock_reads.back().push_back(read_write_round.read);
10559 mock_writes.back().push_back(read_write_round.write);
10560
10561 // kProxyChallenge uses Proxy-Connection: close which means that the
10562 // socket is closed and a new one will be created for the next request.
mmenke0fd148d2015-09-30 23:00:0810563 if (read_write_round.read.data == kProxyChallenge.data &&
10564 read_write_round.write.data != kConnect.data) {
rchcb68dc62015-05-21 04:45:3610565 mock_reads.push_back(std::vector<MockRead>());
10566 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1510567 }
10568
rchcb68dc62015-05-21 04:45:3610569 if (read_write_round.extra_read) {
10570 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1510571 }
rchcb68dc62015-05-21 04:45:3610572 if (read_write_round.extra_write) {
10573 mock_writes.back().push_back(*read_write_round.extra_write);
10574 }
[email protected]044de0642010-06-17 10:42:1510575
10576 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1510577 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710578 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510579 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3610580 }
[email protected]044de0642010-06-17 10:42:1510581
rchcb68dc62015-05-21 04:45:3610582 ScopedVector<StaticSocketDataProvider> data_providers;
10583 for (size_t i = 0; i < mock_reads.size(); ++i) {
10584 data_providers.push_back(new StaticSocketDataProvider(
10585 vector_as_array(&mock_reads[i]), mock_reads[i].size(),
10586 vector_as_array(&mock_writes[i]), mock_writes[i].size()));
10587 session_deps_.socket_factory->AddSocketDataProvider(
10588 data_providers.back());
10589 }
10590
10591 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10592 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1510593 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110594 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510595 int rv;
10596 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110597 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510598 } else {
[email protected]49639fa2011-12-20 23:22:4110599 rv = trans.RestartWithAuth(
10600 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510601 }
10602 if (rv == ERR_IO_PENDING)
10603 rv = callback.WaitForResult();
10604
10605 // Compare results with expected data.
10606 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010607 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5510608 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1510609 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10610 continue;
10611 }
10612 if (round + 1 < test_config.num_auth_rounds) {
10613 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10614 } else {
10615 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10616 }
10617 }
[email protected]e5ae96a2010-04-14 20:12:4510618 }
10619}
10620
[email protected]23e482282013-06-14 16:08:0210621TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410622 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410623 HttpAuthHandlerMock::Factory* auth_factory(
10624 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710625 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0310626 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0710627 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10628 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410629
10630 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10631 auth_handler->set_connection_based(true);
10632 std::string auth_challenge = "Mock realm=server";
10633 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410634 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10635 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410636 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10637 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810638 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410639
[email protected]c871bce92010-07-15 21:51:1410640 int rv = OK;
10641 const HttpResponseInfo* response = NULL;
10642 HttpRequestInfo request;
10643 request.method = "GET";
10644 request.url = origin;
10645 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710646
mmenke6b3af6e2015-09-12 02:06:0610647 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010648
10649 // Use a TCP Socket Pool with only one connection per group. This is used
10650 // to validate that the TCP socket is not released to the pool between
10651 // each round of multi-round authentication.
mmenke6b3af6e2015-09-12 02:06:0610652 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810653 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010654 50, // Max sockets for pool
10655 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0710656 session_deps_.host_resolver.get(),
10657 session_deps_.socket_factory.get(),
10658 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410659 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10660 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210661 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110662 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010663
[email protected]262eec82013-03-19 21:01:3610664 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010665 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110666 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410667
10668 const MockWrite kGet(
10669 "GET / HTTP/1.1\r\n"
10670 "Host: www.example.com\r\n"
10671 "Connection: keep-alive\r\n\r\n");
10672 const MockWrite kGetAuth(
10673 "GET / HTTP/1.1\r\n"
10674 "Host: www.example.com\r\n"
10675 "Connection: keep-alive\r\n"
10676 "Authorization: auth_token\r\n\r\n");
10677
10678 const MockRead kServerChallenge(
10679 "HTTP/1.1 401 Unauthorized\r\n"
10680 "WWW-Authenticate: Mock realm=server\r\n"
10681 "Content-Type: text/html; charset=iso-8859-1\r\n"
10682 "Content-Length: 14\r\n\r\n"
10683 "Unauthorized\r\n");
10684 const MockRead kSuccess(
10685 "HTTP/1.1 200 OK\r\n"
10686 "Content-Type: text/html; charset=iso-8859-1\r\n"
10687 "Content-Length: 3\r\n\r\n"
10688 "Yes");
10689
10690 MockWrite writes[] = {
10691 // First round
10692 kGet,
10693 // Second round
10694 kGetAuth,
10695 // Third round
10696 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010697 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010698 kGetAuth,
10699 // Competing request
10700 kGet,
[email protected]c871bce92010-07-15 21:51:1410701 };
10702 MockRead reads[] = {
10703 // First round
10704 kServerChallenge,
10705 // Second round
10706 kServerChallenge,
10707 // Third round
[email protected]eca50e122010-09-11 14:03:3010708 kServerChallenge,
10709 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410710 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010711 // Competing response
10712 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410713 };
10714 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10715 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710716 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410717
thestig9d3bb0c2015-01-24 00:49:5110718 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010719
10720 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410721 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110722 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410723 if (rv == ERR_IO_PENDING)
10724 rv = callback.WaitForResult();
10725 EXPECT_EQ(OK, rv);
10726 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010727 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410728 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810729 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410730
[email protected]7ef4cbbb2011-02-06 11:19:1010731 // In between rounds, another request comes in for the same domain.
10732 // It should not be able to grab the TCP socket that trans has already
10733 // claimed.
10734 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010735 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110736 TestCompletionCallback callback_compete;
10737 rv = trans_compete->Start(
10738 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010739 EXPECT_EQ(ERR_IO_PENDING, rv);
10740 // callback_compete.WaitForResult at this point would stall forever,
10741 // since the HttpNetworkTransaction does not release the request back to
10742 // the pool until after authentication completes.
10743
10744 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410745 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110746 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410747 if (rv == ERR_IO_PENDING)
10748 rv = callback.WaitForResult();
10749 EXPECT_EQ(OK, rv);
10750 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010751 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410752 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810753 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410754
[email protected]7ef4cbbb2011-02-06 11:19:1010755 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1410756 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110757 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410758 if (rv == ERR_IO_PENDING)
10759 rv = callback.WaitForResult();
10760 EXPECT_EQ(OK, rv);
10761 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010762 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410763 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810764 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3010765
[email protected]7ef4cbbb2011-02-06 11:19:1010766 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010767 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110768 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010769 if (rv == ERR_IO_PENDING)
10770 rv = callback.WaitForResult();
10771 EXPECT_EQ(OK, rv);
10772 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010773 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3010774 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810775 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010776
10777 // Read the body since the fourth round was successful. This will also
10778 // release the socket back to the pool.
10779 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010780 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010781 if (rv == ERR_IO_PENDING)
10782 rv = callback.WaitForResult();
10783 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010784 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010785 EXPECT_EQ(0, rv);
10786 // There are still 0 idle sockets, since the trans_compete transaction
10787 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810788 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010789
10790 // The competing request can now finish. Wait for the headers and then
10791 // read the body.
10792 rv = callback_compete.WaitForResult();
10793 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010794 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010795 if (rv == ERR_IO_PENDING)
10796 rv = callback.WaitForResult();
10797 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010798 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010799 EXPECT_EQ(0, rv);
10800
10801 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810802 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410803}
10804
[email protected]65041fa2010-05-21 06:56:5310805// This tests the case that a request is issued via http instead of spdy after
10806// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210807TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bnc55ff9da2015-08-19 18:42:3510808 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310809 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610810 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310811 session_deps_.next_protos = next_protos;
10812
[email protected]65041fa2010-05-21 06:56:5310813 HttpRequestInfo request;
10814 request.method = "GET";
bncce36dca22015-04-21 22:11:2310815 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5310816 request.load_flags = 0;
10817
10818 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310819 MockWrite(
10820 "GET / HTTP/1.1\r\n"
10821 "Host: www.example.org\r\n"
10822 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5310823 };
10824
[email protected]8a0fc822013-06-27 20:52:4310825 std::string alternate_protocol_http_header =
10826 GetAlternateProtocolHttpHeader();
10827
[email protected]65041fa2010-05-21 06:56:5310828 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210829 MockRead("HTTP/1.1 200 OK\r\n"),
10830 MockRead(alternate_protocol_http_header.c_str()),
10831 MockRead("\r\n"),
10832 MockRead("hello world"),
10833 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310834 };
10835
[email protected]8ddf8322012-02-23 18:08:0610836 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4810837 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5310838
[email protected]bb88e1d32013-05-03 23:11:0710839 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310840
10841 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10842 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710843 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310844
[email protected]49639fa2011-12-20 23:22:4110845 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310846
mmenke6b3af6e2015-09-12 02:06:0610847 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610848 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010849 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310850
[email protected]49639fa2011-12-20 23:22:4110851 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310852
10853 EXPECT_EQ(ERR_IO_PENDING, rv);
10854 EXPECT_EQ(OK, callback.WaitForResult());
10855
10856 const HttpResponseInfo* response = trans->GetResponseInfo();
10857 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010858 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310859 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10860
10861 std::string response_data;
10862 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10863 EXPECT_EQ("hello world", response_data);
10864
10865 EXPECT_FALSE(response->was_fetched_via_spdy);
10866 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310867}
[email protected]26ef6582010-06-24 02:30:4710868
bnc55ff9da2015-08-19 18:42:3510869// Simulate the SSL handshake completing with an NPN negotiation followed by an
10870// immediate server closing of the socket.
10871// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0210872TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bnc55ff9da2015-08-19 18:42:3510873 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310874 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710875
10876 HttpRequestInfo request;
10877 request.method = "GET";
bncce36dca22015-04-21 22:11:2310878 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4710879 request.load_flags = 0;
10880
[email protected]8ddf8322012-02-23 18:08:0610881 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210882 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710883 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710884
[email protected]cdf8f7e72013-05-23 10:56:4610885 scoped_ptr<SpdyFrame> req(
10886 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310887 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4710888
10889 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610890 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710891 };
10892
rch8e6c6c42015-05-01 14:05:1310893 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10894 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710895 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710896
[email protected]49639fa2011-12-20 23:22:4110897 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710898
mmenke6b3af6e2015-09-12 02:06:0610899 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610900 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010901 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710902
[email protected]49639fa2011-12-20 23:22:4110903 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710904 EXPECT_EQ(ERR_IO_PENDING, rv);
10905 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710906}
[email protected]65d34382010-07-01 18:12:2610907
[email protected]795cbf82013-07-22 09:37:2710908// A subclass of HttpAuthHandlerMock that records the request URL when
10909// it gets it. This is needed since the auth handler may get destroyed
10910// before we get a chance to query it.
10911class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10912 public:
10913 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10914
dchengb03027d2014-10-21 12:00:2010915 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710916
10917 protected:
dchengb03027d2014-10-21 12:00:2010918 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10919 const HttpRequestInfo* request,
10920 const CompletionCallback& callback,
10921 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710922 *url_ = request->url;
10923 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10924 credentials, request, callback, auth_token);
10925 }
10926
10927 private:
10928 GURL* url_;
10929};
10930
bnc55ff9da2015-08-19 18:42:3510931// This test ensures that the URL passed into the proxy is upgraded to https
10932// when doing an Alternate Protocol upgrade.
[email protected]23e482282013-06-14 16:08:0210933TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
bnc55ff9da2015-08-19 18:42:3510934 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310935 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010936
rdsmith82957ad2015-09-16 19:42:0310937 session_deps_.proxy_service =
10938 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5110939 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710940 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710941 GURL request_url;
10942 {
10943 HttpAuthHandlerMock::Factory* auth_factory =
10944 new HttpAuthHandlerMock::Factory();
10945 UrlRecordingHttpAuthHandlerMock* auth_handler =
10946 new UrlRecordingHttpAuthHandlerMock(&request_url);
10947 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10948 auth_factory->set_do_init_from_challenge(true);
10949 session_deps_.http_auth_handler_factory.reset(auth_factory);
10950 }
[email protected]f45c1ee2010-08-03 00:54:3010951
10952 HttpRequestInfo request;
10953 request.method = "GET";
bncce36dca22015-04-21 22:11:2310954 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3010955 request.load_flags = 0;
10956
10957 // First round goes unauthenticated through the proxy.
10958 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2310959 MockWrite(
10960 "GET http://www.example.org/ HTTP/1.1\r\n"
10961 "Host: www.example.org\r\n"
10962 "Proxy-Connection: keep-alive\r\n"
10963 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010964 };
10965 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610966 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810967 MockRead("HTTP/1.1 200 OK\r\n"),
10968 MockRead("Alternate-Protocol: 443:"),
10969 MockRead(GetAlternateProtocolFromParam()),
10970 MockRead("\r\n"),
10971 MockRead("Proxy-Connection: close\r\n"),
10972 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010973 };
10974 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10975 data_writes_1, arraysize(data_writes_1));
10976
bncce36dca22015-04-21 22:11:2310977 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3010978 // Alternate-Protocol announcement in the first round. It fails due
10979 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2310980 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5910981 // Proxy-Authorization headers. There is then a SPDY request round.
10982 //
[email protected]fe3b7dc2012-02-03 19:52:0910983 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10984 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10985 // does a Disconnect and Connect on the same socket, rather than trying
10986 // to obtain a new one.
10987 //
[email protected]394816e92010-08-03 07:38:5910988 // NOTE: Originally, the proxy response to the second CONNECT request
10989 // simply returned another 407 so the unit test could skip the SSL connection
10990 // establishment and SPDY framing issues. Alas, the
10991 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010992 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910993
[email protected]cdf8f7e72013-05-23 10:56:4610994 scoped_ptr<SpdyFrame> req(
10995 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210996 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10997 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010998
[email protected]394816e92010-08-03 07:38:5910999 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2311000 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311001 MockWrite(ASYNC, 0,
11002 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11003 "Host: www.example.org\r\n"
11004 "Proxy-Connection: keep-alive\r\n"
11005 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911006
bncce36dca22015-04-21 22:11:2311007 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311008 MockWrite(ASYNC, 2,
11009 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11010 "Host: www.example.org\r\n"
11011 "Proxy-Connection: keep-alive\r\n"
11012 "Proxy-Authorization: auth_token\r\n"
11013 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011014
bncce36dca22015-04-21 22:11:2311015 // SPDY request
rch8e6c6c42015-05-01 14:05:1311016 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3011017 };
mmenke0fd148d2015-09-30 23:00:0811018 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
11019 "Proxy-Authenticate: Mock\r\n"
11020 "Proxy-Connection: close\r\n"
11021 "\r\n");
11022 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
[email protected]394816e92010-08-03 07:38:5911023 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1311024 // First connection attempt fails
mmenke0fd148d2015-09-30 23:00:0811025 MockRead(ASYNC, kRejectConnectResponse,
11026 arraysize(kRejectConnectResponse) - 1, 1),
[email protected]394816e92010-08-03 07:38:5911027
rch8e6c6c42015-05-01 14:05:1311028 // Second connection attempt passes
mmenke0fd148d2015-09-30 23:00:0811029 MockRead(ASYNC, kAcceptConnectResponse,
11030 arraysize(kAcceptConnectResponse) - 1, 3),
[email protected]394816e92010-08-03 07:38:5911031
rch8e6c6c42015-05-01 14:05:1311032 // SPDY response
mmenke0fd148d2015-09-30 23:00:0811033 CreateMockRead(*resp.get(), 5),
11034 CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1311035 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5911036 };
rch8e6c6c42015-05-01 14:05:1311037 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
11038 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3011039
[email protected]8ddf8322012-02-23 18:08:0611040 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211041 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2311042 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
11043 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3011044
[email protected]d973e99a2012-02-17 21:02:3611045 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511046 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11047 NULL, 0, NULL, 0);
11048 hanging_non_alternate_protocol_socket.set_connect_data(
11049 never_finishing_connect);
11050
[email protected]bb88e1d32013-05-03 23:11:0711051 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
11052 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
11053 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11054 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511055 &hanging_non_alternate_protocol_socket);
mmenke6b3af6e2015-09-12 02:06:0611056 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3011057
11058 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4111059 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3611060 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5011061 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111062 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011063 EXPECT_EQ(ERR_IO_PENDING, rv);
11064 EXPECT_EQ(OK, callback_1.WaitForResult());
11065
11066 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4111067 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3611068 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5011069 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111070 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011071 EXPECT_EQ(ERR_IO_PENDING, rv);
11072 EXPECT_EQ(OK, callback_2.WaitForResult());
11073 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011074 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3011075 ASSERT_FALSE(response->auth_challenge.get() == NULL);
11076
11077 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4111078 TestCompletionCallback callback_3;
11079 rv = trans_2->RestartWithAuth(
11080 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3011081 EXPECT_EQ(ERR_IO_PENDING, rv);
11082 EXPECT_EQ(OK, callback_3.WaitForResult());
11083
11084 // After all that work, these two lines (or actually, just the scheme) are
11085 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3011086 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2311087 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3011088
[email protected]029c83b62013-01-24 05:28:2011089 LoadTimingInfo load_timing_info;
11090 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
11091 TestLoadTimingNotReusedWithPac(load_timing_info,
11092 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3811093}
11094
11095// Test that if we cancel the transaction as the connection is completing, that
11096// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0211097TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3811098 // Setup everything about the connection to complete synchronously, so that
11099 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
11100 // for is the callback from the HttpStreamRequest.
11101 // Then cancel the transaction.
11102 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3611103 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3811104 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611105 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
11106 MockRead(SYNCHRONOUS, "hello world"),
11107 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3811108 };
11109
[email protected]8e6441ca2010-08-19 05:56:3811110 HttpRequestInfo request;
11111 request.method = "GET";
bncce36dca22015-04-21 22:11:2311112 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3811113 request.load_flags = 0;
11114
[email protected]bb88e1d32013-05-03 23:11:0711115 session_deps_.host_resolver->set_synchronous_mode(true);
mmenke6b3af6e2015-09-12 02:06:0611116 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2711117 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111118 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2711119
[email protected]8e6441ca2010-08-19 05:56:3811120 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11121 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711122 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3811123
[email protected]49639fa2011-12-20 23:22:4111124 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3811125
vishal.b62985ca92015-04-17 08:45:5111126 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4111127 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3811128 EXPECT_EQ(ERR_IO_PENDING, rv);
11129 trans.reset(); // Cancel the transaction here.
11130
[email protected]2da659e2013-05-23 20:51:3411131 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3011132}
11133
[email protected]ecab6e052014-05-16 14:58:1211134// Test that if a transaction is cancelled after receiving the headers, the
11135// stream is drained properly and added back to the socket pool. The main
11136// purpose of this test is to make sure that an HttpStreamParser can be read
11137// from after the HttpNetworkTransaction and the objects it owns have been
11138// deleted.
11139// See http://crbug.com/368418
11140TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
11141 MockRead data_reads[] = {
11142 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
11143 MockRead(ASYNC, "Content-Length: 2\r\n"),
11144 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
11145 MockRead(ASYNC, "1"),
11146 // 2 async reads are necessary to trigger a ReadResponseBody call after the
11147 // HttpNetworkTransaction has been deleted.
11148 MockRead(ASYNC, "2"),
11149 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
11150 };
11151 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11152 session_deps_.socket_factory->AddSocketDataProvider(&data);
11153
mmenke6b3af6e2015-09-12 02:06:0611154 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1211155
11156 {
11157 HttpRequestInfo request;
11158 request.method = "GET";
bncce36dca22015-04-21 22:11:2311159 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1211160 request.load_flags = 0;
11161
dcheng48459ac22014-08-26 00:46:4111162 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1211163 TestCompletionCallback callback;
11164
11165 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
11166 EXPECT_EQ(ERR_IO_PENDING, rv);
11167 callback.WaitForResult();
11168
11169 const HttpResponseInfo* response = trans.GetResponseInfo();
11170 ASSERT_TRUE(response != NULL);
11171 EXPECT_TRUE(response->headers.get() != NULL);
11172 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11173
11174 // The transaction and HttpRequestInfo are deleted.
11175 }
11176
11177 // Let the HttpResponseBodyDrainer drain the socket.
11178 base::MessageLoop::current()->RunUntilIdle();
11179
11180 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4111181 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1211182}
11183
[email protected]76a505b2010-08-25 06:23:0011184// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211185TEST_P(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0311186 session_deps_.proxy_service =
11187 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111188 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711189 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:0611190 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011191
[email protected]76a505b2010-08-25 06:23:0011192 HttpRequestInfo request;
11193 request.method = "GET";
bncce36dca22015-04-21 22:11:2311194 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011195
11196 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311197 MockWrite(
11198 "GET http://www.example.org/ HTTP/1.1\r\n"
11199 "Host: www.example.org\r\n"
11200 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011201 };
11202
11203 MockRead data_reads1[] = {
11204 MockRead("HTTP/1.1 200 OK\r\n"),
11205 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11206 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611207 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011208 };
11209
11210 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11211 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711212 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0011213
[email protected]49639fa2011-12-20 23:22:4111214 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011215
[email protected]262eec82013-03-19 21:01:3611216 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011217 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2711218 BeforeProxyHeadersSentHandler proxy_headers_handler;
11219 trans->SetBeforeProxyHeadersSentCallback(
11220 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
11221 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5011222
[email protected]49639fa2011-12-20 23:22:4111223 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011224 EXPECT_EQ(ERR_IO_PENDING, rv);
11225
11226 rv = callback1.WaitForResult();
11227 EXPECT_EQ(OK, rv);
11228
11229 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011230 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011231
11232 EXPECT_TRUE(response->headers->IsKeepAlive());
11233 EXPECT_EQ(200, response->headers->response_code());
11234 EXPECT_EQ(100, response->headers->GetContentLength());
11235 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511236 EXPECT_TRUE(
11237 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2711238 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
11239 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0011240 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2011241
11242 LoadTimingInfo load_timing_info;
11243 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11244 TestLoadTimingNotReusedWithPac(load_timing_info,
11245 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0011246}
11247
11248// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211249TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0311250 session_deps_.proxy_service =
11251 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111252 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711253 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:0611254 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011255
[email protected]76a505b2010-08-25 06:23:0011256 HttpRequestInfo request;
11257 request.method = "GET";
bncce36dca22015-04-21 22:11:2311258 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011259
11260 // Since we have proxy, should try to establish tunnel.
11261 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311262 MockWrite(
11263 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11264 "Host: www.example.org\r\n"
11265 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011266
bncce36dca22015-04-21 22:11:2311267 MockWrite(
11268 "GET / HTTP/1.1\r\n"
11269 "Host: www.example.org\r\n"
11270 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011271 };
11272
11273 MockRead data_reads1[] = {
11274 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
11275
11276 MockRead("HTTP/1.1 200 OK\r\n"),
11277 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11278 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611279 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011280 };
11281
11282 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11283 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711284 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611285 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711286 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011287
[email protected]49639fa2011-12-20 23:22:4111288 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011289
[email protected]262eec82013-03-19 21:01:3611290 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011291 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011292
[email protected]49639fa2011-12-20 23:22:4111293 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011294 EXPECT_EQ(ERR_IO_PENDING, rv);
11295
11296 rv = callback1.WaitForResult();
11297 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4611298 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011299 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011300 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011301 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011302 NetLog::PHASE_NONE);
11303 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011304 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011305 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11306 NetLog::PHASE_NONE);
11307
11308 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011309 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011310
11311 EXPECT_TRUE(response->headers->IsKeepAlive());
11312 EXPECT_EQ(200, response->headers->response_code());
11313 EXPECT_EQ(100, response->headers->GetContentLength());
11314 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
11315 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511316 EXPECT_TRUE(
11317 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2011318
11319 LoadTimingInfo load_timing_info;
11320 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11321 TestLoadTimingNotReusedWithPac(load_timing_info,
11322 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0011323}
11324
11325// Test a basic HTTPS GET request through a proxy, but the server hangs up
11326// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0211327TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0311328 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111329 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711330 session_deps_.net_log = log.bound().net_log();
mmenke6b3af6e2015-09-12 02:06:0611331 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011332
[email protected]76a505b2010-08-25 06:23:0011333 HttpRequestInfo request;
11334 request.method = "GET";
bncce36dca22015-04-21 22:11:2311335 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011336
11337 // Since we have proxy, should try to establish tunnel.
11338 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311339 MockWrite(
11340 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11341 "Host: www.example.org\r\n"
11342 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011343
bncce36dca22015-04-21 22:11:2311344 MockWrite(
11345 "GET / HTTP/1.1\r\n"
11346 "Host: www.example.org\r\n"
11347 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011348 };
11349
11350 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0611351 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0011352 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611353 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0011354 };
11355
11356 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11357 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711358 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611359 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711360 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011361
[email protected]49639fa2011-12-20 23:22:4111362 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011363
[email protected]262eec82013-03-19 21:01:3611364 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011365 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011366
[email protected]49639fa2011-12-20 23:22:4111367 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011368 EXPECT_EQ(ERR_IO_PENDING, rv);
11369
11370 rv = callback1.WaitForResult();
11371 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4611372 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011373 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011374 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011375 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011376 NetLog::PHASE_NONE);
11377 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011378 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011379 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11380 NetLog::PHASE_NONE);
11381}
11382
[email protected]749eefa82010-09-13 22:14:0311383// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0211384TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4611385 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2311386 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1311387 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0311388
[email protected]23e482282013-06-14 16:08:0211389 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11390 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0311391 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311392 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0311393 };
11394
rch8e6c6c42015-05-01 14:05:1311395 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11396 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711397 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0311398
[email protected]8ddf8322012-02-23 18:08:0611399 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211400 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711401 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0311402
mmenke6b3af6e2015-09-12 02:06:0611403 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0311404
11405 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2311406 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011407 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311408 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711409 base::WeakPtr<SpdySession> spdy_session =
mmenke6b3af6e2015-09-12 02:06:0611410 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311411
11412 HttpRequestInfo request;
11413 request.method = "GET";
bncce36dca22015-04-21 22:11:2311414 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0311415 request.load_flags = 0;
11416
11417 // This is the important line that marks this as a preconnect.
11418 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
11419
[email protected]262eec82013-03-19 21:01:3611420 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011421 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0311422
[email protected]41d64e82013-07-03 22:44:2611423 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4111424 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311425 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111426 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0311427}
11428
[email protected]73b8dd222010-11-11 19:55:2411429// Given a net error, cause that error to be returned from the first Write()
11430// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0211431void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0711432 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2911433 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711434 request_info.url = GURL("https://www.example.com/");
11435 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911436 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711437
[email protected]8ddf8322012-02-23 18:08:0611438 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2911439 MockWrite data_writes[] = {
11440 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2411441 };
ttuttle859dc7a2015-04-23 19:42:2911442 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711443 session_deps_.socket_factory->AddSocketDataProvider(&data);
11444 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2411445
mmenke6b3af6e2015-09-12 02:06:0611446 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611447 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011448 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2411449
[email protected]49639fa2011-12-20 23:22:4111450 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911451 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11452 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2411453 rv = callback.WaitForResult();
11454 ASSERT_EQ(error, rv);
11455}
11456
[email protected]23e482282013-06-14 16:08:0211457TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2411458 // Just check a grab bag of cert errors.
11459 static const int kErrors[] = {
11460 ERR_CERT_COMMON_NAME_INVALID,
11461 ERR_CERT_AUTHORITY_INVALID,
11462 ERR_CERT_DATE_INVALID,
11463 };
11464 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0611465 CheckErrorIsPassedBack(kErrors[i], ASYNC);
11466 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2411467 }
11468}
11469
[email protected]bd0b6772011-01-11 19:59:3011470// Ensure that a client certificate is removed from the SSL client auth
11471// cache when:
11472// 1) No proxy is involved.
11473// 2) TLS False Start is disabled.
11474// 3) The initial TLS handshake requests a client certificate.
11475// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211476TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311477 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911478 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711479 request_info.url = GURL("https://www.example.com/");
11480 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911481 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711482
[email protected]bd0b6772011-01-11 19:59:3011483 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111484 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011485
11486 // [ssl_]data1 contains the data for the first SSL handshake. When a
11487 // CertificateRequest is received for the first time, the handshake will
11488 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2911489 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011490 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711491 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911492 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711493 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011494
11495 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
11496 // False Start is not being used, the result of the SSL handshake will be
11497 // returned as part of the SSLClientSocket::Connect() call. This test
11498 // matches the result of a server sending a handshake_failure alert,
11499 // rather than a Finished message, because it requires a client
11500 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2911501 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011502 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711503 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911504 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711505 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011506
11507 // [ssl_]data3 contains the data for the third SSL handshake. When a
11508 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211509 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
11510 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3011511 // of the HttpNetworkTransaction. Because this test failure is due to
11512 // requiring a client certificate, this fallback handshake should also
11513 // fail.
ttuttle859dc7a2015-04-23 19:42:2911514 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011515 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711516 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911517 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711518 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011519
[email protected]80c75f682012-05-26 16:22:1711520 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
11521 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211522 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
11523 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1711524 // of the HttpNetworkTransaction. Because this test failure is due to
11525 // requiring a client certificate, this fallback handshake should also
11526 // fail.
ttuttle859dc7a2015-04-23 19:42:2911527 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1711528 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711529 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911530 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711531 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711532
mmenke6b3af6e2015-09-12 02:06:0611533 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611534 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011535 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011536
[email protected]bd0b6772011-01-11 19:59:3011537 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4111538 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911539 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11540 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011541
11542 // Complete the SSL handshake, which should abort due to requiring a
11543 // client certificate.
11544 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911545 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011546
11547 // Indicate that no certificate should be supplied. From the perspective
11548 // of SSLClientCertCache, NULL is just as meaningful as a real
11549 // certificate, so this is the same as supply a
11550 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111551 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911552 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011553
11554 // Ensure the certificate was added to the client auth cache before
11555 // allowing the connection to continue restarting.
11556 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111557 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11558 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011559 ASSERT_EQ(NULL, client_cert.get());
11560
11561 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711562 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11563 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011564 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911565 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011566
11567 // Ensure that the client certificate is removed from the cache on a
11568 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111569 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11570 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011571}
11572
11573// Ensure that a client certificate is removed from the SSL client auth
11574// cache when:
11575// 1) No proxy is involved.
11576// 2) TLS False Start is enabled.
11577// 3) The initial TLS handshake requests a client certificate.
11578// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211579TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311580 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911581 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711582 request_info.url = GURL("https://www.example.com/");
11583 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911584 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711585
[email protected]bd0b6772011-01-11 19:59:3011586 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111587 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011588
11589 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11590 // return successfully after reading up to the peer's Certificate message.
11591 // This is to allow the caller to call SSLClientSocket::Write(), which can
11592 // enqueue application data to be sent in the same packet as the
11593 // ChangeCipherSpec and Finished messages.
11594 // The actual handshake will be finished when SSLClientSocket::Read() is
11595 // called, which expects to process the peer's ChangeCipherSpec and
11596 // Finished messages. If there was an error negotiating with the peer,
11597 // such as due to the peer requiring a client certificate when none was
11598 // supplied, the alert sent by the peer won't be processed until Read() is
11599 // called.
11600
11601 // Like the non-False Start case, when a client certificate is requested by
11602 // the peer, the handshake is aborted during the Connect() call.
11603 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2911604 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011605 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711606 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911607 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711608 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011609
11610 // When a client certificate is supplied, Connect() will not be aborted
11611 // when the peer requests the certificate. Instead, the handshake will
11612 // artificially succeed, allowing the caller to write the HTTP request to
11613 // the socket. The handshake messages are not processed until Read() is
11614 // called, which then detects that the handshake was aborted, due to the
11615 // peer sending a handshake_failure because it requires a client
11616 // certificate.
ttuttle859dc7a2015-04-23 19:42:2911617 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011618 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911620 MockRead data2_reads[] = {
11621 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011622 };
ttuttle859dc7a2015-04-23 19:42:2911623 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711624 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011625
11626 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711627 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11628 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911629 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011630 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711631 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911632 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711633 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011634
[email protected]80c75f682012-05-26 16:22:1711635 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11636 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911637 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1711638 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711639 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911640 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711641 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711642
[email protected]7799de12013-05-30 05:52:5111643 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2911644 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5111645 ssl_data5.cert_request_info = cert_request.get();
11646 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2911647 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5111648 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11649
mmenke6b3af6e2015-09-12 02:06:0611650 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611651 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011652 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011653
[email protected]bd0b6772011-01-11 19:59:3011654 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111655 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911656 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11657 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011658
11659 // Complete the SSL handshake, which should abort due to requiring a
11660 // client certificate.
11661 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911662 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011663
11664 // Indicate that no certificate should be supplied. From the perspective
11665 // of SSLClientCertCache, NULL is just as meaningful as a real
11666 // certificate, so this is the same as supply a
11667 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111668 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911669 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011670
11671 // Ensure the certificate was added to the client auth cache before
11672 // allowing the connection to continue restarting.
11673 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111674 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11675 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011676 ASSERT_EQ(NULL, client_cert.get());
11677
[email protected]bd0b6772011-01-11 19:59:3011678 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711679 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11680 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011681 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911682 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011683
11684 // Ensure that the client certificate is removed from the cache on a
11685 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111686 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11687 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011688}
11689
[email protected]8c405132011-01-11 22:03:1811690// Ensure that a client certificate is removed from the SSL client auth
11691// cache when:
11692// 1) An HTTPS proxy is involved.
11693// 3) The HTTPS proxy requests a client certificate.
11694// 4) The client supplies an invalid/unacceptable certificate for the
11695// proxy.
11696// The test is repeated twice, first for connecting to an HTTPS endpoint,
11697// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211698TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0311699 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5111700 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711701 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811702
11703 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111704 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811705
11706 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11707 // [ssl_]data[1-3]. Rather than represending the endpoint
11708 // (www.example.com:443), they represent failures with the HTTPS proxy
11709 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2911710 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811711 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711712 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911713 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711714 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811715
ttuttle859dc7a2015-04-23 19:42:2911716 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811717 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711718 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911719 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711720 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811721
[email protected]80c75f682012-05-26 16:22:1711722 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11723#if 0
ttuttle859dc7a2015-04-23 19:42:2911724 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811725 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711726 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911727 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711728 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711729#endif
[email protected]8c405132011-01-11 22:03:1811730
ttuttle859dc7a2015-04-23 19:42:2911731 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1811732 requests[0].url = GURL("https://www.example.com/");
11733 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911734 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811735
11736 requests[1].url = GURL("http://www.example.com/");
11737 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911738 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811739
11740 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711741 session_deps_.socket_factory->ResetNextMockIndexes();
mmenke6b3af6e2015-09-12 02:06:0611742 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811743 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011744 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811745
11746 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111747 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911748 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
11749 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811750
11751 // Complete the SSL handshake, which should abort due to requiring a
11752 // client certificate.
11753 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911754 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1811755
11756 // Indicate that no certificate should be supplied. From the perspective
11757 // of SSLClientCertCache, NULL is just as meaningful as a real
11758 // certificate, so this is the same as supply a
11759 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111760 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911761 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811762
11763 // Ensure the certificate was added to the client auth cache before
11764 // allowing the connection to continue restarting.
11765 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111766 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11767 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811768 ASSERT_EQ(NULL, client_cert.get());
11769 // Ensure the certificate was NOT cached for the endpoint. This only
11770 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111771 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11772 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811773
11774 // Restart the handshake. This will consume ssl_data2, which fails, and
11775 // then consume ssl_data3, which should also fail. The result code is
11776 // checked against what ssl_data3 should return.
11777 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911778 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1811779
11780 // Now that the new handshake has failed, ensure that the client
11781 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111782 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11783 HostPortPair("proxy", 70), &client_cert));
11784 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11785 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811786 }
11787}
11788
mmenke5c642132015-06-02 16:05:1311789TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bnc55ff9da2015-08-19 18:42:3511790 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311791 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611792
11793 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711794 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenke6b3af6e2015-09-12 02:06:0611795 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611796 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11797 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611798
[email protected]8ddf8322012-02-23 18:08:0611799 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211800 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711801 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611802
[email protected]cdf8f7e72013-05-23 10:56:4611803 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311804 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611805 scoped_ptr<SpdyFrame> host2_req(
11806 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611807 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311808 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611809 };
[email protected]23e482282013-06-14 16:08:0211810 scoped_ptr<SpdyFrame> host1_resp(
11811 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11812 scoped_ptr<SpdyFrame> host1_resp_body(
11813 spdy_util_.ConstructSpdyBodyFrame(1, true));
11814 scoped_ptr<SpdyFrame> host2_resp(
11815 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11816 scoped_ptr<SpdyFrame> host2_resp_body(
11817 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611818 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311819 CreateMockRead(*host1_resp, 1),
11820 CreateMockRead(*host1_resp_body, 2),
11821 CreateMockRead(*host2_resp, 4),
11822 CreateMockRead(*host2_resp_body, 5),
11823 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611824 };
11825
[email protected]d2b5f092012-06-08 23:55:0211826 IPAddressNumber ip;
11827 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11828 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11829 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311830 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11831 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711832 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611833
[email protected]aa22b242011-11-16 18:58:2911834 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611835 HttpRequestInfo request1;
11836 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311837 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611838 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011839 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611840
[email protected]49639fa2011-12-20 23:22:4111841 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611842 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111843 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611844
11845 const HttpResponseInfo* response = trans1.GetResponseInfo();
11846 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011847 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611848 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11849
11850 std::string response_data;
11851 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11852 EXPECT_EQ("hello!", response_data);
11853
11854 // Preload www.gmail.com into HostCache.
11855 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011856 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611857 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011858 rv = session_deps_.host_resolver->Resolve(resolve_info,
11859 DEFAULT_PRIORITY,
11860 &ignored,
11861 callback.callback(),
11862 NULL,
11863 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711864 EXPECT_EQ(ERR_IO_PENDING, rv);
11865 rv = callback.WaitForResult();
11866 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611867
11868 HttpRequestInfo request2;
11869 request2.method = "GET";
11870 request2.url = GURL("https://www.gmail.com/");
11871 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011872 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611873
[email protected]49639fa2011-12-20 23:22:4111874 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611875 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111876 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611877
11878 response = trans2.GetResponseInfo();
11879 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011880 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611881 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11882 EXPECT_TRUE(response->was_fetched_via_spdy);
11883 EXPECT_TRUE(response->was_npn_negotiated);
11884 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11885 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611886}
11887
[email protected]23e482282013-06-14 16:08:0211888TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bnc55ff9da2015-08-19 18:42:3511889 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311890 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211891
11892 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711893 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenke6b3af6e2015-09-12 02:06:0611894 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211895 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11896 pool_peer.DisableDomainAuthenticationVerification();
11897
11898 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211899 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711900 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211901
[email protected]cdf8f7e72013-05-23 10:56:4611902 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311903 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611904 scoped_ptr<SpdyFrame> host2_req(
11905 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211906 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311907 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0211908 };
[email protected]23e482282013-06-14 16:08:0211909 scoped_ptr<SpdyFrame> host1_resp(
11910 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11911 scoped_ptr<SpdyFrame> host1_resp_body(
11912 spdy_util_.ConstructSpdyBodyFrame(1, true));
11913 scoped_ptr<SpdyFrame> host2_resp(
11914 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11915 scoped_ptr<SpdyFrame> host2_resp_body(
11916 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211917 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311918 CreateMockRead(*host1_resp, 1),
11919 CreateMockRead(*host1_resp_body, 2),
11920 CreateMockRead(*host2_resp, 4),
11921 CreateMockRead(*host2_resp_body, 5),
11922 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0211923 };
11924
11925 IPAddressNumber ip;
11926 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11927 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11928 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311929 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11930 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711931 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211932
11933 TestCompletionCallback callback;
11934 HttpRequestInfo request1;
11935 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311936 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0211937 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011938 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211939
11940 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11941 EXPECT_EQ(ERR_IO_PENDING, rv);
11942 EXPECT_EQ(OK, callback.WaitForResult());
11943
11944 const HttpResponseInfo* response = trans1.GetResponseInfo();
11945 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011946 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211947 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11948
11949 std::string response_data;
11950 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11951 EXPECT_EQ("hello!", response_data);
11952
11953 HttpRequestInfo request2;
11954 request2.method = "GET";
11955 request2.url = GURL("https://www.gmail.com/");
11956 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011957 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211958
11959 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11960 EXPECT_EQ(ERR_IO_PENDING, rv);
11961 EXPECT_EQ(OK, callback.WaitForResult());
11962
11963 response = trans2.GetResponseInfo();
11964 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011965 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211966 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11967 EXPECT_TRUE(response->was_fetched_via_spdy);
11968 EXPECT_TRUE(response->was_npn_negotiated);
11969 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11970 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211971}
11972
ttuttle859dc7a2015-04-23 19:42:2911973class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4611974 public:
11975 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11976 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011977 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611978
11979 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11980
11981 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011982 int Resolve(const RequestInfo& info,
11983 RequestPriority priority,
11984 AddressList* addresses,
11985 const CompletionCallback& callback,
11986 RequestHandle* out_req,
11987 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011988 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011989 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011990 }
11991
dchengb03027d2014-10-21 12:00:2011992 int ResolveFromCache(const RequestInfo& info,
11993 AddressList* addresses,
11994 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011995 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11996 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911997 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611998 return rv;
11999 }
12000
dchengb03027d2014-10-21 12:00:2012001 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4612002 host_resolver_.CancelRequest(req);
12003 }
12004
[email protected]46da33be2011-07-19 21:58:0412005 MockCachingHostResolver* GetMockHostResolver() {
12006 return &host_resolver_;
12007 }
12008
[email protected]e3ceb682011-06-28 23:55:4612009 private:
12010 MockCachingHostResolver host_resolver_;
12011 const HostPortPair host_port_;
12012};
12013
mmenke5c642132015-06-02 16:05:1312014TEST_P(HttpNetworkTransactionTest,
12015 UseIPConnectionPoolingWithHostCacheExpiration) {
bnc55ff9da2015-08-19 18:42:3512016 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2312017 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4612018
12019 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4612020 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3412021 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0712022 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4612023 params.host_resolver = &host_resolver;
mmenke6b3af6e2015-09-12 02:06:0612024 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612025 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12026 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612027
[email protected]8ddf8322012-02-23 18:08:0612028 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212029 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712030 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612031
[email protected]cdf8f7e72013-05-23 10:56:4612032 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2312033 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4612034 scoped_ptr<SpdyFrame> host2_req(
12035 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612036 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312037 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612038 };
[email protected]23e482282013-06-14 16:08:0212039 scoped_ptr<SpdyFrame> host1_resp(
12040 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12041 scoped_ptr<SpdyFrame> host1_resp_body(
12042 spdy_util_.ConstructSpdyBodyFrame(1, true));
12043 scoped_ptr<SpdyFrame> host2_resp(
12044 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12045 scoped_ptr<SpdyFrame> host2_resp_body(
12046 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612047 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312048 CreateMockRead(*host1_resp, 1),
12049 CreateMockRead(*host1_resp_body, 2),
12050 CreateMockRead(*host2_resp, 4),
12051 CreateMockRead(*host2_resp_body, 5),
12052 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612053 };
12054
[email protected]d2b5f092012-06-08 23:55:0212055 IPAddressNumber ip;
12056 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12057 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12058 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312059 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12060 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712061 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612062
[email protected]aa22b242011-11-16 18:58:2912063 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612064 HttpRequestInfo request1;
12065 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312066 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612067 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012068 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612069
[email protected]49639fa2011-12-20 23:22:4112070 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612071 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112072 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612073
12074 const HttpResponseInfo* response = trans1.GetResponseInfo();
12075 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012076 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612077 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12078
12079 std::string response_data;
12080 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12081 EXPECT_EQ("hello!", response_data);
12082
12083 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1012084 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4612085 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012086 rv = host_resolver.Resolve(resolve_info,
12087 DEFAULT_PRIORITY,
12088 &ignored,
12089 callback.callback(),
12090 NULL,
12091 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712092 EXPECT_EQ(ERR_IO_PENDING, rv);
12093 rv = callback.WaitForResult();
12094 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612095
12096 HttpRequestInfo request2;
12097 request2.method = "GET";
12098 request2.url = GURL("https://www.gmail.com/");
12099 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012100 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612101
[email protected]49639fa2011-12-20 23:22:4112102 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612103 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112104 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612105
12106 response = trans2.GetResponseInfo();
12107 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012108 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612109 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12110 EXPECT_TRUE(response->was_fetched_via_spdy);
12111 EXPECT_TRUE(response->was_npn_negotiated);
12112 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12113 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612114}
12115
[email protected]23e482282013-06-14 16:08:0212116TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2312117 const std::string https_url = "https://www.example.org:8080/";
12118 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412119
12120 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4612121 scoped_ptr<SpdyFrame> req1(
12122 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0412123
12124 MockWrite writes1[] = {
12125 CreateMockWrite(*req1, 0),
12126 };
12127
[email protected]23e482282013-06-14 16:08:0212128 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12129 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0412130 MockRead reads1[] = {
12131 CreateMockRead(*resp1, 1),
12132 CreateMockRead(*body1, 2),
12133 MockRead(ASYNC, ERR_IO_PENDING, 3)
12134 };
12135
rch8e6c6c42015-05-01 14:05:1312136 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
12137 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412138 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712139 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412140
12141 // HTTP GET for the HTTP URL
12142 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1312143 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3412144 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2312145 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3412146 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0412147 };
12148
12149 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1312150 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12151 MockRead(ASYNC, 2, "hello"),
12152 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0412153 };
12154
rch8e6c6c42015-05-01 14:05:1312155 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12156 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0412157
[email protected]8450d722012-07-02 19:14:0412158 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212159 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712160 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12161 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12162 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0412163
mmenke6b3af6e2015-09-12 02:06:0612164 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412165
12166 // Start the first transaction to set up the SpdySession
12167 HttpRequestInfo request1;
12168 request1.method = "GET";
12169 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412170 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012171 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412172 TestCompletionCallback callback1;
12173 EXPECT_EQ(ERR_IO_PENDING,
12174 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412175 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412176
12177 EXPECT_EQ(OK, callback1.WaitForResult());
12178 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12179
12180 // Now, start the HTTP request
12181 HttpRequestInfo request2;
12182 request2.method = "GET";
12183 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412184 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012185 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412186 TestCompletionCallback callback2;
12187 EXPECT_EQ(ERR_IO_PENDING,
12188 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412189 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412190
12191 EXPECT_EQ(OK, callback2.WaitForResult());
12192 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12193}
12194
bnc1b0e36852015-04-28 15:32:5912195class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
12196 public:
12197 void Run(bool pooling, bool valid) {
12198 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
12199 443);
12200 HostPortPair alternative("www.example.org", 443);
12201
12202 base::FilePath certs_dir = GetTestCertsDirectory();
12203 scoped_refptr<X509Certificate> cert(
12204 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
12205 ASSERT_TRUE(cert.get());
12206 bool common_name_fallback_used;
12207 EXPECT_EQ(valid,
12208 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
12209 EXPECT_TRUE(
12210 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
12211 SSLSocketDataProvider ssl(ASYNC, OK);
12212 ssl.SetNextProto(GetParam());
12213 ssl.cert = cert;
12214 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12215
12216 // If pooling, then start a request to alternative first to create a
12217 // SpdySession.
12218 std::string url0 = "https://www.example.org:443";
12219 // Second request to origin, which has an alternative service, and could
12220 // open a connection to the alternative host or pool to the existing one.
12221 std::string url1("https://");
12222 url1.append(origin.host());
12223 url1.append(":443");
12224
12225 scoped_ptr<SpdyFrame> req0;
12226 scoped_ptr<SpdyFrame> req1;
12227 scoped_ptr<SpdyFrame> resp0;
12228 scoped_ptr<SpdyFrame> body0;
12229 scoped_ptr<SpdyFrame> resp1;
12230 scoped_ptr<SpdyFrame> body1;
12231 std::vector<MockWrite> writes;
12232 std::vector<MockRead> reads;
12233
12234 if (pooling) {
12235 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
12236 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
12237
12238 writes.push_back(CreateMockWrite(*req0, 0));
12239 writes.push_back(CreateMockWrite(*req1, 3));
12240
12241 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12242 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12243 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12244 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
12245
12246 reads.push_back(CreateMockRead(*resp0, 1));
12247 reads.push_back(CreateMockRead(*body0, 2));
12248 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
12249 reads.push_back(CreateMockRead(*resp1, 5));
12250 reads.push_back(CreateMockRead(*body1, 6));
12251 reads.push_back(MockRead(ASYNC, OK, 7));
12252 } else {
12253 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
12254
12255 writes.push_back(CreateMockWrite(*req1, 0));
12256
12257 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12258 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12259
12260 reads.push_back(CreateMockRead(*resp1, 1));
12261 reads.push_back(CreateMockRead(*body1, 2));
12262 reads.push_back(MockRead(ASYNC, OK, 3));
12263 }
12264
rch32320842015-05-16 15:57:0912265 SequencedSocketData data(vector_as_array(&reads), reads.size(),
12266 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5912267 session_deps_.socket_factory->AddSocketDataProvider(&data);
12268
12269 // Connection to the origin fails.
12270 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12271 StaticSocketDataProvider data_refused;
12272 data_refused.set_connect_data(mock_connect);
12273 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12274
bnc55ff9da2015-08-19 18:42:3512275 session_deps_.use_alternative_services = true;
mmenke6b3af6e2015-09-12 02:06:0612276 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc1b0e36852015-04-28 15:32:5912277 base::WeakPtr<HttpServerProperties> http_server_properties =
12278 session->http_server_properties();
12279 AlternativeService alternative_service(
12280 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212281 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc1b0e36852015-04-28 15:32:5912282 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212283 1.0, expiration);
bnc1b0e36852015-04-28 15:32:5912284
12285 // First request to alternative.
12286 if (pooling) {
12287 scoped_ptr<HttpTransaction> trans0(
12288 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12289 HttpRequestInfo request0;
12290 request0.method = "GET";
12291 request0.url = GURL(url0);
12292 request0.load_flags = 0;
12293 TestCompletionCallback callback0;
12294
12295 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
12296 EXPECT_EQ(ERR_IO_PENDING, rv);
12297 rv = callback0.WaitForResult();
12298 EXPECT_EQ(OK, rv);
12299 }
12300
12301 // Second request to origin.
12302 scoped_ptr<HttpTransaction> trans1(
12303 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12304 HttpRequestInfo request1;
12305 request1.method = "GET";
12306 request1.url = GURL(url1);
12307 request1.load_flags = 0;
12308 TestCompletionCallback callback1;
12309
12310 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12311 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0912312 base::MessageLoop::current()->RunUntilIdle();
12313 if (data.IsReadPaused()) {
12314 data.CompleteRead();
12315 }
bnc1b0e36852015-04-28 15:32:5912316 rv = callback1.WaitForResult();
12317 if (valid) {
12318 EXPECT_EQ(OK, rv);
12319 } else {
12320 if (pooling) {
12321 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12322 } else {
12323 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
12324 }
12325 }
12326 }
12327};
12328
12329INSTANTIATE_TEST_CASE_P(NextProto,
12330 AltSvcCertificateVerificationTest,
12331 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:4312332 kProtoHTTP2));
bnc1b0e36852015-04-28 15:32:5912333
12334// The alternative service host must exhibit a certificate that is valid for the
12335// origin host. Test that this is enforced when pooling to an existing
12336// connection.
12337TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
12338 Run(true, true);
12339}
12340
12341TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
12342 Run(true, false);
12343}
12344
12345// The alternative service host must exhibit a certificate that is valid for the
12346// origin host. Test that this is enforced when opening a new connection.
12347TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
12348 Run(false, true);
12349}
12350
12351TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
12352 Run(false, false);
12353}
12354
bnc5452e2a2015-05-08 16:27:4212355// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
12356// with the alternative server. That connection should not be used.
12357TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
12358 HostPortPair origin("origin.example.org", 443);
12359 HostPortPair alternative("alternative.example.org", 443);
12360
12361 // Negotiate HTTP/1.1 with alternative.example.org.
12362 SSLSocketDataProvider ssl(ASYNC, OK);
12363 ssl.SetNextProto(kProtoHTTP11);
12364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12365
12366 // No data should be read from the alternative, because HTTP/1.1 is
12367 // negotiated.
12368 StaticSocketDataProvider data;
12369 session_deps_.socket_factory->AddSocketDataProvider(&data);
12370
12371 // This test documents that an alternate Job should not be used if HTTP/1.1 is
12372 // negotiated. In order to test this, a failed connection to the origin is
12373 // mocked. This way the request relies on the alternate Job.
12374 StaticSocketDataProvider data_refused;
12375 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12376 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12377
12378 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512379 session_deps_.use_alternative_services = true;
mmenke6b3af6e2015-09-12 02:06:0612380 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4212381 base::WeakPtr<HttpServerProperties> http_server_properties =
12382 session->http_server_properties();
12383 AlternativeService alternative_service(
12384 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212385 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212386 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212387 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212388
12389 scoped_ptr<HttpTransaction> trans(
12390 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12391 HttpRequestInfo request;
12392 request.method = "GET";
12393 request.url = GURL("https://origin.example.org:443");
12394 request.load_flags = 0;
12395 TestCompletionCallback callback;
12396
12397 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
12398 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
12399 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12400 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
12401}
12402
bnc40448a532015-05-11 19:13:1412403// A request to a server with an alternative service fires two Jobs: one to the
12404// origin, and an alternate one to the alternative server. If the former
12405// succeeds, the request should succeed, even if the latter fails because
12406// HTTP/1.1 is negotiated which is insufficient for alternative service.
12407TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
12408 HostPortPair origin("origin.example.org", 443);
12409 HostPortPair alternative("alternative.example.org", 443);
12410
12411 // Negotiate HTTP/1.1 with alternative.
12412 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
12413 alternative_ssl.SetNextProto(kProtoHTTP11);
12414 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
12415
12416 // No data should be read from the alternative, because HTTP/1.1 is
12417 // negotiated.
12418 StaticSocketDataProvider data;
12419 session_deps_.socket_factory->AddSocketDataProvider(&data);
12420
12421 // Negotiate HTTP/1.1 with origin.
12422 SSLSocketDataProvider origin_ssl(ASYNC, OK);
12423 origin_ssl.SetNextProto(kProtoHTTP11);
12424 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
12425
12426 MockWrite http_writes[] = {
12427 MockWrite(
12428 "GET / HTTP/1.1\r\n"
12429 "Host: origin.example.org\r\n"
12430 "Connection: keep-alive\r\n\r\n"),
12431 MockWrite(
12432 "GET /second HTTP/1.1\r\n"
12433 "Host: origin.example.org\r\n"
12434 "Connection: keep-alive\r\n\r\n"),
12435 };
12436
12437 MockRead http_reads[] = {
12438 MockRead("HTTP/1.1 200 OK\r\n"),
12439 MockRead("Content-Type: text/html\r\n"),
12440 MockRead("Content-Length: 6\r\n\r\n"),
12441 MockRead("foobar"),
12442 MockRead("HTTP/1.1 200 OK\r\n"),
12443 MockRead("Content-Type: text/html\r\n"),
12444 MockRead("Content-Length: 7\r\n\r\n"),
12445 MockRead("another"),
12446 };
12447 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12448 http_writes, arraysize(http_writes));
12449 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12450
12451 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512452 session_deps_.use_alternative_services = true;
mmenke6b3af6e2015-09-12 02:06:0612453 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc40448a532015-05-11 19:13:1412454 base::WeakPtr<HttpServerProperties> http_server_properties =
12455 session->http_server_properties();
12456 AlternativeService alternative_service(
12457 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212458 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc40448a532015-05-11 19:13:1412459 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212460 1.0, expiration);
bnc40448a532015-05-11 19:13:1412461
12462 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
12463 HttpRequestInfo request1;
12464 request1.method = "GET";
12465 request1.url = GURL("https://origin.example.org:443");
12466 request1.load_flags = 0;
12467 TestCompletionCallback callback1;
12468
12469 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
12470 rv = callback1.GetResult(rv);
12471 EXPECT_EQ(OK, rv);
12472
12473 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
12474 ASSERT_TRUE(response1 != nullptr);
12475 ASSERT_TRUE(response1->headers.get() != nullptr);
12476 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12477
12478 std::string response_data1;
12479 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
12480 EXPECT_EQ("foobar", response_data1);
12481
12482 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
12483 // for alternative service.
12484 EXPECT_TRUE(
12485 http_server_properties->IsAlternativeServiceBroken(alternative_service));
12486
12487 // Since |alternative_service| is broken, a second transaction to origin
12488 // should not start an alternate Job. It should pool to existing connection
12489 // to origin.
12490 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
12491 HttpRequestInfo request2;
12492 request2.method = "GET";
12493 request2.url = GURL("https://origin.example.org:443/second");
12494 request2.load_flags = 0;
12495 TestCompletionCallback callback2;
12496
12497 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
12498 rv = callback2.GetResult(rv);
12499 EXPECT_EQ(OK, rv);
12500
12501 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
12502 ASSERT_TRUE(response2 != nullptr);
12503 ASSERT_TRUE(response2->headers.get() != nullptr);
12504 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
12505
12506 std::string response_data2;
12507 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
12508 EXPECT_EQ("another", response_data2);
12509}
12510
bnc5452e2a2015-05-08 16:27:4212511// Alternative service requires HTTP/2 (or SPDY), but there is already a
12512// HTTP/1.1 socket open to the alternative server. That socket should not be
12513// used.
12514TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
12515 HostPortPair origin("origin.example.org", 443);
12516 HostPortPair alternative("alternative.example.org", 443);
12517 std::string origin_url = "https://origin.example.org:443";
12518 std::string alternative_url = "https://alternative.example.org:443";
12519
12520 // Negotiate HTTP/1.1 with alternative.example.org.
12521 SSLSocketDataProvider ssl(ASYNC, OK);
12522 ssl.SetNextProto(kProtoHTTP11);
12523 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12524
12525 // HTTP/1.1 data for |request1| and |request2|.
12526 MockWrite http_writes[] = {
12527 MockWrite(
12528 "GET / HTTP/1.1\r\n"
12529 "Host: alternative.example.org\r\n"
12530 "Connection: keep-alive\r\n\r\n"),
12531 MockWrite(
12532 "GET / HTTP/1.1\r\n"
12533 "Host: alternative.example.org\r\n"
12534 "Connection: keep-alive\r\n\r\n"),
12535 };
12536
12537 MockRead http_reads[] = {
12538 MockRead(
12539 "HTTP/1.1 200 OK\r\n"
12540 "Content-Type: text/html; charset=iso-8859-1\r\n"
12541 "Content-Length: 40\r\n\r\n"
12542 "first HTTP/1.1 response from alternative"),
12543 MockRead(
12544 "HTTP/1.1 200 OK\r\n"
12545 "Content-Type: text/html; charset=iso-8859-1\r\n"
12546 "Content-Length: 41\r\n\r\n"
12547 "second HTTP/1.1 response from alternative"),
12548 };
12549 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12550 http_writes, arraysize(http_writes));
12551 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12552
12553 // This test documents that an alternate Job should not pool to an already
12554 // existing HTTP/1.1 connection. In order to test this, a failed connection
12555 // to the origin is mocked. This way |request2| relies on the alternate Job.
12556 StaticSocketDataProvider data_refused;
12557 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12558 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12559
12560 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512561 session_deps_.use_alternative_services = true;
mmenke6b3af6e2015-09-12 02:06:0612562 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4212563 base::WeakPtr<HttpServerProperties> http_server_properties =
12564 session->http_server_properties();
12565 AlternativeService alternative_service(
12566 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212567 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212568 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212569 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212570
12571 // First transaction to alternative to open an HTTP/1.1 socket.
12572 scoped_ptr<HttpTransaction> trans1(
12573 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12574 HttpRequestInfo request1;
12575 request1.method = "GET";
12576 request1.url = GURL(alternative_url);
12577 request1.load_flags = 0;
12578 TestCompletionCallback callback1;
12579
12580 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12581 EXPECT_EQ(OK, callback1.GetResult(rv));
12582 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12583 ASSERT_TRUE(response1);
12584 ASSERT_TRUE(response1->headers.get());
12585 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12586 EXPECT_TRUE(response1->was_npn_negotiated);
12587 EXPECT_FALSE(response1->was_fetched_via_spdy);
12588 std::string response_data1;
12589 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
12590 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
12591
12592 // Request for origin.example.org, which has an alternative service. This
12593 // will start two Jobs: the alternative looks for connections to pool to,
12594 // finds one which is HTTP/1.1, and should ignore it, and should not try to
12595 // open other connections to alternative server. The Job to origin fails, so
12596 // this request fails.
12597 scoped_ptr<HttpTransaction> trans2(
12598 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12599 HttpRequestInfo request2;
12600 request2.method = "GET";
12601 request2.url = GURL(origin_url);
12602 request2.load_flags = 0;
12603 TestCompletionCallback callback2;
12604
12605 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
12606 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
12607
12608 // Another transaction to alternative. This is to test that the HTTP/1.1
12609 // socket is still open and in the pool.
12610 scoped_ptr<HttpTransaction> trans3(
12611 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12612 HttpRequestInfo request3;
12613 request3.method = "GET";
12614 request3.url = GURL(alternative_url);
12615 request3.load_flags = 0;
12616 TestCompletionCallback callback3;
12617
12618 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
12619 EXPECT_EQ(OK, callback3.GetResult(rv));
12620 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12621 ASSERT_TRUE(response3);
12622 ASSERT_TRUE(response3->headers.get());
12623 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
12624 EXPECT_TRUE(response3->was_npn_negotiated);
12625 EXPECT_FALSE(response3->was_fetched_via_spdy);
12626 std::string response_data3;
12627 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
12628 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
12629}
12630
[email protected]23e482282013-06-14 16:08:0212631TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2312632 const std::string https_url = "https://www.example.org:8080/";
12633 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412634
12635 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2312636 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3412637 scoped_ptr<SpdyFrame> connect(
12638 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4612639 scoped_ptr<SpdyFrame> req1(
12640 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0212641 scoped_ptr<SpdyFrame> wrapped_req1(
12642 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3912643
12644 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2912645 SpdyHeaderBlock req2_block;
bnc7ecc1122015-09-28 13:22:4912646 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]745aa9c2014-06-27 02:21:2912647 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2312648 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2912649 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4912650 req2_block[spdy_util_.GetPathKey()] = "/";
[email protected]601e03f12014-04-06 16:26:3912651 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2912652 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0412653
12654 MockWrite writes1[] = {
12655 CreateMockWrite(*connect, 0),
12656 CreateMockWrite(*wrapped_req1, 2),
12657 CreateMockWrite(*req2, 5),
12658 };
12659
[email protected]23e482282013-06-14 16:08:0212660 scoped_ptr<SpdyFrame> conn_resp(
12661 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12662 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12663 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
12664 scoped_ptr<SpdyFrame> wrapped_resp1(
12665 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
12666 scoped_ptr<SpdyFrame> wrapped_body1(
12667 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
12668 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12669 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0412670 MockRead reads1[] = {
12671 CreateMockRead(*conn_resp, 1),
12672 CreateMockRead(*wrapped_resp1, 3),
12673 CreateMockRead(*wrapped_body1, 4),
12674 CreateMockRead(*resp2, 6),
12675 CreateMockRead(*body2, 7),
12676 MockRead(ASYNC, ERR_IO_PENDING, 8)
12677 };
12678
[email protected]dd54bd82012-07-19 23:44:5712679 DeterministicSocketData data1(reads1, arraysize(reads1),
12680 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412681 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712682 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412683
rdsmith82957ad2015-09-16 19:42:0312684 session_deps_.proxy_service =
12685 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5112686 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712687 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0412688 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0212689 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712690 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0412691 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212692 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712693 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12694 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0412695
mmenke6b3af6e2015-09-12 02:06:0612696 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712697 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412698
12699 // Start the first transaction to set up the SpdySession
12700 HttpRequestInfo request1;
12701 request1.method = "GET";
12702 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412703 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012704 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412705 TestCompletionCallback callback1;
12706 EXPECT_EQ(ERR_IO_PENDING,
12707 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412708 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712709 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0412710
12711 EXPECT_EQ(OK, callback1.WaitForResult());
12712 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12713
[email protected]f6c63db52013-02-02 00:35:2212714 LoadTimingInfo load_timing_info1;
12715 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
12716 TestLoadTimingNotReusedWithPac(load_timing_info1,
12717 CONNECT_TIMING_HAS_SSL_TIMES);
12718
[email protected]8450d722012-07-02 19:14:0412719 // Now, start the HTTP request
12720 HttpRequestInfo request2;
12721 request2.method = "GET";
12722 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412723 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012724 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412725 TestCompletionCallback callback2;
12726 EXPECT_EQ(ERR_IO_PENDING,
12727 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412728 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712729 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0412730
12731 EXPECT_EQ(OK, callback2.WaitForResult());
12732 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2212733
12734 LoadTimingInfo load_timing_info2;
12735 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
12736 // The established SPDY sessions is considered reused by the HTTP request.
12737 TestLoadTimingReusedWithPac(load_timing_info2);
12738 // HTTP requests over a SPDY session should have a different connection
12739 // socket_log_id than requests over a tunnel.
12740 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0412741}
12742
[email protected]2d88e7d2012-07-19 17:55:1712743// Test that in the case where we have a SPDY session to a SPDY proxy
12744// that we do not pool other origins that resolve to the same IP when
12745// the certificate does not match the new origin.
12746// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0212747TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2312748 const std::string url1 = "http://www.example.org/";
12749 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1712750 const std::string ip_addr = "1.2.3.4";
12751
12752 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0212753 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2312754 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2912755 scoped_ptr<SpdyFrame> req1(
12756 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1712757
12758 MockWrite writes1[] = {
12759 CreateMockWrite(*req1, 0),
12760 };
12761
[email protected]23e482282013-06-14 16:08:0212762 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12763 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712764 MockRead reads1[] = {
bncb9e20fc62015-08-17 17:19:3712765 CreateMockRead(*resp1, 1),
12766 CreateMockRead(*body1, 2),
12767 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1712768 };
12769
12770 scoped_ptr<DeterministicSocketData> data1(
12771 new DeterministicSocketData(reads1, arraysize(reads1),
12772 writes1, arraysize(writes1)));
12773 IPAddressNumber ip;
12774 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
12775 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12776 MockConnect connect_data1(ASYNC, OK, peer_addr);
12777 data1->set_connect_data(connect_data1);
12778
12779 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4612780 scoped_ptr<SpdyFrame> req2(
12781 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1712782
12783 MockWrite writes2[] = {
12784 CreateMockWrite(*req2, 0),
12785 };
12786
[email protected]23e482282013-06-14 16:08:0212787 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12788 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712789 MockRead reads2[] = {
bncb9e20fc62015-08-17 17:19:3712790 CreateMockRead(*resp2, 1),
12791 CreateMockRead(*body2, 2),
12792 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1712793 };
12794
12795 scoped_ptr<DeterministicSocketData> data2(
12796 new DeterministicSocketData(reads2, arraysize(reads2),
12797 writes2, arraysize(writes2)));
12798 MockConnect connect_data2(ASYNC, OK);
12799 data2->set_connect_data(connect_data2);
12800
12801 // Set up a proxy config that sends HTTP requests to a proxy, and
12802 // all others direct.
12803 ProxyConfig proxy_config;
12804 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0712805 session_deps_.proxy_service.reset(new ProxyService(
csharrisonb7e3a082015-09-22 19:13:0412806 make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)), nullptr,
12807 NULL));
[email protected]2d88e7d2012-07-19 17:55:1712808
bncce36dca22015-04-21 22:11:2312809 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
12810 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1712811 // Load a valid cert. Note, that this does not need to
12812 // be valid for proxy because the MockSSLClientSocket does
12813 // not actually verify it. But SpdySession will use this
12814 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2312815 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12816 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0712817 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12818 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12819 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1712820
12821 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212822 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712823 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12824 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12825 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1712826
[email protected]bb88e1d32013-05-03 23:11:0712827 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2312828 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0712829 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1712830
mmenke6b3af6e2015-09-12 02:06:0612831 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712832 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1712833
12834 // Start the first transaction to set up the SpdySession
12835 HttpRequestInfo request1;
12836 request1.method = "GET";
12837 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1712838 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012839 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712840 TestCompletionCallback callback1;
12841 ASSERT_EQ(ERR_IO_PENDING,
12842 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
12843 data1->RunFor(3);
12844
12845 ASSERT_TRUE(callback1.have_result());
12846 EXPECT_EQ(OK, callback1.WaitForResult());
12847 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12848
12849 // Now, start the HTTP request
12850 HttpRequestInfo request2;
12851 request2.method = "GET";
12852 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1712853 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012854 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712855 TestCompletionCallback callback2;
12856 EXPECT_EQ(ERR_IO_PENDING,
12857 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412858 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1712859 data2->RunFor(3);
12860
12861 ASSERT_TRUE(callback2.have_result());
12862 EXPECT_EQ(OK, callback2.WaitForResult());
12863 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12864}
12865
[email protected]85f97342013-04-17 06:12:2412866// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12867// error) in SPDY session, removes the socket from pool and closes the SPDY
12868// session. Verify that new url's from the same HttpNetworkSession (and a new
12869// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212870TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2312871 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2412872
12873 MockRead reads1[] = {
12874 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12875 };
12876
mmenke11eb5152015-06-09 14:50:5012877 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2412878
[email protected]cdf8f7e72013-05-23 10:56:4612879 scoped_ptr<SpdyFrame> req2(
12880 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412881 MockWrite writes2[] = {
12882 CreateMockWrite(*req2, 0),
12883 };
12884
[email protected]23e482282013-06-14 16:08:0212885 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12886 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412887 MockRead reads2[] = {
12888 CreateMockRead(*resp2, 1),
12889 CreateMockRead(*body2, 2),
12890 MockRead(ASYNC, OK, 3) // EOF
12891 };
12892
mmenke11eb5152015-06-09 14:50:5012893 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12894 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2412895
[email protected]85f97342013-04-17 06:12:2412896 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212897 ssl1.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012898 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12899 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2412900
12901 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212902 ssl2.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012903 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12904 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2412905
mmenke6b3af6e2015-09-12 02:06:0612906 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5012907 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2412908
12909 // Start the first transaction to set up the SpdySession and verify that
12910 // connection was closed.
12911 HttpRequestInfo request1;
12912 request1.method = "GET";
12913 request1.url = GURL(https_url);
12914 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012915 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412916 TestCompletionCallback callback1;
12917 EXPECT_EQ(ERR_IO_PENDING,
12918 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412919 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
12920
12921 // Now, start the second request and make sure it succeeds.
12922 HttpRequestInfo request2;
12923 request2.method = "GET";
12924 request2.url = GURL(https_url);
12925 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012926 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412927 TestCompletionCallback callback2;
12928 EXPECT_EQ(ERR_IO_PENDING,
12929 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412930
mmenke11eb5152015-06-09 14:50:5012931 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2412932 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12933}
12934
[email protected]23e482282013-06-14 16:08:0212935TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2312936 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0312937 ClientSocketPoolManager::set_max_sockets_per_group(
12938 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12939 ClientSocketPoolManager::set_max_sockets_per_pool(
12940 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12941
12942 // Use two different hosts with different IPs so they don't get pooled.
12943 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
12944 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
mmenke6b3af6e2015-09-12 02:06:0612945 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0312946
12947 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212948 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312949 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212950 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312951 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12952 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12953
[email protected]cdf8f7e72013-05-23 10:56:4612954 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312955 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
12956 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1312957 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0312958 };
[email protected]23e482282013-06-14 16:08:0212959 scoped_ptr<SpdyFrame> host1_resp(
12960 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12961 scoped_ptr<SpdyFrame> host1_resp_body(
12962 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312963 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1312964 CreateMockRead(*host1_resp, 1),
12965 CreateMockRead(*host1_resp_body, 2),
12966 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312967 };
12968
rch8e6c6c42015-05-01 14:05:1312969 scoped_ptr<SequencedSocketData> spdy1_data(
12970 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
12971 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0312972 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
12973
[email protected]cdf8f7e72013-05-23 10:56:4612974 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312975 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
12976 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1312977 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0312978 };
[email protected]23e482282013-06-14 16:08:0212979 scoped_ptr<SpdyFrame> host2_resp(
12980 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12981 scoped_ptr<SpdyFrame> host2_resp_body(
12982 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312983 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1312984 CreateMockRead(*host2_resp, 1),
12985 CreateMockRead(*host2_resp_body, 2),
12986 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312987 };
12988
rch8e6c6c42015-05-01 14:05:1312989 scoped_ptr<SequencedSocketData> spdy2_data(
12990 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
12991 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0312992 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
12993
12994 MockWrite http_write[] = {
12995 MockWrite("GET / HTTP/1.1\r\n"
12996 "Host: www.a.com\r\n"
12997 "Connection: keep-alive\r\n\r\n"),
12998 };
12999
13000 MockRead http_read[] = {
13001 MockRead("HTTP/1.1 200 OK\r\n"),
13002 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13003 MockRead("Content-Length: 6\r\n\r\n"),
13004 MockRead("hello!"),
13005 };
13006 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
13007 http_write, arraysize(http_write));
13008 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13009
13010 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4013011 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5313012 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313013 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613014 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313015
13016 TestCompletionCallback callback;
13017 HttpRequestInfo request1;
13018 request1.method = "GET";
13019 request1.url = GURL("https://www.a.com/");
13020 request1.load_flags = 0;
13021 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5013022 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313023
13024 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
13025 EXPECT_EQ(ERR_IO_PENDING, rv);
13026 EXPECT_EQ(OK, callback.WaitForResult());
13027
13028 const HttpResponseInfo* response = trans->GetResponseInfo();
13029 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013030 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313031 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13032 EXPECT_TRUE(response->was_fetched_via_spdy);
13033 EXPECT_TRUE(response->was_npn_negotiated);
13034
13035 std::string response_data;
13036 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13037 EXPECT_EQ("hello!", response_data);
13038 trans.reset();
13039 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613040 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313041
13042 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4013043 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5313044 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313045 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613046 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313047 HttpRequestInfo request2;
13048 request2.method = "GET";
13049 request2.url = GURL("https://www.b.com/");
13050 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013051 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313052
13053 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
13054 EXPECT_EQ(ERR_IO_PENDING, rv);
13055 EXPECT_EQ(OK, callback.WaitForResult());
13056
13057 response = trans->GetResponseInfo();
13058 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013059 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313060 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13061 EXPECT_TRUE(response->was_fetched_via_spdy);
13062 EXPECT_TRUE(response->was_npn_negotiated);
13063 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13064 EXPECT_EQ("hello!", response_data);
13065 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613066 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313067 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613068 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313069
13070 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4013071 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5313072 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313073 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613074 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0313075 HttpRequestInfo request3;
13076 request3.method = "GET";
13077 request3.url = GURL("http://www.a.com/");
13078 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013079 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313080
13081 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
13082 EXPECT_EQ(ERR_IO_PENDING, rv);
13083 EXPECT_EQ(OK, callback.WaitForResult());
13084
13085 response = trans->GetResponseInfo();
13086 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013087 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313088 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13089 EXPECT_FALSE(response->was_fetched_via_spdy);
13090 EXPECT_FALSE(response->was_npn_negotiated);
13091 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13092 EXPECT_EQ("hello!", response_data);
13093 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613094 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313095 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613096 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313097}
13098
[email protected]79e1fd62013-06-20 06:50:0413099TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
13100 HttpRequestInfo request;
13101 request.method = "GET";
bncce36dca22015-04-21 22:11:2313102 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413103 request.load_flags = 0;
13104
mmenke6b3af6e2015-09-12 02:06:0613105 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413106 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113107 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413108
ttuttled9dbc652015-09-29 20:00:5913109 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413110 StaticSocketDataProvider data;
13111 data.set_connect_data(mock_connect);
13112 session_deps_.socket_factory->AddSocketDataProvider(&data);
13113
13114 TestCompletionCallback callback;
13115
13116 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13117 EXPECT_EQ(ERR_IO_PENDING, rv);
13118
13119 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5913120 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0413121
[email protected]79e1fd62013-06-20 06:50:0413122 // We don't care whether this succeeds or fails, but it shouldn't crash.
13123 HttpRequestHeaders request_headers;
13124 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713125
13126 ConnectionAttempts attempts;
13127 trans->GetConnectionAttempts(&attempts);
13128 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5913129 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
13130
13131 IPEndPoint endpoint;
13132 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
13133 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413134}
13135
13136TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
13137 HttpRequestInfo request;
13138 request.method = "GET";
bncce36dca22015-04-21 22:11:2313139 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413140 request.load_flags = 0;
13141
mmenke6b3af6e2015-09-12 02:06:0613142 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413143 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113144 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413145
ttuttled9dbc652015-09-29 20:00:5913146 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413147 StaticSocketDataProvider data;
13148 data.set_connect_data(mock_connect);
13149 session_deps_.socket_factory->AddSocketDataProvider(&data);
13150
13151 TestCompletionCallback callback;
13152
13153 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13154 EXPECT_EQ(ERR_IO_PENDING, rv);
13155
13156 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5913157 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0413158
[email protected]79e1fd62013-06-20 06:50:0413159 // We don't care whether this succeeds or fails, but it shouldn't crash.
13160 HttpRequestHeaders request_headers;
13161 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713162
13163 ConnectionAttempts attempts;
13164 trans->GetConnectionAttempts(&attempts);
13165 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5913166 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
13167
13168 IPEndPoint endpoint;
13169 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
13170 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413171}
13172
13173TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
13174 HttpRequestInfo request;
13175 request.method = "GET";
bncce36dca22015-04-21 22:11:2313176 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413177 request.load_flags = 0;
13178
mmenke6b3af6e2015-09-12 02:06:0613179 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413180 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113181 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413182
13183 MockWrite data_writes[] = {
13184 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13185 };
13186 MockRead data_reads[] = {
13187 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13188 };
13189
13190 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13191 data_writes, arraysize(data_writes));
13192 session_deps_.socket_factory->AddSocketDataProvider(&data);
13193
13194 TestCompletionCallback callback;
13195
13196 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13197 EXPECT_EQ(ERR_IO_PENDING, rv);
13198
13199 rv = callback.WaitForResult();
13200 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13201
[email protected]79e1fd62013-06-20 06:50:0413202 HttpRequestHeaders request_headers;
13203 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13204 EXPECT_TRUE(request_headers.HasHeader("Host"));
13205}
13206
13207TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
13208 HttpRequestInfo request;
13209 request.method = "GET";
bncce36dca22015-04-21 22:11:2313210 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413211 request.load_flags = 0;
13212
mmenke6b3af6e2015-09-12 02:06:0613213 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413214 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113215 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413216
13217 MockWrite data_writes[] = {
13218 MockWrite(ASYNC, ERR_CONNECTION_RESET),
13219 };
13220 MockRead data_reads[] = {
13221 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13222 };
13223
13224 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13225 data_writes, arraysize(data_writes));
13226 session_deps_.socket_factory->AddSocketDataProvider(&data);
13227
13228 TestCompletionCallback callback;
13229
13230 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13231 EXPECT_EQ(ERR_IO_PENDING, rv);
13232
13233 rv = callback.WaitForResult();
13234 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13235
[email protected]79e1fd62013-06-20 06:50:0413236 HttpRequestHeaders request_headers;
13237 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13238 EXPECT_TRUE(request_headers.HasHeader("Host"));
13239}
13240
13241TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
13242 HttpRequestInfo request;
13243 request.method = "GET";
bncce36dca22015-04-21 22:11:2313244 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413245 request.load_flags = 0;
13246
mmenke6b3af6e2015-09-12 02:06:0613247 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413248 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113249 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413250
13251 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313252 MockWrite(
13253 "GET / HTTP/1.1\r\n"
13254 "Host: www.example.org\r\n"
13255 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413256 };
13257 MockRead data_reads[] = {
13258 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
13259 };
13260
13261 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13262 data_writes, arraysize(data_writes));
13263 session_deps_.socket_factory->AddSocketDataProvider(&data);
13264
13265 TestCompletionCallback callback;
13266
13267 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13268 EXPECT_EQ(ERR_IO_PENDING, rv);
13269
13270 rv = callback.WaitForResult();
13271 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13272
[email protected]79e1fd62013-06-20 06:50:0413273 HttpRequestHeaders request_headers;
13274 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13275 EXPECT_TRUE(request_headers.HasHeader("Host"));
13276}
13277
13278TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
13279 HttpRequestInfo request;
13280 request.method = "GET";
bncce36dca22015-04-21 22:11:2313281 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413282 request.load_flags = 0;
13283
mmenke6b3af6e2015-09-12 02:06:0613284 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413285 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113286 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413287
13288 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313289 MockWrite(
13290 "GET / HTTP/1.1\r\n"
13291 "Host: www.example.org\r\n"
13292 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413293 };
13294 MockRead data_reads[] = {
13295 MockRead(ASYNC, ERR_CONNECTION_RESET),
13296 };
13297
13298 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13299 data_writes, arraysize(data_writes));
13300 session_deps_.socket_factory->AddSocketDataProvider(&data);
13301
13302 TestCompletionCallback callback;
13303
13304 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13305 EXPECT_EQ(ERR_IO_PENDING, rv);
13306
13307 rv = callback.WaitForResult();
13308 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13309
[email protected]79e1fd62013-06-20 06:50:0413310 HttpRequestHeaders request_headers;
13311 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13312 EXPECT_TRUE(request_headers.HasHeader("Host"));
13313}
13314
13315TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
13316 HttpRequestInfo request;
13317 request.method = "GET";
bncce36dca22015-04-21 22:11:2313318 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413319 request.load_flags = 0;
13320 request.extra_headers.SetHeader("X-Foo", "bar");
13321
mmenke6b3af6e2015-09-12 02:06:0613322 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413323 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113324 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413325
13326 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313327 MockWrite(
13328 "GET / HTTP/1.1\r\n"
13329 "Host: www.example.org\r\n"
13330 "Connection: keep-alive\r\n"
13331 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413332 };
13333 MockRead data_reads[] = {
13334 MockRead("HTTP/1.1 200 OK\r\n"
13335 "Content-Length: 5\r\n\r\n"
13336 "hello"),
13337 MockRead(ASYNC, ERR_UNEXPECTED),
13338 };
13339
13340 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13341 data_writes, arraysize(data_writes));
13342 session_deps_.socket_factory->AddSocketDataProvider(&data);
13343
13344 TestCompletionCallback callback;
13345
13346 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13347 EXPECT_EQ(ERR_IO_PENDING, rv);
13348
13349 rv = callback.WaitForResult();
13350 EXPECT_EQ(OK, rv);
13351
13352 HttpRequestHeaders request_headers;
13353 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13354 std::string foo;
13355 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
13356 EXPECT_EQ("bar", foo);
13357}
13358
[email protected]bf828982013-08-14 18:01:4713359namespace {
13360
yhiranoa7e05bb2014-11-06 05:40:3913361// Fake HttpStream that simply records calls to SetPriority().
13362class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0313363 public base::SupportsWeakPtr<FakeStream> {
13364 public:
13365 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2013366 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0313367
13368 RequestPriority priority() const { return priority_; }
13369
dchengb03027d2014-10-21 12:00:2013370 int InitializeStream(const HttpRequestInfo* request_info,
13371 RequestPriority priority,
13372 const BoundNetLog& net_log,
13373 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313374 return ERR_IO_PENDING;
13375 }
13376
dchengb03027d2014-10-21 12:00:2013377 int SendRequest(const HttpRequestHeaders& request_headers,
13378 HttpResponseInfo* response,
13379 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313380 ADD_FAILURE();
13381 return ERR_UNEXPECTED;
13382 }
13383
dchengb03027d2014-10-21 12:00:2013384 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313385 ADD_FAILURE();
13386 return ERR_UNEXPECTED;
13387 }
13388
dchengb03027d2014-10-21 12:00:2013389 int ReadResponseBody(IOBuffer* buf,
13390 int buf_len,
13391 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313392 ADD_FAILURE();
13393 return ERR_UNEXPECTED;
13394 }
13395
dchengb03027d2014-10-21 12:00:2013396 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0313397
dchengb03027d2014-10-21 12:00:2013398 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0313399 ADD_FAILURE();
13400 return false;
13401 }
13402
dchengb03027d2014-10-21 12:00:2013403 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0313404 ADD_FAILURE();
13405 return false;
13406 }
13407
dchengb03027d2014-10-21 12:00:2013408 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313409
mmenkebd84c392015-09-02 14:12:3413410 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0313411
sclittle4de1bab92015-09-22 21:28:2413412 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5913413 ADD_FAILURE();
13414 return 0;
13415 }
13416
sclittlebe1ccf62015-09-02 19:40:3613417 int64_t GetTotalSentBytes() const override {
13418 ADD_FAILURE();
13419 return 0;
13420 }
13421
dchengb03027d2014-10-21 12:00:2013422 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0313423 ADD_FAILURE();
13424 return false;
13425 }
13426
dchengb03027d2014-10-21 12:00:2013427 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
13428
13429 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0313430 ADD_FAILURE();
13431 }
13432
ttuttled9dbc652015-09-29 20:00:5913433 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
13434
dchengb03027d2014-10-21 12:00:2013435 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313436
dchengb03027d2014-10-21 12:00:2013437 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0313438
yhiranoa7e05bb2014-11-06 05:40:3913439 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
13440
13441 HttpStream* RenewStreamForAuth() override { return NULL; }
13442
[email protected]e86839fd2013-08-14 18:29:0313443 private:
13444 RequestPriority priority_;
13445
13446 DISALLOW_COPY_AND_ASSIGN(FakeStream);
13447};
13448
13449// Fake HttpStreamRequest that simply records calls to SetPriority()
13450// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4713451class FakeStreamRequest : public HttpStreamRequest,
13452 public base::SupportsWeakPtr<FakeStreamRequest> {
13453 public:
[email protected]e86839fd2013-08-14 18:29:0313454 FakeStreamRequest(RequestPriority priority,
13455 HttpStreamRequest::Delegate* delegate)
13456 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4413457 delegate_(delegate),
13458 websocket_stream_create_helper_(NULL) {}
13459
13460 FakeStreamRequest(RequestPriority priority,
13461 HttpStreamRequest::Delegate* delegate,
13462 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
13463 : priority_(priority),
13464 delegate_(delegate),
13465 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0313466
dchengb03027d2014-10-21 12:00:2013467 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4713468
13469 RequestPriority priority() const { return priority_; }
13470
[email protected]831e4a32013-11-14 02:14:4413471 const WebSocketHandshakeStreamBase::CreateHelper*
13472 websocket_stream_create_helper() const {
13473 return websocket_stream_create_helper_;
13474 }
13475
[email protected]e86839fd2013-08-14 18:29:0313476 // Create a new FakeStream and pass it to the request's
13477 // delegate. Returns a weak pointer to the FakeStream.
13478 base::WeakPtr<FakeStream> FinishStreamRequest() {
13479 FakeStream* fake_stream = new FakeStream(priority_);
13480 // Do this before calling OnStreamReady() as OnStreamReady() may
13481 // immediately delete |fake_stream|.
13482 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
13483 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
13484 return weak_stream;
13485 }
13486
dchengb03027d2014-10-21 12:00:2013487 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4713488 ADD_FAILURE();
13489 return ERR_UNEXPECTED;
13490 }
13491
dchengb03027d2014-10-21 12:00:2013492 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4713493 ADD_FAILURE();
13494 return LoadState();
13495 }
13496
dchengb03027d2014-10-21 12:00:2013497 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4713498
dchengb03027d2014-10-21 12:00:2013499 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713500
dchengb03027d2014-10-21 12:00:2013501 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4713502
dchengb03027d2014-10-21 12:00:2013503 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713504
ttuttle1f2d7e92015-04-28 16:17:4713505 const ConnectionAttempts& connection_attempts() const override {
13506 static ConnectionAttempts no_attempts;
13507 return no_attempts;
13508 }
13509
[email protected]bf828982013-08-14 18:01:4713510 private:
13511 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0313512 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4413513 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4713514
13515 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
13516};
13517
13518// Fake HttpStreamFactory that vends FakeStreamRequests.
13519class FakeStreamFactory : public HttpStreamFactory {
13520 public:
13521 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2013522 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4713523
13524 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
13525 // RequestStream() (which may be NULL if it was destroyed already).
13526 base::WeakPtr<FakeStreamRequest> last_stream_request() {
13527 return last_stream_request_;
13528 }
13529
dchengb03027d2014-10-21 12:00:2013530 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
13531 RequestPriority priority,
13532 const SSLConfig& server_ssl_config,
13533 const SSLConfig& proxy_ssl_config,
13534 HttpStreamRequest::Delegate* delegate,
13535 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0313536 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4713537 last_stream_request_ = fake_request->AsWeakPtr();
13538 return fake_request;
13539 }
13540
dchengb03027d2014-10-21 12:00:2013541 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4713542 const HttpRequestInfo& info,
13543 RequestPriority priority,
13544 const SSLConfig& server_ssl_config,
13545 const SSLConfig& proxy_ssl_config,
13546 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4613547 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1313548 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4413549 FakeStreamRequest* fake_request =
13550 new FakeStreamRequest(priority, delegate, create_helper);
13551 last_stream_request_ = fake_request->AsWeakPtr();
13552 return fake_request;
[email protected]bf828982013-08-14 18:01:4713553 }
13554
dchengb03027d2014-10-21 12:00:2013555 void PreconnectStreams(int num_streams,
13556 const HttpRequestInfo& info,
dchengb03027d2014-10-21 12:00:2013557 const SSLConfig& server_ssl_config,
13558 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4713559 ADD_FAILURE();
13560 }
13561
dchengb03027d2014-10-21 12:00:2013562 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4713563 ADD_FAILURE();
13564 return NULL;
13565 }
13566
13567 private:
13568 base::WeakPtr<FakeStreamRequest> last_stream_request_;
13569
13570 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
13571};
13572
Adam Rice425cf122015-01-19 06:18:2413573// TODO(ricea): Maybe unify this with the one in
13574// url_request_http_job_unittest.cc ?
13575class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
13576 public:
13577 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
13578 bool using_proxy)
13579 : state_(connection.release(), using_proxy) {}
13580
13581 // Fake implementation of HttpStreamBase methods.
13582 // This ends up being quite "real" because this object has to really send data
13583 // on the mock socket. It might be easier to use the real implementation, but
13584 // the fact that the WebSocket code is not compiled on iOS makes that
13585 // difficult.
13586 int InitializeStream(const HttpRequestInfo* request_info,
13587 RequestPriority priority,
13588 const BoundNetLog& net_log,
13589 const CompletionCallback& callback) override {
13590 state_.Initialize(request_info, priority, net_log, callback);
13591 return OK;
13592 }
13593
13594 int SendRequest(const HttpRequestHeaders& request_headers,
13595 HttpResponseInfo* response,
13596 const CompletionCallback& callback) override {
13597 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
13598 response, callback);
13599 }
13600
13601 int ReadResponseHeaders(const CompletionCallback& callback) override {
13602 return parser()->ReadResponseHeaders(callback);
13603 }
13604
13605 int ReadResponseBody(IOBuffer* buf,
13606 int buf_len,
13607 const CompletionCallback& callback) override {
13608 NOTREACHED();
13609 return ERR_IO_PENDING;
13610 }
13611
13612 void Close(bool not_reusable) override {
13613 if (parser())
13614 parser()->Close(true);
13615 }
13616
13617 bool IsResponseBodyComplete() const override {
13618 NOTREACHED();
13619 return false;
13620 }
13621
Adam Rice425cf122015-01-19 06:18:2413622 bool IsConnectionReused() const override {
13623 NOTREACHED();
13624 return false;
13625 }
13626 void SetConnectionReused() override { NOTREACHED(); }
13627
mmenkebd84c392015-09-02 14:12:3413628 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2413629
sclittle4de1bab92015-09-22 21:28:2413630 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2413631 NOTREACHED();
13632 return 0;
13633 }
13634
sclittlebe1ccf62015-09-02 19:40:3613635 int64_t GetTotalSentBytes() const override {
13636 NOTREACHED();
13637 return 0;
13638 }
13639
Adam Rice425cf122015-01-19 06:18:2413640 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
13641 NOTREACHED();
13642 return false;
13643 }
13644
Adam Ricecb76ac62015-02-20 05:33:2513645 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2413646
13647 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
13648 NOTREACHED();
13649 }
13650
ttuttled9dbc652015-09-29 20:00:5913651 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
13652
Adam Rice425cf122015-01-19 06:18:2413653 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
13654
13655 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
13656
13657 UploadProgress GetUploadProgress() const override {
13658 NOTREACHED();
13659 return UploadProgress();
13660 }
13661
13662 HttpStream* RenewStreamForAuth() override {
13663 NOTREACHED();
13664 return nullptr;
13665 }
13666
13667 // Fake implementation of WebSocketHandshakeStreamBase method(s)
13668 scoped_ptr<WebSocketStream> Upgrade() override {
13669 NOTREACHED();
13670 return scoped_ptr<WebSocketStream>();
13671 }
13672
13673 private:
13674 HttpStreamParser* parser() const { return state_.parser(); }
13675 HttpBasicState state_;
13676
13677 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
13678};
13679
[email protected]831e4a32013-11-14 02:14:4413680// TODO(yhirano): Split this class out into a net/websockets file, if it is
13681// worth doing.
13682class FakeWebSocketStreamCreateHelper :
13683 public WebSocketHandshakeStreamBase::CreateHelper {
13684 public:
dchengb03027d2014-10-21 12:00:2013685 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2113686 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1313687 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2413688 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
13689 using_proxy);
[email protected]831e4a32013-11-14 02:14:4413690 }
13691
dchengb03027d2014-10-21 12:00:2013692 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4413693 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1313694 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4413695 NOTREACHED();
13696 return NULL;
13697 };
13698
dchengb03027d2014-10-21 12:00:2013699 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4413700
13701 virtual scoped_ptr<WebSocketStream> Upgrade() {
13702 NOTREACHED();
13703 return scoped_ptr<WebSocketStream>();
13704 }
13705};
13706
[email protected]bf828982013-08-14 18:01:4713707} // namespace
13708
13709// Make sure that HttpNetworkTransaction passes on its priority to its
13710// stream request on start.
13711TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
mmenke6b3af6e2015-09-12 02:06:0613712 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13713 HttpNetworkSessionPeer peer(session);
[email protected]bf828982013-08-14 18:01:4713714 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413715 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713716
dcheng48459ac22014-08-26 00:46:4113717 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713718
13719 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
13720
13721 HttpRequestInfo request;
13722 TestCompletionCallback callback;
13723 EXPECT_EQ(ERR_IO_PENDING,
13724 trans.Start(&request, callback.callback(), BoundNetLog()));
13725
13726 base::WeakPtr<FakeStreamRequest> fake_request =
13727 fake_factory->last_stream_request();
13728 ASSERT_TRUE(fake_request != NULL);
13729 EXPECT_EQ(LOW, fake_request->priority());
13730}
13731
13732// Make sure that HttpNetworkTransaction passes on its priority
13733// updates to its stream request.
13734TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
mmenke6b3af6e2015-09-12 02:06:0613735 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13736 HttpNetworkSessionPeer peer(session);
[email protected]bf828982013-08-14 18:01:4713737 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413738 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713739
dcheng48459ac22014-08-26 00:46:4113740 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713741
13742 HttpRequestInfo request;
13743 TestCompletionCallback callback;
13744 EXPECT_EQ(ERR_IO_PENDING,
13745 trans.Start(&request, callback.callback(), BoundNetLog()));
13746
13747 base::WeakPtr<FakeStreamRequest> fake_request =
13748 fake_factory->last_stream_request();
13749 ASSERT_TRUE(fake_request != NULL);
13750 EXPECT_EQ(LOW, fake_request->priority());
13751
13752 trans.SetPriority(LOWEST);
13753 ASSERT_TRUE(fake_request != NULL);
13754 EXPECT_EQ(LOWEST, fake_request->priority());
13755}
13756
[email protected]e86839fd2013-08-14 18:29:0313757// Make sure that HttpNetworkTransaction passes on its priority
13758// updates to its stream.
13759TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
mmenke6b3af6e2015-09-12 02:06:0613760 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13761 HttpNetworkSessionPeer peer(session);
[email protected]e86839fd2013-08-14 18:29:0313762 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413763 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0313764
dcheng48459ac22014-08-26 00:46:4113765 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0313766
13767 HttpRequestInfo request;
13768 TestCompletionCallback callback;
13769 EXPECT_EQ(ERR_IO_PENDING,
13770 trans.Start(&request, callback.callback(), BoundNetLog()));
13771
13772 base::WeakPtr<FakeStreamRequest> fake_request =
13773 fake_factory->last_stream_request();
13774 ASSERT_TRUE(fake_request != NULL);
13775 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
13776 ASSERT_TRUE(fake_stream != NULL);
13777 EXPECT_EQ(LOW, fake_stream->priority());
13778
13779 trans.SetPriority(LOWEST);
13780 EXPECT_EQ(LOWEST, fake_stream->priority());
13781}
13782
[email protected]831e4a32013-11-14 02:14:4413783TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
13784 // The same logic needs to be tested for both ws: and wss: schemes, but this
13785 // test is already parameterised on NextProto, so it uses a loop to verify
13786 // that the different schemes work.
bncce36dca22015-04-21 22:11:2313787 std::string test_cases[] = {"ws://www.example.org/",
13788 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4413789 for (size_t i = 0; i < arraysize(test_cases); ++i) {
mmenke6b3af6e2015-09-12 02:06:0613790 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13791 HttpNetworkSessionPeer peer(session);
[email protected]831e4a32013-11-14 02:14:4413792 FakeStreamFactory* fake_factory = new FakeStreamFactory();
13793 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2313794 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4413795 scoped_ptr<HttpStreamFactory>(fake_factory));
13796
dcheng48459ac22014-08-26 00:46:4113797 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4413798 trans.SetWebSocketHandshakeStreamCreateHelper(
13799 &websocket_stream_create_helper);
13800
13801 HttpRequestInfo request;
13802 TestCompletionCallback callback;
13803 request.method = "GET";
13804 request.url = GURL(test_cases[i]);
13805
13806 EXPECT_EQ(ERR_IO_PENDING,
13807 trans.Start(&request, callback.callback(), BoundNetLog()));
13808
13809 base::WeakPtr<FakeStreamRequest> fake_request =
13810 fake_factory->last_stream_request();
13811 ASSERT_TRUE(fake_request != NULL);
13812 EXPECT_EQ(&websocket_stream_create_helper,
13813 fake_request->websocket_stream_create_helper());
13814 }
13815}
13816
[email protected]043b68c82013-08-22 23:41:5213817// Tests that when a used socket is returned to the SSL socket pool, it's closed
13818// if the transport socket pool is stalled on the global socket limit.
13819TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
13820 ClientSocketPoolManager::set_max_sockets_per_group(
13821 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13822 ClientSocketPoolManager::set_max_sockets_per_pool(
13823 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13824
13825 // Set up SSL request.
13826
13827 HttpRequestInfo ssl_request;
13828 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2313829 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213830
13831 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2313832 MockWrite(
13833 "GET / HTTP/1.1\r\n"
13834 "Host: www.example.org\r\n"
13835 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213836 };
13837 MockRead ssl_reads[] = {
13838 MockRead("HTTP/1.1 200 OK\r\n"),
13839 MockRead("Content-Length: 11\r\n\r\n"),
13840 MockRead("hello world"),
13841 MockRead(SYNCHRONOUS, OK),
13842 };
13843 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
13844 ssl_writes, arraysize(ssl_writes));
13845 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13846
13847 SSLSocketDataProvider ssl(ASYNC, OK);
13848 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13849
13850 // Set up HTTP request.
13851
13852 HttpRequestInfo http_request;
13853 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313854 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213855
13856 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313857 MockWrite(
13858 "GET / HTTP/1.1\r\n"
13859 "Host: www.example.org\r\n"
13860 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213861 };
13862 MockRead http_reads[] = {
13863 MockRead("HTTP/1.1 200 OK\r\n"),
13864 MockRead("Content-Length: 7\r\n\r\n"),
13865 MockRead("falafel"),
13866 MockRead(SYNCHRONOUS, OK),
13867 };
13868 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13869 http_writes, arraysize(http_writes));
13870 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13871
mmenke6b3af6e2015-09-12 02:06:0613872 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5213873
13874 // Start the SSL request.
13875 TestCompletionCallback ssl_callback;
13876 scoped_ptr<HttpTransaction> ssl_trans(
13877 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13878 ASSERT_EQ(ERR_IO_PENDING,
13879 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13880 BoundNetLog()));
13881
13882 // Start the HTTP request. Pool should stall.
13883 TestCompletionCallback http_callback;
13884 scoped_ptr<HttpTransaction> http_trans(
13885 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13886 ASSERT_EQ(ERR_IO_PENDING,
13887 http_trans->Start(&http_request, http_callback.callback(),
13888 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113889 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213890
13891 // Wait for response from SSL request.
13892 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13893 std::string response_data;
13894 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13895 EXPECT_EQ("hello world", response_data);
13896
13897 // The SSL socket should automatically be closed, so the HTTP request can
13898 // start.
dcheng48459ac22014-08-26 00:46:4113899 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13900 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213901
13902 // The HTTP request can now complete.
13903 ASSERT_EQ(OK, http_callback.WaitForResult());
13904 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13905 EXPECT_EQ("falafel", response_data);
13906
dcheng48459ac22014-08-26 00:46:4113907 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213908}
13909
13910// Tests that when a SSL connection is established but there's no corresponding
13911// request that needs it, the new socket is closed if the transport socket pool
13912// is stalled on the global socket limit.
13913TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
13914 ClientSocketPoolManager::set_max_sockets_per_group(
13915 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13916 ClientSocketPoolManager::set_max_sockets_per_pool(
13917 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13918
13919 // Set up an ssl request.
13920
13921 HttpRequestInfo ssl_request;
13922 ssl_request.method = "GET";
13923 ssl_request.url = GURL("https://www.foopy.com/");
13924
13925 // No data will be sent on the SSL socket.
13926 StaticSocketDataProvider ssl_data;
13927 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13928
13929 SSLSocketDataProvider ssl(ASYNC, OK);
13930 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13931
13932 // Set up HTTP request.
13933
13934 HttpRequestInfo http_request;
13935 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313936 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213937
13938 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313939 MockWrite(
13940 "GET / HTTP/1.1\r\n"
13941 "Host: www.example.org\r\n"
13942 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213943 };
13944 MockRead http_reads[] = {
13945 MockRead("HTTP/1.1 200 OK\r\n"),
13946 MockRead("Content-Length: 7\r\n\r\n"),
13947 MockRead("falafel"),
13948 MockRead(SYNCHRONOUS, OK),
13949 };
13950 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13951 http_writes, arraysize(http_writes));
13952 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13953
mmenke6b3af6e2015-09-12 02:06:0613954 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5213955
13956 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
13957 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2913958 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
13959 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5213960 session->ssl_config_service()->GetSSLConfig(&ssl_config);
mmenked1205bd3972015-07-15 22:26:3513961 http_stream_factory->PreconnectStreams(1, ssl_request, ssl_config,
13962 ssl_config);
dcheng48459ac22014-08-26 00:46:4113963 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213964
13965 // Start the HTTP request. Pool should stall.
13966 TestCompletionCallback http_callback;
13967 scoped_ptr<HttpTransaction> http_trans(
13968 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13969 ASSERT_EQ(ERR_IO_PENDING,
13970 http_trans->Start(&http_request, http_callback.callback(),
13971 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113972 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213973
13974 // The SSL connection will automatically be closed once the connection is
13975 // established, to let the HTTP request start.
13976 ASSERT_EQ(OK, http_callback.WaitForResult());
13977 std::string response_data;
13978 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13979 EXPECT_EQ("falafel", response_data);
13980
dcheng48459ac22014-08-26 00:46:4113981 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213982}
13983
[email protected]02d74a02014-04-23 18:10:5413984TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
13985 ScopedVector<UploadElementReader> element_readers;
13986 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713987 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413988
13989 HttpRequestInfo request;
13990 request.method = "POST";
13991 request.url = GURL("http://www.foo.com/");
13992 request.upload_data_stream = &upload_data_stream;
13993 request.load_flags = 0;
13994
mmenke6b3af6e2015-09-12 02:06:0613995 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5413996 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113997 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413998 // Send headers successfully, but get an error while sending the body.
13999 MockWrite data_writes[] = {
14000 MockWrite("POST / HTTP/1.1\r\n"
14001 "Host: www.foo.com\r\n"
14002 "Connection: keep-alive\r\n"
14003 "Content-Length: 3\r\n\r\n"),
14004 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14005 };
14006
14007 MockRead data_reads[] = {
14008 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14009 MockRead("hello world"),
14010 MockRead(SYNCHRONOUS, OK),
14011 };
14012 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14013 arraysize(data_writes));
14014 session_deps_.socket_factory->AddSocketDataProvider(&data);
14015
14016 TestCompletionCallback callback;
14017
14018 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14019 EXPECT_EQ(ERR_IO_PENDING, rv);
14020
14021 rv = callback.WaitForResult();
14022 EXPECT_EQ(OK, rv);
14023
14024 const HttpResponseInfo* response = trans->GetResponseInfo();
14025 ASSERT_TRUE(response != NULL);
14026
14027 EXPECT_TRUE(response->headers.get() != NULL);
14028 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14029
14030 std::string response_data;
14031 rv = ReadTransaction(trans.get(), &response_data);
14032 EXPECT_EQ(OK, rv);
14033 EXPECT_EQ("hello world", response_data);
14034}
14035
14036// This test makes sure the retry logic doesn't trigger when reading an error
14037// response from a server that rejected a POST with a CONNECTION_RESET.
14038TEST_P(HttpNetworkTransactionTest,
14039 PostReadsErrorResponseAfterResetOnReusedSocket) {
mmenke6b3af6e2015-09-12 02:06:0614040 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414041 MockWrite data_writes[] = {
14042 MockWrite("GET / HTTP/1.1\r\n"
14043 "Host: www.foo.com\r\n"
14044 "Connection: keep-alive\r\n\r\n"),
14045 MockWrite("POST / HTTP/1.1\r\n"
14046 "Host: www.foo.com\r\n"
14047 "Connection: keep-alive\r\n"
14048 "Content-Length: 3\r\n\r\n"),
14049 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14050 };
14051
14052 MockRead data_reads[] = {
14053 MockRead("HTTP/1.1 200 Peachy\r\n"
14054 "Content-Length: 14\r\n\r\n"),
14055 MockRead("first response"),
14056 MockRead("HTTP/1.1 400 Not OK\r\n"
14057 "Content-Length: 15\r\n\r\n"),
14058 MockRead("second response"),
14059 MockRead(SYNCHRONOUS, OK),
14060 };
14061 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14062 arraysize(data_writes));
14063 session_deps_.socket_factory->AddSocketDataProvider(&data);
14064
14065 TestCompletionCallback callback;
14066 HttpRequestInfo request1;
14067 request1.method = "GET";
14068 request1.url = GURL("http://www.foo.com/");
14069 request1.load_flags = 0;
14070
14071 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4114072 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414073 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
14074 EXPECT_EQ(ERR_IO_PENDING, rv);
14075
14076 rv = callback.WaitForResult();
14077 EXPECT_EQ(OK, rv);
14078
14079 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
14080 ASSERT_TRUE(response1 != NULL);
14081
14082 EXPECT_TRUE(response1->headers.get() != NULL);
14083 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
14084
14085 std::string response_data1;
14086 rv = ReadTransaction(trans1.get(), &response_data1);
14087 EXPECT_EQ(OK, rv);
14088 EXPECT_EQ("first response", response_data1);
14089 // Delete the transaction to release the socket back into the socket pool.
14090 trans1.reset();
14091
14092 ScopedVector<UploadElementReader> element_readers;
14093 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714094 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414095
14096 HttpRequestInfo request2;
14097 request2.method = "POST";
14098 request2.url = GURL("http://www.foo.com/");
14099 request2.upload_data_stream = &upload_data_stream;
14100 request2.load_flags = 0;
14101
14102 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4114103 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414104 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
14105 EXPECT_EQ(ERR_IO_PENDING, rv);
14106
14107 rv = callback.WaitForResult();
14108 EXPECT_EQ(OK, rv);
14109
14110 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
14111 ASSERT_TRUE(response2 != NULL);
14112
14113 EXPECT_TRUE(response2->headers.get() != NULL);
14114 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
14115
14116 std::string response_data2;
14117 rv = ReadTransaction(trans2.get(), &response_data2);
14118 EXPECT_EQ(OK, rv);
14119 EXPECT_EQ("second response", response_data2);
14120}
14121
14122TEST_P(HttpNetworkTransactionTest,
14123 PostReadsErrorResponseAfterResetPartialBodySent) {
14124 ScopedVector<UploadElementReader> element_readers;
14125 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714126 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414127
14128 HttpRequestInfo request;
14129 request.method = "POST";
14130 request.url = GURL("http://www.foo.com/");
14131 request.upload_data_stream = &upload_data_stream;
14132 request.load_flags = 0;
14133
mmenke6b3af6e2015-09-12 02:06:0614134 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414135 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114136 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414137 // Send headers successfully, but get an error while sending the body.
14138 MockWrite data_writes[] = {
14139 MockWrite("POST / HTTP/1.1\r\n"
14140 "Host: www.foo.com\r\n"
14141 "Connection: keep-alive\r\n"
14142 "Content-Length: 3\r\n\r\n"
14143 "fo"),
14144 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14145 };
14146
14147 MockRead data_reads[] = {
14148 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14149 MockRead("hello world"),
14150 MockRead(SYNCHRONOUS, OK),
14151 };
14152 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14153 arraysize(data_writes));
14154 session_deps_.socket_factory->AddSocketDataProvider(&data);
14155
14156 TestCompletionCallback callback;
14157
14158 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14159 EXPECT_EQ(ERR_IO_PENDING, rv);
14160
14161 rv = callback.WaitForResult();
14162 EXPECT_EQ(OK, rv);
14163
14164 const HttpResponseInfo* response = trans->GetResponseInfo();
14165 ASSERT_TRUE(response != NULL);
14166
14167 EXPECT_TRUE(response->headers.get() != NULL);
14168 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14169
14170 std::string response_data;
14171 rv = ReadTransaction(trans.get(), &response_data);
14172 EXPECT_EQ(OK, rv);
14173 EXPECT_EQ("hello world", response_data);
14174}
14175
14176// This tests the more common case than the previous test, where headers and
14177// body are not merged into a single request.
14178TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
14179 ScopedVector<UploadElementReader> element_readers;
14180 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714181 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5414182
14183 HttpRequestInfo request;
14184 request.method = "POST";
14185 request.url = GURL("http://www.foo.com/");
14186 request.upload_data_stream = &upload_data_stream;
14187 request.load_flags = 0;
14188
mmenke6b3af6e2015-09-12 02:06:0614189 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414190 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114191 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414192 // Send headers successfully, but get an error while sending the body.
14193 MockWrite data_writes[] = {
14194 MockWrite("POST / HTTP/1.1\r\n"
14195 "Host: www.foo.com\r\n"
14196 "Connection: keep-alive\r\n"
14197 "Transfer-Encoding: chunked\r\n\r\n"),
14198 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14199 };
14200
14201 MockRead data_reads[] = {
14202 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14203 MockRead("hello world"),
14204 MockRead(SYNCHRONOUS, OK),
14205 };
14206 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14207 arraysize(data_writes));
14208 session_deps_.socket_factory->AddSocketDataProvider(&data);
14209
14210 TestCompletionCallback callback;
14211
14212 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14213 EXPECT_EQ(ERR_IO_PENDING, rv);
14214 // Make sure the headers are sent before adding a chunk. This ensures that
14215 // they can't be merged with the body in a single send. Not currently
14216 // necessary since a chunked body is never merged with headers, but this makes
14217 // the test more future proof.
14218 base::RunLoop().RunUntilIdle();
14219
mmenkecbc2b712014-10-09 20:29:0714220 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5414221
14222 rv = callback.WaitForResult();
14223 EXPECT_EQ(OK, rv);
14224
14225 const HttpResponseInfo* response = trans->GetResponseInfo();
14226 ASSERT_TRUE(response != NULL);
14227
14228 EXPECT_TRUE(response->headers.get() != NULL);
14229 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14230
14231 std::string response_data;
14232 rv = ReadTransaction(trans.get(), &response_data);
14233 EXPECT_EQ(OK, rv);
14234 EXPECT_EQ("hello world", response_data);
14235}
14236
14237TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
14238 ScopedVector<UploadElementReader> element_readers;
14239 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714240 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414241
14242 HttpRequestInfo request;
14243 request.method = "POST";
14244 request.url = GURL("http://www.foo.com/");
14245 request.upload_data_stream = &upload_data_stream;
14246 request.load_flags = 0;
14247
mmenke6b3af6e2015-09-12 02:06:0614248 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414249 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114250 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414251
14252 MockWrite data_writes[] = {
14253 MockWrite("POST / HTTP/1.1\r\n"
14254 "Host: www.foo.com\r\n"
14255 "Connection: keep-alive\r\n"
14256 "Content-Length: 3\r\n\r\n"),
14257 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14258 };
14259
14260 MockRead data_reads[] = {
14261 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14262 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14263 MockRead("hello world"),
14264 MockRead(SYNCHRONOUS, OK),
14265 };
14266 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14267 arraysize(data_writes));
14268 session_deps_.socket_factory->AddSocketDataProvider(&data);
14269
14270 TestCompletionCallback callback;
14271
14272 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14273 EXPECT_EQ(ERR_IO_PENDING, rv);
14274
14275 rv = callback.WaitForResult();
14276 EXPECT_EQ(OK, rv);
14277
14278 const HttpResponseInfo* response = trans->GetResponseInfo();
14279 ASSERT_TRUE(response != NULL);
14280
14281 EXPECT_TRUE(response->headers.get() != NULL);
14282 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14283
14284 std::string response_data;
14285 rv = ReadTransaction(trans.get(), &response_data);
14286 EXPECT_EQ(OK, rv);
14287 EXPECT_EQ("hello world", response_data);
14288}
14289
14290TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
14291 ScopedVector<UploadElementReader> element_readers;
14292 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714293 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414294
14295 HttpRequestInfo request;
14296 request.method = "POST";
14297 request.url = GURL("http://www.foo.com/");
14298 request.upload_data_stream = &upload_data_stream;
14299 request.load_flags = 0;
14300
mmenke6b3af6e2015-09-12 02:06:0614301 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414302 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114303 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414304 // Send headers successfully, but get an error while sending the body.
14305 MockWrite data_writes[] = {
14306 MockWrite("POST / HTTP/1.1\r\n"
14307 "Host: www.foo.com\r\n"
14308 "Connection: keep-alive\r\n"
14309 "Content-Length: 3\r\n\r\n"),
14310 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14311 };
14312
14313 MockRead data_reads[] = {
14314 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
14315 MockRead("hello world"),
14316 MockRead(SYNCHRONOUS, OK),
14317 };
14318 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14319 arraysize(data_writes));
14320 session_deps_.socket_factory->AddSocketDataProvider(&data);
14321
14322 TestCompletionCallback callback;
14323
14324 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14325 EXPECT_EQ(ERR_IO_PENDING, rv);
14326
14327 rv = callback.WaitForResult();
14328 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414329}
14330
14331TEST_P(HttpNetworkTransactionTest,
14332 PostIgnoresNonErrorResponseAfterResetAnd100) {
14333 ScopedVector<UploadElementReader> element_readers;
14334 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714335 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414336
14337 HttpRequestInfo request;
14338 request.method = "POST";
14339 request.url = GURL("http://www.foo.com/");
14340 request.upload_data_stream = &upload_data_stream;
14341 request.load_flags = 0;
14342
mmenke6b3af6e2015-09-12 02:06:0614343 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414344 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114345 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414346 // Send headers successfully, but get an error while sending the body.
14347 MockWrite data_writes[] = {
14348 MockWrite("POST / HTTP/1.1\r\n"
14349 "Host: www.foo.com\r\n"
14350 "Connection: keep-alive\r\n"
14351 "Content-Length: 3\r\n\r\n"),
14352 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14353 };
14354
14355 MockRead data_reads[] = {
14356 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14357 MockRead("HTTP/1.0 302 Redirect\r\n"),
14358 MockRead("Location: http://somewhere-else.com/\r\n"),
14359 MockRead("Content-Length: 0\r\n\r\n"),
14360 MockRead(SYNCHRONOUS, OK),
14361 };
14362 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14363 arraysize(data_writes));
14364 session_deps_.socket_factory->AddSocketDataProvider(&data);
14365
14366 TestCompletionCallback callback;
14367
14368 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14369 EXPECT_EQ(ERR_IO_PENDING, rv);
14370
14371 rv = callback.WaitForResult();
14372 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414373}
14374
14375TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
14376 ScopedVector<UploadElementReader> element_readers;
14377 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714378 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414379
14380 HttpRequestInfo request;
14381 request.method = "POST";
14382 request.url = GURL("http://www.foo.com/");
14383 request.upload_data_stream = &upload_data_stream;
14384 request.load_flags = 0;
14385
mmenke6b3af6e2015-09-12 02:06:0614386 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414387 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114388 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414389 // Send headers successfully, but get an error while sending the body.
14390 MockWrite data_writes[] = {
14391 MockWrite("POST / HTTP/1.1\r\n"
14392 "Host: www.foo.com\r\n"
14393 "Connection: keep-alive\r\n"
14394 "Content-Length: 3\r\n\r\n"),
14395 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14396 };
14397
14398 MockRead data_reads[] = {
14399 MockRead("HTTP 0.9 rocks!"),
14400 MockRead(SYNCHRONOUS, OK),
14401 };
14402 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14403 arraysize(data_writes));
14404 session_deps_.socket_factory->AddSocketDataProvider(&data);
14405
14406 TestCompletionCallback callback;
14407
14408 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14409 EXPECT_EQ(ERR_IO_PENDING, rv);
14410
14411 rv = callback.WaitForResult();
14412 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414413}
14414
14415TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
14416 ScopedVector<UploadElementReader> element_readers;
14417 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714418 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414419
14420 HttpRequestInfo request;
14421 request.method = "POST";
14422 request.url = GURL("http://www.foo.com/");
14423 request.upload_data_stream = &upload_data_stream;
14424 request.load_flags = 0;
14425
mmenke6b3af6e2015-09-12 02:06:0614426 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414427 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114428 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414429 // Send headers successfully, but get an error while sending the body.
14430 MockWrite data_writes[] = {
14431 MockWrite("POST / HTTP/1.1\r\n"
14432 "Host: www.foo.com\r\n"
14433 "Connection: keep-alive\r\n"
14434 "Content-Length: 3\r\n\r\n"),
14435 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14436 };
14437
14438 MockRead data_reads[] = {
14439 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
14440 MockRead(SYNCHRONOUS, OK),
14441 };
14442 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14443 arraysize(data_writes));
14444 session_deps_.socket_factory->AddSocketDataProvider(&data);
14445
14446 TestCompletionCallback callback;
14447
14448 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14449 EXPECT_EQ(ERR_IO_PENDING, rv);
14450
14451 rv = callback.WaitForResult();
14452 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414453}
14454
Adam Rice425cf122015-01-19 06:18:2414455// Verify that proxy headers are not sent to the destination server when
14456// establishing a tunnel for a secure WebSocket connection.
14457TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
14458 HttpRequestInfo request;
14459 request.method = "GET";
bncce36dca22015-04-21 22:11:2314460 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414461 AddWebSocketHeaders(&request.extra_headers);
14462
14463 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0314464 session_deps_.proxy_service =
14465 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2414466
mmenke6b3af6e2015-09-12 02:06:0614467 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2414468
14469 // Since a proxy is configured, try to establish a tunnel.
14470 MockWrite data_writes[] = {
14471 MockWrite(
bncce36dca22015-04-21 22:11:2314472 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14473 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414474 "Proxy-Connection: keep-alive\r\n\r\n"),
14475
14476 // After calling trans->RestartWithAuth(), this is the request we should
14477 // be issuing -- the final header line contains the credentials.
14478 MockWrite(
bncce36dca22015-04-21 22:11:2314479 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14480 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414481 "Proxy-Connection: keep-alive\r\n"
14482 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14483
14484 MockWrite(
14485 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314486 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414487 "Connection: Upgrade\r\n"
14488 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314489 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414490 "Sec-WebSocket-Version: 13\r\n"
14491 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14492 };
14493
14494 // The proxy responds to the connect with a 407, using a persistent
14495 // connection.
14496 MockRead data_reads[] = {
14497 // No credentials.
14498 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
14499 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenke0fd148d2015-09-30 23:00:0814500 MockRead("Proxy-Connection: close\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2414501
14502 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14503
14504 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14505 MockRead("Upgrade: websocket\r\n"),
14506 MockRead("Connection: Upgrade\r\n"),
14507 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14508 };
14509
14510 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14511 arraysize(data_writes));
14512 session_deps_.socket_factory->AddSocketDataProvider(&data);
14513 SSLSocketDataProvider ssl(ASYNC, OK);
14514 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14515
14516 scoped_ptr<HttpTransaction> trans(
14517 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14518 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14519 trans->SetWebSocketHandshakeStreamCreateHelper(
14520 &websocket_stream_create_helper);
14521
14522 {
14523 TestCompletionCallback callback;
14524
14525 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14526 EXPECT_EQ(ERR_IO_PENDING, rv);
14527
14528 rv = callback.WaitForResult();
14529 EXPECT_EQ(OK, rv);
14530 }
14531
14532 const HttpResponseInfo* response = trans->GetResponseInfo();
14533 ASSERT_TRUE(response);
14534 ASSERT_TRUE(response->headers.get());
14535 EXPECT_EQ(407, response->headers->response_code());
14536
14537 {
14538 TestCompletionCallback callback;
14539
14540 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
14541 callback.callback());
14542 EXPECT_EQ(ERR_IO_PENDING, rv);
14543
14544 rv = callback.WaitForResult();
14545 EXPECT_EQ(OK, rv);
14546 }
14547
14548 response = trans->GetResponseInfo();
14549 ASSERT_TRUE(response);
14550 ASSERT_TRUE(response->headers.get());
14551
14552 EXPECT_EQ(101, response->headers->response_code());
14553
14554 trans.reset();
14555 session->CloseAllConnections();
14556}
14557
14558// Verify that proxy headers are not sent to the destination server when
14559// establishing a tunnel for an insecure WebSocket connection.
14560// This requires the authentication info to be injected into the auth cache
14561// due to crbug.com/395064
14562// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
14563TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
14564 HttpRequestInfo request;
14565 request.method = "GET";
bncce36dca22015-04-21 22:11:2314566 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414567 AddWebSocketHeaders(&request.extra_headers);
14568
14569 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0314570 session_deps_.proxy_service =
14571 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2414572
mmenke6b3af6e2015-09-12 02:06:0614573 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2414574
14575 MockWrite data_writes[] = {
14576 // Try to establish a tunnel for the WebSocket connection, with
14577 // credentials. Because WebSockets have a separate set of socket pools,
14578 // they cannot and will not use the same TCP/IP connection as the
14579 // preflight HTTP request.
14580 MockWrite(
bncce36dca22015-04-21 22:11:2314581 "CONNECT www.example.org:80 HTTP/1.1\r\n"
14582 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2414583 "Proxy-Connection: keep-alive\r\n"
14584 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14585
14586 MockWrite(
14587 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314588 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414589 "Connection: Upgrade\r\n"
14590 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314591 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414592 "Sec-WebSocket-Version: 13\r\n"
14593 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14594 };
14595
14596 MockRead data_reads[] = {
14597 // HTTP CONNECT with credentials.
14598 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14599
14600 // WebSocket connection established inside tunnel.
14601 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14602 MockRead("Upgrade: websocket\r\n"),
14603 MockRead("Connection: Upgrade\r\n"),
14604 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14605 };
14606
14607 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14608 arraysize(data_writes));
14609 session_deps_.socket_factory->AddSocketDataProvider(&data);
14610
14611 session->http_auth_cache()->Add(
14612 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
14613 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
14614
14615 scoped_ptr<HttpTransaction> trans(
14616 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14617 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14618 trans->SetWebSocketHandshakeStreamCreateHelper(
14619 &websocket_stream_create_helper);
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 const HttpResponseInfo* response = trans->GetResponseInfo();
14630 ASSERT_TRUE(response);
14631 ASSERT_TRUE(response->headers.get());
14632
14633 EXPECT_EQ(101, response->headers->response_code());
14634
14635 trans.reset();
14636 session->CloseAllConnections();
14637}
14638
sclittlefb249892015-09-10 21:33:2214639TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
14640 ScopedVector<UploadElementReader> element_readers;
14641 element_readers.push_back(new UploadBytesElementReader("foo", 3));
14642 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
14643
14644 HttpRequestInfo request;
14645 request.method = "POST";
14646 request.url = GURL("http://www.foo.com/");
14647 request.upload_data_stream = &upload_data_stream;
14648
mmenke6b3af6e2015-09-12 02:06:0614649 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2214650 scoped_ptr<HttpTransaction> trans(
14651 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14652 MockWrite data_writes[] = {
14653 MockWrite("POST / HTTP/1.1\r\n"
14654 "Host: www.foo.com\r\n"
14655 "Connection: keep-alive\r\n"
14656 "Content-Length: 3\r\n\r\n"),
14657 MockWrite("foo"),
14658 };
14659
14660 MockRead data_reads[] = {
14661 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
14662 MockRead(SYNCHRONOUS, OK),
14663 };
14664 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14665 arraysize(data_writes));
14666 session_deps_.socket_factory->AddSocketDataProvider(&data);
14667
14668 TestCompletionCallback callback;
14669
14670 EXPECT_EQ(ERR_IO_PENDING,
14671 trans->Start(&request, callback.callback(), BoundNetLog()));
14672 EXPECT_EQ(OK, callback.WaitForResult());
14673
14674 std::string response_data;
14675 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14676
14677 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
14678 trans->GetTotalSentBytes());
14679 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
14680 trans->GetTotalReceivedBytes());
14681}
14682
14683TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
14684 ScopedVector<UploadElementReader> element_readers;
14685 element_readers.push_back(new UploadBytesElementReader("foo", 3));
14686 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
14687
14688 HttpRequestInfo request;
14689 request.method = "POST";
14690 request.url = GURL("http://www.foo.com/");
14691 request.upload_data_stream = &upload_data_stream;
14692
mmenke6b3af6e2015-09-12 02:06:0614693 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2214694 scoped_ptr<HttpTransaction> trans(
14695 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14696 MockWrite data_writes[] = {
14697 MockWrite("POST / HTTP/1.1\r\n"
14698 "Host: www.foo.com\r\n"
14699 "Connection: keep-alive\r\n"
14700 "Content-Length: 3\r\n\r\n"),
14701 MockWrite("foo"),
14702 };
14703
14704 MockRead data_reads[] = {
14705 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
14706 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
14707 MockRead(SYNCHRONOUS, OK),
14708 };
14709 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14710 arraysize(data_writes));
14711 session_deps_.socket_factory->AddSocketDataProvider(&data);
14712
14713 TestCompletionCallback callback;
14714
14715 EXPECT_EQ(ERR_IO_PENDING,
14716 trans->Start(&request, callback.callback(), BoundNetLog()));
14717 EXPECT_EQ(OK, callback.WaitForResult());
14718
14719 std::string response_data;
14720 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14721
14722 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
14723 trans->GetTotalSentBytes());
14724 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
14725 trans->GetTotalReceivedBytes());
14726}
14727
14728TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
14729 ScopedVector<UploadElementReader> element_readers;
14730 element_readers.push_back(new UploadBytesElementReader("foo", 3));
14731 ChunkedUploadDataStream upload_data_stream(0);
14732
14733 HttpRequestInfo request;
14734 request.method = "POST";
14735 request.url = GURL("http://www.foo.com/");
14736 request.upload_data_stream = &upload_data_stream;
14737
mmenke6b3af6e2015-09-12 02:06:0614738 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2214739 scoped_ptr<HttpTransaction> trans(
14740 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14741 // Send headers successfully, but get an error while sending the body.
14742 MockWrite data_writes[] = {
14743 MockWrite("POST / HTTP/1.1\r\n"
14744 "Host: www.foo.com\r\n"
14745 "Connection: keep-alive\r\n"
14746 "Transfer-Encoding: chunked\r\n\r\n"),
14747 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
14748 };
14749
14750 MockRead data_reads[] = {
14751 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
14752 MockRead(SYNCHRONOUS, OK),
14753 };
14754 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14755 arraysize(data_writes));
14756 session_deps_.socket_factory->AddSocketDataProvider(&data);
14757
14758 TestCompletionCallback callback;
14759
14760 EXPECT_EQ(ERR_IO_PENDING,
14761 trans->Start(&request, callback.callback(), BoundNetLog()));
14762
14763 base::RunLoop().RunUntilIdle();
14764 upload_data_stream.AppendData("f", 1, false);
14765
14766 base::RunLoop().RunUntilIdle();
14767 upload_data_stream.AppendData("oo", 2, true);
14768
14769 EXPECT_EQ(OK, callback.WaitForResult());
14770
14771 std::string response_data;
14772 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14773
14774 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
14775 trans->GetTotalSentBytes());
14776 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
14777 trans->GetTotalReceivedBytes());
14778}
14779
[email protected]89ceba9a2009-03-21 03:46:0614780} // namespace net