blob: c9014a47254a36249b27e1593a76521d394d0ec2 [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
mmenkee65e7af2015-10-13 17:16:42235scoped_ptr<HttpNetworkSession> CreateSession(
236 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34237 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14238}
239
[email protected]448d4ca52012-03-04 04:12:23240} // namespace
241
[email protected]23e482282013-06-14 16:08:02242class HttpNetworkTransactionTest
243 : public PlatformTest,
244 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03245 public:
[email protected]23e482282013-06-14 16:08:02246 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03247 // Important to restore the per-pool limit first, since the pool limit must
248 // always be greater than group limit, and the tests reduce both limits.
249 ClientSocketPoolManager::set_max_sockets_per_pool(
250 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
251 ClientSocketPoolManager::set_max_sockets_per_group(
252 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
253 }
254
[email protected]e3ceb682011-06-28 23:55:46255 protected:
[email protected]23e482282013-06-14 16:08:02256 HttpNetworkTransactionTest()
257 : spdy_util_(GetParam()),
258 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03259 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
260 HttpNetworkSession::NORMAL_SOCKET_POOL)),
261 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
262 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
263 }
[email protected]bb88e1d32013-05-03 23:11:07264
[email protected]e3ceb682011-06-28 23:55:46265 struct SimpleGetHelperResult {
266 int rv;
267 std::string status_line;
268 std::string response_data;
sclittlefb249892015-09-10 21:33:22269 int64_t total_received_bytes;
270 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25271 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47272 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59273 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46274 };
275
dcheng67be2b1f2014-10-27 21:47:29276 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50277 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34278 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54279 }
280
dcheng67be2b1f2014-10-27 21:47:29281 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50282 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34283 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09284 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34285 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09286 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50287 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34288 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09289 }
290
bnc33b8cef42014-11-19 17:30:38291 const char* GetAlternateProtocolFromParam() {
292 return
293 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam()));
294 }
295
bncc958faa2015-07-31 18:14:52296 std::string GetAlternativeServiceHttpHeader() {
297 return std::string("Alt-Svc: ") + GetAlternateProtocolFromParam() +
298 "=\"www.example.com:443\"\r\n";
299 }
300
[email protected]8a0fc822013-06-27 20:52:43301 std::string GetAlternateProtocolHttpHeader() {
bnc33b8cef42014-11-19 17:30:38302 return std::string("Alternate-Protocol: 443:") +
bncc958faa2015-07-31 18:14:52303 GetAlternateProtocolFromParam() + "\r\n";
[email protected]8a0fc822013-06-27 20:52:43304 }
305
[email protected]202965992011-12-07 23:04:51306 // Either |write_failure| specifies a write failure or |read_failure|
307 // specifies a read failure when using a reused socket. In either case, the
308 // failure should cause the network transaction to resend the request, and the
309 // other argument should be NULL.
310 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
311 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52312
[email protected]a34f61ee2014-03-18 20:59:49313 // Either |write_failure| specifies a write failure or |read_failure|
314 // specifies a read failure when using a reused socket. In either case, the
315 // failure should cause the network transaction to resend the request, and the
316 // other argument should be NULL.
317 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10318 const MockRead* read_failure,
319 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49320
[email protected]5a60c8b2011-10-19 20:14:29321 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
322 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15323 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52324
[email protected]ff007e162009-05-23 09:13:15325 HttpRequestInfo request;
326 request.method = "GET";
bncce36dca22015-04-21 22:11:23327 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15328 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52329
vishal.b62985ca92015-04-17 08:45:51330 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07331 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:42332 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27333 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41334 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27335
[email protected]5a60c8b2011-10-19 20:14:29336 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07337 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29338 }
initial.commit586acc5fe2008-07-26 22:42:52339
[email protected]49639fa2011-12-20 23:22:41340 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52341
eroman24bc6a12015-05-06 19:55:48342 EXPECT_TRUE(log.bound().IsCapturing());
[email protected]49639fa2011-12-20 23:22:41343 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15344 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52345
[email protected]ff007e162009-05-23 09:13:15346 out.rv = callback.WaitForResult();
sclittlefb249892015-09-10 21:33:22347 out.total_received_bytes = trans->GetTotalReceivedBytes();
348 out.total_sent_bytes = trans->GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25349
350 // Even in the failure cases that use this function, connections are always
351 // successfully established before the error.
352 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
353 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
354
[email protected]ff007e162009-05-23 09:13:15355 if (out.rv != OK)
356 return out;
357
358 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50359 // Can't use ASSERT_* inside helper functions like this, so
360 // return an error.
[email protected]90499482013-06-01 00:39:50361 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50362 out.rv = ERR_UNEXPECTED;
363 return out;
364 }
[email protected]ff007e162009-05-23 09:13:15365 out.status_line = response->headers->GetStatusLine();
366
[email protected]80a09a82012-11-16 17:40:06367 EXPECT_EQ("127.0.0.1", response->socket_address.host());
368 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19369
ttuttled9dbc652015-09-29 20:00:59370 bool got_endpoint =
371 trans->GetRemoteEndpoint(&out.remote_endpoint_after_start);
372 EXPECT_EQ(got_endpoint,
373 out.remote_endpoint_after_start.address().size() > 0);
374
[email protected]ff007e162009-05-23 09:13:15375 rv = ReadTransaction(trans.get(), &out.response_data);
376 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40377
mmenke43758e62015-05-04 21:09:46378 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40379 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39380 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40381 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12382 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39383 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40384 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39385 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
386 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15387
[email protected]f3da152d2012-06-02 01:00:57388 std::string line;
389 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
390 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
391
[email protected]79e1fd62013-06-20 06:50:04392 HttpRequestHeaders request_headers;
393 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
394 std::string value;
395 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23396 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04397 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
398 EXPECT_EQ("keep-alive", value);
399
400 std::string response_headers;
401 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23402 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04403 response_headers);
[email protected]3deb9a52010-11-11 00:24:40404
sclittlefb249892015-09-10 21:33:22405 out.total_received_bytes = trans->GetTotalReceivedBytes();
406 // The total number of sent bytes should not have changed.
407 EXPECT_EQ(out.total_sent_bytes, trans->GetTotalSentBytes());
408
ttuttle1f2d7e92015-04-28 16:17:47409 trans->GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47410 return out;
[email protected]ff007e162009-05-23 09:13:15411 }
initial.commit586acc5fe2008-07-26 22:42:52412
[email protected]5a60c8b2011-10-19 20:14:29413 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
414 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22415 MockWrite data_writes[] = {
416 MockWrite("GET / HTTP/1.1\r\n"
417 "Host: www.example.org\r\n"
418 "Connection: keep-alive\r\n\r\n"),
419 };
[email protected]5a60c8b2011-10-19 20:14:29420
sclittlefb249892015-09-10 21:33:22421 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
422 arraysize(data_writes));
423 StaticSocketDataProvider* data[] = {&reads};
424 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
425
426 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
427 out.total_sent_bytes);
428 return out;
[email protected]b8015c42013-12-24 15:18:19429 }
430
[email protected]ff007e162009-05-23 09:13:15431 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
432 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52433
[email protected]ff007e162009-05-23 09:13:15434 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07435
436 void BypassHostCacheOnRefreshHelper(int load_flags);
437
438 void CheckErrorIsPassedBack(int error, IoMode mode);
439
[email protected]4bd46222013-05-14 19:32:23440 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07441 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03442
443 // Original socket limits. Some tests set these. Safest to always restore
444 // them once each test has been run.
445 int old_max_group_sockets_;
446 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15447};
[email protected]231d5a32008-09-13 00:45:27448
bnc57685ae62015-03-10 21:27:20449INSTANTIATE_TEST_CASE_P(NextProto,
450 HttpNetworkTransactionTest,
451 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:43452 kProtoHTTP2));
[email protected]23e482282013-06-14 16:08:02453
[email protected]448d4ca52012-03-04 04:12:23454namespace {
455
[email protected]1826a402014-01-08 15:40:48456class BeforeNetworkStartHandler {
457 public:
458 explicit BeforeNetworkStartHandler(bool defer)
459 : defer_on_before_network_start_(defer),
460 observed_before_network_start_(false) {}
461
462 void OnBeforeNetworkStart(bool* defer) {
463 *defer = defer_on_before_network_start_;
464 observed_before_network_start_ = true;
465 }
466
467 bool observed_before_network_start() const {
468 return observed_before_network_start_;
469 }
470
471 private:
472 const bool defer_on_before_network_start_;
473 bool observed_before_network_start_;
474
475 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
476};
477
[email protected]597a1ab2014-06-26 08:12:27478class BeforeProxyHeadersSentHandler {
479 public:
480 BeforeProxyHeadersSentHandler()
481 : observed_before_proxy_headers_sent_(false) {}
482
[email protected]1252d42f2014-07-01 21:20:20483 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
484 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27485 observed_before_proxy_headers_sent_ = true;
486 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
487 }
488
489 bool observed_before_proxy_headers_sent() const {
490 return observed_before_proxy_headers_sent_;
491 }
492
493 std::string observed_proxy_server_uri() const {
494 return observed_proxy_server_uri_;
495 }
496
497 private:
498 bool observed_before_proxy_headers_sent_;
499 std::string observed_proxy_server_uri_;
500
501 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
502};
503
[email protected]15a5ccf82008-10-23 19:57:43504// Fill |str| with a long header list that consumes >= |size| bytes.
505void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51506 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19507 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
508 const int sizeof_row = strlen(row);
509 const int num_rows = static_cast<int>(
510 ceil(static_cast<float>(size) / sizeof_row));
511 const int sizeof_data = num_rows * sizeof_row;
512 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43513 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51514
[email protected]4ddaf2502008-10-23 18:26:19515 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43516 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19517}
518
thakis84dff942015-07-28 20:47:38519#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29520// Alternative functions that eliminate randomness and dependency on the local
521// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20522void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29523 static const uint8 bytes[] = {
524 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
525 };
526 static size_t current_byte = 0;
527 for (size_t i = 0; i < n; ++i) {
528 output[i] = bytes[current_byte++];
529 current_byte %= arraysize(bytes);
530 }
531}
532
[email protected]fe2bc6a2009-03-23 16:52:20533void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29534 static const uint8 bytes[] = {
535 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
536 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
537 };
538 static size_t current_byte = 0;
539 for (size_t i = 0; i < n; ++i) {
540 output[i] = bytes[current_byte++];
541 current_byte %= arraysize(bytes);
542 }
543}
544
[email protected]fe2bc6a2009-03-23 16:52:20545std::string MockGetHostName() {
546 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29547}
thakis84dff942015-07-28 20:47:38548#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29549
[email protected]e60e47a2010-07-14 03:37:18550template<typename ParentPool>
551class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31552 public:
[email protected]9e1bdd32011-02-03 21:48:34553 CaptureGroupNameSocketPool(HostResolver* host_resolver,
554 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18555
[email protected]d80a4322009-08-14 07:07:49556 const std::string last_group_name_received() const {
557 return last_group_name_;
558 }
559
dmichaeld6e570d2014-12-18 22:30:57560 int RequestSocket(const std::string& group_name,
561 const void* socket_params,
562 RequestPriority priority,
563 ClientSocketHandle* handle,
564 const CompletionCallback& callback,
565 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31566 last_group_name_ = group_name;
567 return ERR_IO_PENDING;
568 }
dmichaeld6e570d2014-12-18 22:30:57569 void CancelRequest(const std::string& group_name,
570 ClientSocketHandle* handle) override {}
571 void ReleaseSocket(const std::string& group_name,
572 scoped_ptr<StreamSocket> socket,
573 int id) override {}
574 void CloseIdleSockets() override {}
575 int IdleSocketCount() const override { return 0; }
576 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31577 return 0;
578 }
dmichaeld6e570d2014-12-18 22:30:57579 LoadState GetLoadState(const std::string& group_name,
580 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31581 return LOAD_STATE_IDLE;
582 }
dmichaeld6e570d2014-12-18 22:30:57583 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26584 return base::TimeDelta();
585 }
[email protected]d80a4322009-08-14 07:07:49586
587 private:
[email protected]04e5be32009-06-26 20:00:31588 std::string last_group_name_;
589};
590
[email protected]ab739042011-04-07 15:22:28591typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
592CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13593typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
594CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06595typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11596CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18597typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
598CaptureGroupNameSSLSocketPool;
599
rkaplowd90695c2015-03-25 22:12:41600template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18601CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34602 HostResolver* host_resolver,
603 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41604 : ParentPool(0, 0, host_resolver, NULL, NULL) {
605}
[email protected]e60e47a2010-07-14 03:37:18606
hashimoto0d3e4fb2015-01-09 05:02:50607template <>
[email protected]2df19bb2010-08-25 20:13:46608CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21609 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34610 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41611 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50612}
[email protected]2df19bb2010-08-25 20:13:46613
[email protected]007b3f82013-04-09 08:46:45614template <>
[email protected]e60e47a2010-07-14 03:37:18615CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21616 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34617 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45618 : SSLClientSocketPool(0,
619 0,
[email protected]007b3f82013-04-09 08:46:45620 cert_verifier,
621 NULL,
622 NULL,
[email protected]284303b62013-11-28 15:11:54623 NULL,
eranm6571b2b2014-12-03 15:53:23624 NULL,
[email protected]007b3f82013-04-09 08:46:45625 std::string(),
626 NULL,
627 NULL,
628 NULL,
629 NULL,
630 NULL,
[email protected]8e458552014-08-05 00:02:15631 NULL) {
632}
[email protected]2227c692010-05-04 15:36:11633
[email protected]231d5a32008-09-13 00:45:27634//-----------------------------------------------------------------------------
635
[email protected]79cb5c12011-09-12 13:12:04636// Helper functions for validating that AuthChallengeInfo's are correctly
637// configured for common cases.
638bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
639 if (!auth_challenge)
640 return false;
641 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23642 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04643 EXPECT_EQ("MyRealm1", auth_challenge->realm);
644 EXPECT_EQ("basic", auth_challenge->scheme);
645 return true;
646}
647
648bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
649 if (!auth_challenge)
650 return false;
651 EXPECT_TRUE(auth_challenge->is_proxy);
652 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
653 EXPECT_EQ("MyRealm1", auth_challenge->realm);
654 EXPECT_EQ("basic", auth_challenge->scheme);
655 return true;
656}
657
658bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
659 if (!auth_challenge)
660 return false;
661 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23662 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04663 EXPECT_EQ("digestive", auth_challenge->realm);
664 EXPECT_EQ("digest", auth_challenge->scheme);
665 return true;
666}
667
thakis84dff942015-07-28 20:47:38668#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04669bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
670 if (!auth_challenge)
671 return false;
672 EXPECT_FALSE(auth_challenge->is_proxy);
673 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
674 EXPECT_EQ(std::string(), auth_challenge->realm);
675 EXPECT_EQ("ntlm", auth_challenge->scheme);
676 return true;
677}
thakis84dff942015-07-28 20:47:38678#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04679
[email protected]448d4ca52012-03-04 04:12:23680} // namespace
681
[email protected]23e482282013-06-14 16:08:02682TEST_P(HttpNetworkTransactionTest, Basic) {
mmenkee65e7af2015-10-13 17:16:42683 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40684 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41685 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27686}
687
[email protected]23e482282013-06-14 16:08:02688TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27689 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35690 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
691 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06692 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27693 };
[email protected]31a2bfe2010-02-09 08:03:39694 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
695 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42696 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27697 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
698 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22699 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
700 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47701 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59702
703 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27704}
705
706// Response with no status line.
[email protected]23e482282013-06-14 16:08:02707TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27708 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35709 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06710 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27711 };
[email protected]31a2bfe2010-02-09 08:03:39712 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
713 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42714 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27715 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
716 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22717 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
718 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27719}
720
721// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02722TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27723 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35724 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06725 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27726 };
[email protected]31a2bfe2010-02-09 08:03:39727 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
728 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42729 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27730 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
731 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22732 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
733 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27734}
735
736// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02737TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27738 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35739 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06740 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27741 };
[email protected]31a2bfe2010-02-09 08:03:39742 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
743 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42744 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27745 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
746 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22747 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
748 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27749}
750
751// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02752TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27753 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35754 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06755 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27756 };
[email protected]31a2bfe2010-02-09 08:03:39757 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
758 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42759 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25760 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
761 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
sclittlefb249892015-09-10 21:33:22762 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
763 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27764}
765
766// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02767TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27768 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35769 MockRead("\n"),
770 MockRead("\n"),
771 MockRead("Q"),
772 MockRead("J"),
773 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06774 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27775 };
[email protected]31a2bfe2010-02-09 08:03:39776 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
777 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42778 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27779 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
780 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22781 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
782 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27783}
784
785// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02786TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27787 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35788 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06789 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27790 };
[email protected]31a2bfe2010-02-09 08:03:39791 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
792 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42793 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27794 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
795 EXPECT_EQ("HTT", out.response_data);
sclittlefb249892015-09-10 21:33:22796 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
797 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52798}
799
[email protected]f9d44aa2008-09-23 23:57:17800// Simulate a 204 response, lacking a Content-Length header, sent over a
801// persistent connection. The response should still terminate since a 204
802// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02803TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19804 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17805 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35806 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19807 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06808 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17809 };
[email protected]31a2bfe2010-02-09 08:03:39810 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
811 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42812 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17813 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
814 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22815 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
816 int64_t response_size = reads_size - strlen(junk);
817 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17818}
819
[email protected]0877e3d2009-10-17 22:29:57820// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02821TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19822 std::string final_chunk = "0\r\n\r\n";
823 std::string extra_data = "HTTP/1.1 200 OK\r\n";
824 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57825 MockRead data_reads[] = {
826 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
827 MockRead("5\r\nHello\r\n"),
828 MockRead("1\r\n"),
829 MockRead(" \r\n"),
830 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19831 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06832 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57833 };
[email protected]31a2bfe2010-02-09 08:03:39834 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
835 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57836 EXPECT_EQ(OK, out.rv);
837 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
838 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22839 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
840 int64_t response_size = reads_size - extra_data.size();
841 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57842}
843
[email protected]9fe44f52010-09-23 18:36:00844// Next tests deal with http://crbug.com/56344.
845
[email protected]23e482282013-06-14 16:08:02846TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00847 MultipleContentLengthHeadersNoTransferEncoding) {
848 MockRead data_reads[] = {
849 MockRead("HTTP/1.1 200 OK\r\n"),
850 MockRead("Content-Length: 10\r\n"),
851 MockRead("Content-Length: 5\r\n\r\n"),
852 };
853 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
854 arraysize(data_reads));
855 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
856}
857
[email protected]23e482282013-06-14 16:08:02858TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04859 DuplicateContentLengthHeadersNoTransferEncoding) {
860 MockRead data_reads[] = {
861 MockRead("HTTP/1.1 200 OK\r\n"),
862 MockRead("Content-Length: 5\r\n"),
863 MockRead("Content-Length: 5\r\n\r\n"),
864 MockRead("Hello"),
865 };
866 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
867 arraysize(data_reads));
868 EXPECT_EQ(OK, out.rv);
869 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
870 EXPECT_EQ("Hello", out.response_data);
871}
872
[email protected]23e482282013-06-14 16:08:02873TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04874 ComplexContentLengthHeadersNoTransferEncoding) {
875 // More than 2 dupes.
876 {
877 MockRead data_reads[] = {
878 MockRead("HTTP/1.1 200 OK\r\n"),
879 MockRead("Content-Length: 5\r\n"),
880 MockRead("Content-Length: 5\r\n"),
881 MockRead("Content-Length: 5\r\n\r\n"),
882 MockRead("Hello"),
883 };
884 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
885 arraysize(data_reads));
886 EXPECT_EQ(OK, out.rv);
887 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
888 EXPECT_EQ("Hello", out.response_data);
889 }
890 // HTTP/1.0
891 {
892 MockRead data_reads[] = {
893 MockRead("HTTP/1.0 200 OK\r\n"),
894 MockRead("Content-Length: 5\r\n"),
895 MockRead("Content-Length: 5\r\n"),
896 MockRead("Content-Length: 5\r\n\r\n"),
897 MockRead("Hello"),
898 };
899 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
900 arraysize(data_reads));
901 EXPECT_EQ(OK, out.rv);
902 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
903 EXPECT_EQ("Hello", out.response_data);
904 }
905 // 2 dupes and one mismatched.
906 {
907 MockRead data_reads[] = {
908 MockRead("HTTP/1.1 200 OK\r\n"),
909 MockRead("Content-Length: 10\r\n"),
910 MockRead("Content-Length: 10\r\n"),
911 MockRead("Content-Length: 5\r\n\r\n"),
912 };
913 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
914 arraysize(data_reads));
915 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
916 }
917}
918
[email protected]23e482282013-06-14 16:08:02919TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00920 MultipleContentLengthHeadersTransferEncoding) {
921 MockRead data_reads[] = {
922 MockRead("HTTP/1.1 200 OK\r\n"),
923 MockRead("Content-Length: 666\r\n"),
924 MockRead("Content-Length: 1337\r\n"),
925 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
926 MockRead("5\r\nHello\r\n"),
927 MockRead("1\r\n"),
928 MockRead(" \r\n"),
929 MockRead("5\r\nworld\r\n"),
930 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06931 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00932 };
933 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
934 arraysize(data_reads));
935 EXPECT_EQ(OK, out.rv);
936 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
937 EXPECT_EQ("Hello world", out.response_data);
938}
939
[email protected]1628fe92011-10-04 23:04:55940// Next tests deal with http://crbug.com/98895.
941
942// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02943TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55944 MockRead data_reads[] = {
945 MockRead("HTTP/1.1 200 OK\r\n"),
946 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
947 MockRead("Content-Length: 5\r\n\r\n"),
948 MockRead("Hello"),
949 };
950 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
951 arraysize(data_reads));
952 EXPECT_EQ(OK, out.rv);
953 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
954 EXPECT_EQ("Hello", out.response_data);
955}
956
[email protected]54a9c6e52012-03-21 20:10:59957// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02958TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59959 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55960 MockRead data_reads[] = {
961 MockRead("HTTP/1.1 200 OK\r\n"),
962 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
963 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
964 MockRead("Content-Length: 5\r\n\r\n"),
965 MockRead("Hello"),
966 };
967 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
968 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59969 EXPECT_EQ(OK, out.rv);
970 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
971 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55972}
973
974// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02975TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55976 MockRead data_reads[] = {
977 MockRead("HTTP/1.1 200 OK\r\n"),
978 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
979 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
980 MockRead("Content-Length: 5\r\n\r\n"),
981 MockRead("Hello"),
982 };
983 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
984 arraysize(data_reads));
985 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
986}
987
[email protected]54a9c6e52012-03-21 20:10:59988// Checks that two identical Location headers result in no error.
989// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02990TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55991 MockRead data_reads[] = {
992 MockRead("HTTP/1.1 302 Redirect\r\n"),
993 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59994 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55995 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06996 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55997 };
998
999 HttpRequestInfo request;
1000 request.method = "GET";
1001 request.url = GURL("http://redirect.com/");
1002 request.load_flags = 0;
1003
mmenkee65e7af2015-10-13 17:16:421004 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:551005 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411006 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:551007
1008 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071009 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551010
[email protected]49639fa2011-12-20 23:22:411011 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551012
[email protected]49639fa2011-12-20 23:22:411013 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:551014 EXPECT_EQ(ERR_IO_PENDING, rv);
1015
1016 EXPECT_EQ(OK, callback.WaitForResult());
1017
1018 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:501019 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:551020 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1021 std::string url;
1022 EXPECT_TRUE(response->headers->IsRedirect(&url));
1023 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:151024 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:551025}
1026
[email protected]1628fe92011-10-04 23:04:551027// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:021028TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551029 MockRead data_reads[] = {
1030 MockRead("HTTP/1.1 302 Redirect\r\n"),
1031 MockRead("Location: http://good.com/\r\n"),
1032 MockRead("Location: http://evil.com/\r\n"),
1033 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061034 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551035 };
1036 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1037 arraysize(data_reads));
1038 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1039}
1040
[email protected]ef0faf2e72009-03-05 23:27:231041// Do a request using the HEAD method. Verify that we don't try to read the
1042// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021043TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421044 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231045 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231046 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231047 request.load_flags = 0;
1048
mmenkee65e7af2015-10-13 17:16:421049 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271050 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411051 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271052 BeforeProxyHeadersSentHandler proxy_headers_handler;
1053 trans->SetBeforeProxyHeadersSentCallback(
1054 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1055 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271056
[email protected]ef0faf2e72009-03-05 23:27:231057 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131058 MockWrite("HEAD / HTTP/1.1\r\n"
1059 "Host: www.example.org\r\n"
1060 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231061 };
1062 MockRead data_reads1[] = {
1063 MockRead("HTTP/1.1 404 Not Found\r\n"),
1064 MockRead("Server: Blah\r\n"),
1065 MockRead("Content-Length: 1234\r\n\r\n"),
1066
1067 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061068 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231069 };
1070
[email protected]31a2bfe2010-02-09 08:03:391071 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1072 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071073 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231074
[email protected]49639fa2011-12-20 23:22:411075 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231076
[email protected]49639fa2011-12-20 23:22:411077 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421078 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231079
1080 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421081 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231082
[email protected]1c773ea12009-04-28 19:58:421083 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501084 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231085
1086 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501087 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231088 EXPECT_EQ(1234, response->headers->GetContentLength());
1089 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151090 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271091 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231092
1093 std::string server_header;
1094 void* iter = NULL;
1095 bool has_server_header = response->headers->EnumerateHeader(
1096 &iter, "Server", &server_header);
1097 EXPECT_TRUE(has_server_header);
1098 EXPECT_EQ("Blah", server_header);
1099
1100 // Reading should give EOF right away, since there is no message body
1101 // (despite non-zero content-length).
1102 std::string response_data;
1103 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421104 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231105 EXPECT_EQ("", response_data);
1106}
1107
[email protected]23e482282013-06-14 16:08:021108TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
mmenkee65e7af2015-10-13 17:16:421109 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521110
1111 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351112 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1113 MockRead("hello"),
1114 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1115 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061116 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521117 };
[email protected]31a2bfe2010-02-09 08:03:391118 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071119 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521120
[email protected]0b0bf032010-09-21 18:08:501121 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521122 "hello", "world"
1123 };
1124
1125 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421126 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521127 request.method = "GET";
bncce36dca22015-04-21 22:11:231128 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521129 request.load_flags = 0;
1130
[email protected]262eec82013-03-19 21:01:361131 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501132 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271133
[email protected]49639fa2011-12-20 23:22:411134 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521135
[email protected]49639fa2011-12-20 23:22:411136 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421137 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521138
1139 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421140 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521141
[email protected]1c773ea12009-04-28 19:58:421142 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501143 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521144
[email protected]90499482013-06-01 00:39:501145 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251146 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151147 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521148
1149 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571150 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421151 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251152 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521153 }
1154}
1155
[email protected]23e482282013-06-14 16:08:021156TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061157 ScopedVector<UploadElementReader> element_readers;
1158 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:071159 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271160
[email protected]1c773ea12009-04-28 19:58:421161 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521162 request.method = "POST";
1163 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271164 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521165 request.load_flags = 0;
1166
mmenkee65e7af2015-10-13 17:16:421167 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271168 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411169 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271170
initial.commit586acc5fe2008-07-26 22:42:521171 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351172 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1173 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1174 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061175 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521176 };
[email protected]31a2bfe2010-02-09 08:03:391177 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071178 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521179
[email protected]49639fa2011-12-20 23:22:411180 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521181
[email protected]49639fa2011-12-20 23:22:411182 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421183 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521184
1185 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421186 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521187
[email protected]1c773ea12009-04-28 19:58:421188 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501189 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521190
[email protected]90499482013-06-01 00:39:501191 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251192 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521193
1194 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571195 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421196 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251197 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521198}
1199
[email protected]3a2d3662009-03-27 03:49:141200// This test is almost the same as Ignores100 above, but the response contains
1201// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571202// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021203TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421204 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141205 request.method = "GET";
1206 request.url = GURL("http://www.foo.com/");
1207 request.load_flags = 0;
1208
mmenkee65e7af2015-10-13 17:16:421209 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271210 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411211 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271212
[email protected]3a2d3662009-03-27 03:49:141213 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571214 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1215 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141216 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061217 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141218 };
[email protected]31a2bfe2010-02-09 08:03:391219 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071220 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141221
[email protected]49639fa2011-12-20 23:22:411222 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141223
[email protected]49639fa2011-12-20 23:22:411224 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421225 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141226
1227 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421228 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141229
[email protected]1c773ea12009-04-28 19:58:421230 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501231 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141232
[email protected]90499482013-06-01 00:39:501233 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141234 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1235
1236 std::string response_data;
1237 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421238 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141239 EXPECT_EQ("hello world", response_data);
1240}
1241
[email protected]23e482282013-06-14 16:08:021242TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081243 HttpRequestInfo request;
1244 request.method = "POST";
1245 request.url = GURL("http://www.foo.com/");
1246 request.load_flags = 0;
1247
mmenkee65e7af2015-10-13 17:16:421248 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
zmo9528c9f42015-08-04 22:12:081249 scoped_ptr<HttpTransaction> trans(
1250 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1251
1252 MockRead data_reads[] = {
1253 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1254 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381255 };
zmo9528c9f42015-08-04 22:12:081256 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1257 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381258
zmo9528c9f42015-08-04 22:12:081259 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381260
zmo9528c9f42015-08-04 22:12:081261 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1262 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ee9410e72010-01-07 01:42:381263
zmo9528c9f42015-08-04 22:12:081264 rv = callback.WaitForResult();
1265 EXPECT_EQ(OK, rv);
[email protected]ee9410e72010-01-07 01:42:381266
zmo9528c9f42015-08-04 22:12:081267 std::string response_data;
1268 rv = ReadTransaction(trans.get(), &response_data);
1269 EXPECT_EQ(OK, rv);
1270 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381271}
1272
[email protected]23e482282013-06-14 16:08:021273TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381274 HttpRequestInfo request;
1275 request.method = "POST";
1276 request.url = GURL("http://www.foo.com/");
1277 request.load_flags = 0;
1278
mmenkee65e7af2015-10-13 17:16:421279 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271280 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411281 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271282
[email protected]ee9410e72010-01-07 01:42:381283 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061284 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381285 };
[email protected]31a2bfe2010-02-09 08:03:391286 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071287 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381288
[email protected]49639fa2011-12-20 23:22:411289 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381290
[email protected]49639fa2011-12-20 23:22:411291 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381292 EXPECT_EQ(ERR_IO_PENDING, rv);
1293
1294 rv = callback.WaitForResult();
1295 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1296}
1297
[email protected]23e482282013-06-14 16:08:021298void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511299 const MockWrite* write_failure,
1300 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421301 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521302 request.method = "GET";
1303 request.url = GURL("http://www.foo.com/");
1304 request.load_flags = 0;
1305
vishal.b62985ca92015-04-17 08:45:511306 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071307 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:421308 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271309
[email protected]202965992011-12-07 23:04:511310 // Written data for successfully sending both requests.
1311 MockWrite data1_writes[] = {
1312 MockWrite("GET / HTTP/1.1\r\n"
1313 "Host: www.foo.com\r\n"
1314 "Connection: keep-alive\r\n\r\n"),
1315 MockWrite("GET / HTTP/1.1\r\n"
1316 "Host: www.foo.com\r\n"
1317 "Connection: keep-alive\r\n\r\n")
1318 };
1319
1320 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521321 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351322 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1323 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061324 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521325 };
[email protected]202965992011-12-07 23:04:511326
1327 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491328 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511329 data1_writes[1] = *write_failure;
1330 } else {
1331 ASSERT_TRUE(read_failure);
1332 data1_reads[2] = *read_failure;
1333 }
1334
1335 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1336 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071337 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521338
1339 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351340 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1341 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061342 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521343 };
[email protected]31a2bfe2010-02-09 08:03:391344 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071345 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521346
thestig9d3bb0c2015-01-24 00:49:511347 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521348 "hello", "world"
1349 };
1350
[email protected]58e32bb2013-01-21 18:23:251351 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521352 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411353 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521354
[email protected]262eec82013-03-19 21:01:361355 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501356 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521357
[email protected]49639fa2011-12-20 23:22:411358 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421359 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521360
1361 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421362 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521363
[email protected]58e32bb2013-01-21 18:23:251364 LoadTimingInfo load_timing_info;
1365 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1366 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1367 if (i == 0) {
1368 first_socket_log_id = load_timing_info.socket_log_id;
1369 } else {
1370 // The second request should be using a new socket.
1371 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1372 }
1373
[email protected]1c773ea12009-04-28 19:58:421374 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501375 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521376
[email protected]90499482013-06-01 00:39:501377 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251378 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521379
1380 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571381 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421382 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251383 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521384 }
1385}
[email protected]3d2a59b2008-09-26 19:44:251386
[email protected]a34f61ee2014-03-18 20:59:491387void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1388 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101389 const MockRead* read_failure,
1390 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491391 HttpRequestInfo request;
1392 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101393 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491394 request.load_flags = 0;
1395
vishal.b62985ca92015-04-17 08:45:511396 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491397 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:421398 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491399
[email protected]09356c652014-03-25 15:36:101400 SSLSocketDataProvider ssl1(ASYNC, OK);
1401 SSLSocketDataProvider ssl2(ASYNC, OK);
1402 if (use_spdy) {
1403 ssl1.SetNextProto(GetParam());
1404 ssl2.SetNextProto(GetParam());
1405 }
1406 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1407 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491408
[email protected]09356c652014-03-25 15:36:101409 // SPDY versions of the request and response.
1410 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1411 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1412 scoped_ptr<SpdyFrame> spdy_response(
1413 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1414 scoped_ptr<SpdyFrame> spdy_data(
1415 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491416
[email protected]09356c652014-03-25 15:36:101417 // HTTP/1.1 versions of the request and response.
1418 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1419 "Host: www.foo.com\r\n"
1420 "Connection: keep-alive\r\n\r\n";
1421 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1422 const char kHttpData[] = "hello";
1423
1424 std::vector<MockRead> data1_reads;
1425 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491426 if (write_failure) {
1427 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101428 data1_writes.push_back(*write_failure);
1429 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491430 } else {
1431 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101432 if (use_spdy) {
1433 data1_writes.push_back(CreateMockWrite(*spdy_request));
1434 } else {
1435 data1_writes.push_back(MockWrite(kHttpRequest));
1436 }
1437 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491438 }
1439
[email protected]09356c652014-03-25 15:36:101440 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1441 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491442 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1443
[email protected]09356c652014-03-25 15:36:101444 std::vector<MockRead> data2_reads;
1445 std::vector<MockWrite> data2_writes;
1446
1447 if (use_spdy) {
1448 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1449
1450 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1451 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1452 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1453 } else {
1454 data2_writes.push_back(
1455 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1456
1457 data2_reads.push_back(
1458 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1459 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1460 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1461 }
rch8e6c6c42015-05-01 14:05:131462 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1463 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491464 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1465
1466 // Preconnect a socket.
ttuttle859dc7a2015-04-23 19:42:291467 SSLConfig ssl_config;
[email protected]a34f61ee2014-03-18 20:59:491468 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231469 session->GetNextProtos(&ssl_config.next_protos);
mmenked1205bd3972015-07-15 22:26:351470 session->http_stream_factory()->PreconnectStreams(1, request, ssl_config,
1471 ssl_config);
[email protected]a34f61ee2014-03-18 20:59:491472 // Wait for the preconnect to complete.
1473 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1474 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101475 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491476
1477 // Make the request.
1478 TestCompletionCallback callback;
1479
1480 scoped_ptr<HttpTransaction> trans(
1481 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1482
1483 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1484 EXPECT_EQ(ERR_IO_PENDING, rv);
1485
1486 rv = callback.WaitForResult();
1487 EXPECT_EQ(OK, rv);
1488
1489 LoadTimingInfo load_timing_info;
1490 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101491 TestLoadTimingNotReused(
1492 load_timing_info,
1493 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491494
1495 const HttpResponseInfo* response = trans->GetResponseInfo();
1496 ASSERT_TRUE(response != NULL);
1497
1498 EXPECT_TRUE(response->headers.get() != NULL);
1499 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1500
1501 std::string response_data;
1502 rv = ReadTransaction(trans.get(), &response_data);
1503 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101504 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491505}
1506
[email protected]23e482282013-06-14 16:08:021507TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231508 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061509 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511510 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1511}
1512
[email protected]23e482282013-06-14 16:08:021513TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061514 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511515 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251516}
1517
[email protected]23e482282013-06-14 16:08:021518TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061519 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511520 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251521}
1522
[email protected]d58ceea82014-06-04 10:55:541523// Make sure that on a 408 response (Request Timeout), the request is retried,
1524// if the socket was a reused keep alive socket.
1525TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1526 MockRead read_failure(SYNCHRONOUS,
1527 "HTTP/1.1 408 Request Timeout\r\n"
1528 "Connection: Keep-Alive\r\n"
1529 "Content-Length: 6\r\n\r\n"
1530 "Pickle");
1531 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1532}
1533
[email protected]a34f61ee2014-03-18 20:59:491534TEST_P(HttpNetworkTransactionTest,
1535 PreconnectErrorNotConnectedOnWrite) {
1536 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101537 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491538}
1539
1540TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1541 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101542 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491543}
1544
1545TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1546 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101547 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1548}
1549
1550TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1551 MockRead read_failure(ASYNC, OK); // EOF
1552 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1553}
1554
[email protected]d58ceea82014-06-04 10:55:541555// Make sure that on a 408 response (Request Timeout), the request is retried,
1556// if the socket was a preconnected (UNUSED_IDLE) socket.
1557TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1558 MockRead read_failure(SYNCHRONOUS,
1559 "HTTP/1.1 408 Request Timeout\r\n"
1560 "Connection: Keep-Alive\r\n"
1561 "Content-Length: 6\r\n\r\n"
1562 "Pickle");
1563 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1564 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1565}
1566
[email protected]09356c652014-03-25 15:36:101567TEST_P(HttpNetworkTransactionTest,
1568 SpdyPreconnectErrorNotConnectedOnWrite) {
1569 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1570 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1571}
1572
1573TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1574 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1575 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1576}
1577
1578TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1579 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1580 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1581}
1582
1583TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1584 MockRead read_failure(ASYNC, OK); // EOF
1585 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491586}
1587
[email protected]23e482282013-06-14 16:08:021588TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421589 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251590 request.method = "GET";
bncce36dca22015-04-21 22:11:231591 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251592 request.load_flags = 0;
1593
mmenkee65e7af2015-10-13 17:16:421594 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271595 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411596 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271597
[email protected]3d2a59b2008-09-26 19:44:251598 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061599 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351600 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1601 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061602 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251603 };
[email protected]31a2bfe2010-02-09 08:03:391604 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071605 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251606
[email protected]49639fa2011-12-20 23:22:411607 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251608
[email protected]49639fa2011-12-20 23:22:411609 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421610 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251611
1612 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421613 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:591614
1615 IPEndPoint endpoint;
1616 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
1617 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251618}
1619
1620// What do various browsers do when the server closes a non-keepalive
1621// connection without sending any response header or body?
1622//
1623// IE7: error page
1624// Safari 3.1.2 (Windows): error page
1625// Firefox 3.0.1: blank page
1626// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421627// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1628// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021629TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251630 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061631 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351632 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1633 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061634 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251635 };
[email protected]31a2bfe2010-02-09 08:03:391636 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1637 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421638 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251639}
[email protected]038e9a32008-10-08 22:40:161640
[email protected]1826a402014-01-08 15:40:481641// Test that network access can be deferred and resumed.
1642TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1643 HttpRequestInfo request;
1644 request.method = "GET";
bncce36dca22015-04-21 22:11:231645 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481646 request.load_flags = 0;
1647
mmenkee65e7af2015-10-13 17:16:421648 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1826a402014-01-08 15:40:481649 scoped_ptr<HttpTransaction> trans(
1650 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1651
1652 // Defer on OnBeforeNetworkStart.
1653 BeforeNetworkStartHandler net_start_handler(true); // defer
1654 trans->SetBeforeNetworkStartCallback(
1655 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1656 base::Unretained(&net_start_handler)));
1657
1658 MockRead data_reads[] = {
1659 MockRead("HTTP/1.0 200 OK\r\n"),
1660 MockRead("Content-Length: 5\r\n\r\n"),
1661 MockRead("hello"),
1662 MockRead(SYNCHRONOUS, 0),
1663 };
1664 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1665 session_deps_.socket_factory->AddSocketDataProvider(&data);
1666
1667 TestCompletionCallback callback;
1668
1669 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1670 EXPECT_EQ(ERR_IO_PENDING, rv);
1671 base::MessageLoop::current()->RunUntilIdle();
1672
1673 // Should have deferred for network start.
1674 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1675 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481676
1677 trans->ResumeNetworkStart();
1678 rv = callback.WaitForResult();
1679 EXPECT_EQ(OK, rv);
1680 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1681
1682 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1683 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1684 if (rv == ERR_IO_PENDING)
1685 rv = callback.WaitForResult();
1686 EXPECT_EQ(5, rv);
1687 trans.reset();
1688}
1689
1690// Test that network use can be deferred and canceled.
1691TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1692 HttpRequestInfo request;
1693 request.method = "GET";
bncce36dca22015-04-21 22:11:231694 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481695 request.load_flags = 0;
1696
mmenkee65e7af2015-10-13 17:16:421697 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1826a402014-01-08 15:40:481698 scoped_ptr<HttpTransaction> trans(
1699 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1700
1701 // Defer on OnBeforeNetworkStart.
1702 BeforeNetworkStartHandler net_start_handler(true); // defer
1703 trans->SetBeforeNetworkStartCallback(
1704 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1705 base::Unretained(&net_start_handler)));
1706
1707 TestCompletionCallback callback;
1708
1709 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1710 EXPECT_EQ(ERR_IO_PENDING, rv);
1711 base::MessageLoop::current()->RunUntilIdle();
1712
1713 // Should have deferred for network start.
1714 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1715 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481716}
1717
[email protected]7a5378b2012-11-04 03:25:171718// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1719// tests. There was a bug causing HttpNetworkTransaction to hang in the
1720// destructor in such situations.
1721// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021722TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171723 HttpRequestInfo request;
1724 request.method = "GET";
bncce36dca22015-04-21 22:11:231725 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171726 request.load_flags = 0;
1727
mmenkee65e7af2015-10-13 17:16:421728 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361729 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501730 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171731
1732 MockRead data_reads[] = {
1733 MockRead("HTTP/1.0 200 OK\r\n"),
1734 MockRead("Connection: keep-alive\r\n"),
1735 MockRead("Content-Length: 100\r\n\r\n"),
1736 MockRead("hello"),
1737 MockRead(SYNCHRONOUS, 0),
1738 };
1739 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071740 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171741
1742 TestCompletionCallback callback;
1743
1744 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1745 EXPECT_EQ(ERR_IO_PENDING, rv);
1746
1747 rv = callback.WaitForResult();
1748 EXPECT_EQ(OK, rv);
1749
1750 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501751 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171752 if (rv == ERR_IO_PENDING)
1753 rv = callback.WaitForResult();
1754 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501755 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171756 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1757
1758 trans.reset();
[email protected]2da659e2013-05-23 20:51:341759 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171760 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1761}
1762
[email protected]23e482282013-06-14 16:08:021763TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171764 HttpRequestInfo request;
1765 request.method = "GET";
bncce36dca22015-04-21 22:11:231766 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171767 request.load_flags = 0;
1768
mmenkee65e7af2015-10-13 17:16:421769 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361770 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501771 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171772
1773 MockRead data_reads[] = {
1774 MockRead("HTTP/1.0 200 OK\r\n"),
1775 MockRead("Connection: keep-alive\r\n"),
1776 MockRead("Content-Length: 100\r\n\r\n"),
1777 MockRead(SYNCHRONOUS, 0),
1778 };
1779 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071780 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171781
1782 TestCompletionCallback callback;
1783
1784 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1785 EXPECT_EQ(ERR_IO_PENDING, rv);
1786
1787 rv = callback.WaitForResult();
1788 EXPECT_EQ(OK, rv);
1789
1790 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501791 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171792 if (rv == ERR_IO_PENDING)
1793 rv = callback.WaitForResult();
1794 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1795
1796 trans.reset();
[email protected]2da659e2013-05-23 20:51:341797 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171798 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1799}
1800
[email protected]0b0bf032010-09-21 18:08:501801// Test that we correctly reuse a keep-alive connection after not explicitly
1802// reading the body.
[email protected]23e482282013-06-14 16:08:021803TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131804 HttpRequestInfo request;
1805 request.method = "GET";
1806 request.url = GURL("http://www.foo.com/");
1807 request.load_flags = 0;
1808
vishal.b62985ca92015-04-17 08:45:511809 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071810 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:421811 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271812
[email protected]0b0bf032010-09-21 18:08:501813 // Note that because all these reads happen in the same
1814 // StaticSocketDataProvider, it shows that the same socket is being reused for
1815 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131816 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501817 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1818 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131819 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501820 MockRead("HTTP/1.1 302 Found\r\n"
1821 "Content-Length: 0\r\n\r\n"),
1822 MockRead("HTTP/1.1 302 Found\r\n"
1823 "Content-Length: 5\r\n\r\n"
1824 "hello"),
1825 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1826 "Content-Length: 0\r\n\r\n"),
1827 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1828 "Content-Length: 5\r\n\r\n"
1829 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131830 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1831 MockRead("hello"),
1832 };
1833 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071834 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131835
1836 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061837 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131838 };
1839 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071840 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131841
[email protected]0b0bf032010-09-21 18:08:501842 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1843 std::string response_lines[kNumUnreadBodies];
1844
[email protected]58e32bb2013-01-21 18:23:251845 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501846 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411847 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131848
[email protected]262eec82013-03-19 21:01:361849 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501850 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131851
[email protected]49639fa2011-12-20 23:22:411852 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131853 EXPECT_EQ(ERR_IO_PENDING, rv);
1854
1855 rv = callback.WaitForResult();
1856 EXPECT_EQ(OK, rv);
1857
[email protected]58e32bb2013-01-21 18:23:251858 LoadTimingInfo load_timing_info;
1859 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1860 if (i == 0) {
1861 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1862 first_socket_log_id = load_timing_info.socket_log_id;
1863 } else {
1864 TestLoadTimingReused(load_timing_info);
1865 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1866 }
1867
[email protected]fc31d6a42010-06-24 18:05:131868 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501869 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131870
[email protected]90499482013-06-01 00:39:501871 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501872 response_lines[i] = response->headers->GetStatusLine();
1873
1874 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131875 }
[email protected]0b0bf032010-09-21 18:08:501876
1877 const char* const kStatusLines[] = {
1878 "HTTP/1.1 204 No Content",
1879 "HTTP/1.1 205 Reset Content",
1880 "HTTP/1.1 304 Not Modified",
1881 "HTTP/1.1 302 Found",
1882 "HTTP/1.1 302 Found",
1883 "HTTP/1.1 301 Moved Permanently",
1884 "HTTP/1.1 301 Moved Permanently",
1885 };
1886
mostynb91e0da982015-01-20 19:17:271887 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1888 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501889
1890 for (int i = 0; i < kNumUnreadBodies; ++i)
1891 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1892
[email protected]49639fa2011-12-20 23:22:411893 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361894 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501895 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411896 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501897 EXPECT_EQ(ERR_IO_PENDING, rv);
1898 rv = callback.WaitForResult();
1899 EXPECT_EQ(OK, rv);
1900 const HttpResponseInfo* response = trans->GetResponseInfo();
1901 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501902 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501903 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1904 std::string response_data;
1905 rv = ReadTransaction(trans.get(), &response_data);
1906 EXPECT_EQ(OK, rv);
1907 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131908}
1909
[email protected]038e9a32008-10-08 22:40:161910// Test the request-challenge-retry sequence for basic auth.
1911// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021912TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421913 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161914 request.method = "GET";
bncce36dca22015-04-21 22:11:231915 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161916 request.load_flags = 0;
1917
vishal.b62985ca92015-04-17 08:45:511918 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071919 session_deps_.net_log = &log;
mmenkee65e7af2015-10-13 17:16:421920 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271921 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271923
[email protected]f9ee6b52008-11-08 06:46:231924 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231925 MockWrite(
1926 "GET / HTTP/1.1\r\n"
1927 "Host: www.example.org\r\n"
1928 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231929 };
1930
[email protected]038e9a32008-10-08 22:40:161931 MockRead data_reads1[] = {
1932 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1933 // Give a couple authenticate options (only the middle one is actually
1934 // supported).
[email protected]22927ad2009-09-21 19:56:191935 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161936 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1937 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1938 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1939 // Large content-length -- won't matter, as connection will be reset.
1940 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061941 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161942 };
1943
1944 // After calling trans->RestartWithAuth(), this is the request we should
1945 // be issuing -- the final header line contains the credentials.
1946 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:231947 MockWrite(
1948 "GET / HTTP/1.1\r\n"
1949 "Host: www.example.org\r\n"
1950 "Connection: keep-alive\r\n"
1951 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:161952 };
1953
1954 // Lastly, the server responds with the actual content.
1955 MockRead data_reads2[] = {
1956 MockRead("HTTP/1.0 200 OK\r\n"),
1957 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1958 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061959 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161960 };
1961
[email protected]31a2bfe2010-02-09 08:03:391962 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1963 data_writes1, arraysize(data_writes1));
1964 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1965 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071966 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1967 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161968
[email protected]49639fa2011-12-20 23:22:411969 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161970
[email protected]49639fa2011-12-20 23:22:411971 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421972 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161973
1974 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421975 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161976
[email protected]58e32bb2013-01-21 18:23:251977 LoadTimingInfo load_timing_info1;
1978 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1979 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1980
sclittlefb249892015-09-10 21:33:221981 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
1982 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
1983 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:191984 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1985
[email protected]1c773ea12009-04-28 19:58:421986 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501987 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041988 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161989
[email protected]49639fa2011-12-20 23:22:411990 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161991
[email protected]49639fa2011-12-20 23:22:411992 rv = trans->RestartWithAuth(
1993 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421994 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161995
1996 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421997 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161998
[email protected]58e32bb2013-01-21 18:23:251999 LoadTimingInfo load_timing_info2;
2000 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2001 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2002 // The load timing after restart should have a new socket ID, and times after
2003 // those of the first load timing.
2004 EXPECT_LE(load_timing_info1.receive_headers_end,
2005 load_timing_info2.connect_timing.connect_start);
2006 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2007
sclittlefb249892015-09-10 21:33:222008 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2009 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2010 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
[email protected]b8015c42013-12-24 15:18:192011 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2012
[email protected]038e9a32008-10-08 22:40:162013 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502014 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:162015 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2016 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162017}
2018
ttuttled9dbc652015-09-29 20:00:592019// Test the request-challenge-retry sequence for basic auth.
2020// (basic auth is the easiest to mock, because it has no randomness).
2021TEST_P(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
2022 HttpRequestInfo request;
2023 request.method = "GET";
2024 request.url = GURL("http://www.example.org/");
2025 request.load_flags = 0;
2026
2027 TestNetLog log;
2028 MockHostResolver* resolver = new MockHostResolver();
2029 session_deps_.net_log = &log;
2030 session_deps_.host_resolver.reset(resolver);
mmenkee65e7af2015-10-13 17:16:422031 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
ttuttled9dbc652015-09-29 20:00:592032 scoped_ptr<HttpTransaction> trans(
2033 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2034
2035 resolver->rules()->ClearRules();
2036 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2037
2038 MockWrite data_writes1[] = {
2039 MockWrite("GET / HTTP/1.1\r\n"
2040 "Host: www.example.org\r\n"
2041 "Connection: keep-alive\r\n\r\n"),
2042 };
2043
2044 MockRead data_reads1[] = {
2045 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2046 // Give a couple authenticate options (only the middle one is actually
2047 // supported).
2048 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2049 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2050 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2051 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2052 // Large content-length -- won't matter, as connection will be reset.
2053 MockRead("Content-Length: 10000\r\n\r\n"),
2054 MockRead(SYNCHRONOUS, ERR_FAILED),
2055 };
2056
2057 // After calling trans->RestartWithAuth(), this is the request we should
2058 // be issuing -- the final header line contains the credentials.
2059 MockWrite data_writes2[] = {
2060 MockWrite("GET / HTTP/1.1\r\n"
2061 "Host: www.example.org\r\n"
2062 "Connection: keep-alive\r\n"
2063 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2064 };
2065
2066 // Lastly, the server responds with the actual content.
2067 MockRead data_reads2[] = {
2068 MockRead("HTTP/1.0 200 OK\r\n"),
2069 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2070 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2071 };
2072
2073 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2074 data_writes1, arraysize(data_writes1));
2075 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2076 data_writes2, arraysize(data_writes2));
2077 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2078 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2079
2080 TestCompletionCallback callback1;
2081
2082 EXPECT_EQ(OK, callback1.GetResult(trans->Start(&request, callback1.callback(),
2083 BoundNetLog())));
2084
2085 LoadTimingInfo load_timing_info1;
2086 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2087 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2088
2089 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2090 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2091 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
2092 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2093
2094 const HttpResponseInfo* response = trans->GetResponseInfo();
2095 ASSERT_TRUE(response);
2096 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2097
2098 IPEndPoint endpoint;
2099 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2100 ASSERT_FALSE(endpoint.address().empty());
2101 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2102
2103 resolver->rules()->ClearRules();
2104 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2105
2106 TestCompletionCallback callback2;
2107
2108 EXPECT_EQ(OK, callback2.GetResult(trans->RestartWithAuth(
2109 AuthCredentials(kFoo, kBar), callback2.callback())));
2110
2111 LoadTimingInfo load_timing_info2;
2112 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2113 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2114 // The load timing after restart should have a new socket ID, and times after
2115 // those of the first load timing.
2116 EXPECT_LE(load_timing_info1.receive_headers_end,
2117 load_timing_info2.connect_timing.connect_start);
2118 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2119
2120 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2121 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2122 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
2123 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2124
2125 response = trans->GetResponseInfo();
2126 ASSERT_TRUE(response);
2127 EXPECT_FALSE(response->auth_challenge.get());
2128 EXPECT_EQ(100, response->headers->GetContentLength());
2129
2130 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2131 ASSERT_FALSE(endpoint.address().empty());
2132 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2133}
2134
[email protected]23e482282013-06-14 16:08:022135TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462136 HttpRequestInfo request;
2137 request.method = "GET";
bncce36dca22015-04-21 22:11:232138 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292139 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462140
mmenkee65e7af2015-10-13 17:16:422141 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272142 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412143 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272144
[email protected]861fcd52009-08-26 02:33:462145 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232146 MockWrite(
2147 "GET / HTTP/1.1\r\n"
2148 "Host: www.example.org\r\n"
2149 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462150 };
2151
2152 MockRead data_reads[] = {
2153 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2154 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2155 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2156 // Large content-length -- won't matter, as connection will be reset.
2157 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062158 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462159 };
2160
[email protected]31a2bfe2010-02-09 08:03:392161 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2162 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072163 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412164 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462165
[email protected]49639fa2011-12-20 23:22:412166 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462167 EXPECT_EQ(ERR_IO_PENDING, rv);
2168
2169 rv = callback.WaitForResult();
2170 EXPECT_EQ(0, rv);
2171
sclittlefb249892015-09-10 21:33:222172 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2173 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2174 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
[email protected]b8015c42013-12-24 15:18:192175 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2176
[email protected]861fcd52009-08-26 02:33:462177 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502178 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462179 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2180}
2181
[email protected]2d2697f92009-02-18 21:00:322182// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2183// connection.
[email protected]23e482282013-06-14 16:08:022184TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422185 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322186 request.method = "GET";
bncce36dca22015-04-21 22:11:232187 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322188 request.load_flags = 0;
2189
vishal.b62985ca92015-04-17 08:45:512190 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072191 session_deps_.net_log = &log;
mmenkee65e7af2015-10-13 17:16:422192 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272193
[email protected]2d2697f92009-02-18 21:00:322194 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232195 MockWrite(
2196 "GET / HTTP/1.1\r\n"
2197 "Host: www.example.org\r\n"
2198 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322199
bncce36dca22015-04-21 22:11:232200 // After calling trans->RestartWithAuth(), this is the request we should
2201 // be issuing -- the final header line contains the credentials.
2202 MockWrite(
2203 "GET / HTTP/1.1\r\n"
2204 "Host: www.example.org\r\n"
2205 "Connection: keep-alive\r\n"
2206 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322207 };
2208
2209 MockRead data_reads1[] = {
2210 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2211 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2212 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2213 MockRead("Content-Length: 14\r\n\r\n"),
2214 MockRead("Unauthorized\r\n"),
2215
2216 // Lastly, the server responds with the actual content.
2217 MockRead("HTTP/1.1 200 OK\r\n"),
2218 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502219 MockRead("Content-Length: 5\r\n\r\n"),
2220 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322221 };
2222
[email protected]2d0a4f92011-05-05 16:38:462223 // If there is a regression where we disconnect a Keep-Alive
2224 // connection during an auth roundtrip, we'll end up reading this.
2225 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062226 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462227 };
2228
[email protected]31a2bfe2010-02-09 08:03:392229 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2230 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462231 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2232 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072233 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2234 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322235
[email protected]49639fa2011-12-20 23:22:412236 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322237
[email protected]262eec82013-03-19 21:01:362238 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502239 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412240 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422241 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322242
2243 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422244 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322245
[email protected]58e32bb2013-01-21 18:23:252246 LoadTimingInfo load_timing_info1;
2247 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2248 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2249
[email protected]1c773ea12009-04-28 19:58:422250 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502251 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042252 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322253
[email protected]49639fa2011-12-20 23:22:412254 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322255
[email protected]49639fa2011-12-20 23:22:412256 rv = trans->RestartWithAuth(
2257 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422258 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322259
2260 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422261 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322262
[email protected]58e32bb2013-01-21 18:23:252263 LoadTimingInfo load_timing_info2;
2264 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2265 TestLoadTimingReused(load_timing_info2);
2266 // The load timing after restart should have the same socket ID, and times
2267 // those of the first load timing.
2268 EXPECT_LE(load_timing_info1.receive_headers_end,
2269 load_timing_info2.send_start);
2270 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2271
[email protected]2d2697f92009-02-18 21:00:322272 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502273 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322274 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502275 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192276
2277 std::string response_data;
2278 rv = ReadTransaction(trans.get(), &response_data);
2279 EXPECT_EQ(OK, rv);
sclittlefb249892015-09-10 21:33:222280
2281 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2282 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2283 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:192284 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322285}
2286
2287// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2288// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022289TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422290 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322291 request.method = "GET";
bncce36dca22015-04-21 22:11:232292 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322293 request.load_flags = 0;
2294
mmenkee65e7af2015-10-13 17:16:422295 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272296
[email protected]2d2697f92009-02-18 21:00:322297 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232298 MockWrite(
2299 "GET / HTTP/1.1\r\n"
2300 "Host: www.example.org\r\n"
2301 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322302
bncce36dca22015-04-21 22:11:232303 // After calling trans->RestartWithAuth(), this is the request we should
2304 // be issuing -- the final header line contains the credentials.
2305 MockWrite(
2306 "GET / HTTP/1.1\r\n"
2307 "Host: www.example.org\r\n"
2308 "Connection: keep-alive\r\n"
2309 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322310 };
2311
[email protected]2d2697f92009-02-18 21:00:322312 MockRead data_reads1[] = {
2313 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2314 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312315 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322316
2317 // Lastly, the server responds with the actual content.
2318 MockRead("HTTP/1.1 200 OK\r\n"),
2319 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502320 MockRead("Content-Length: 5\r\n\r\n"),
2321 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322322 };
2323
[email protected]2d0a4f92011-05-05 16:38:462324 // An incorrect reconnect would cause this to be read.
2325 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062326 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462327 };
2328
[email protected]31a2bfe2010-02-09 08:03:392329 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2330 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462331 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2332 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072333 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2334 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322335
[email protected]49639fa2011-12-20 23:22:412336 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322337
[email protected]262eec82013-03-19 21:01:362338 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502339 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412340 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422341 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322342
2343 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422344 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322345
[email protected]1c773ea12009-04-28 19:58:422346 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502347 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042348 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322349
[email protected]49639fa2011-12-20 23:22:412350 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322351
[email protected]49639fa2011-12-20 23:22:412352 rv = trans->RestartWithAuth(
2353 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422354 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322355
2356 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422357 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322358
2359 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502360 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322361 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502362 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322363}
2364
2365// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2366// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022367TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422368 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322369 request.method = "GET";
bncce36dca22015-04-21 22:11:232370 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322371 request.load_flags = 0;
2372
mmenkee65e7af2015-10-13 17:16:422373 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272374
[email protected]2d2697f92009-02-18 21:00:322375 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232376 MockWrite(
2377 "GET / HTTP/1.1\r\n"
2378 "Host: www.example.org\r\n"
2379 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322380
bncce36dca22015-04-21 22:11:232381 // After calling trans->RestartWithAuth(), this is the request we should
2382 // be issuing -- the final header line contains the credentials.
2383 MockWrite(
2384 "GET / HTTP/1.1\r\n"
2385 "Host: www.example.org\r\n"
2386 "Connection: keep-alive\r\n"
2387 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322388 };
2389
2390 // Respond with 5 kb of response body.
2391 std::string large_body_string("Unauthorized");
2392 large_body_string.append(5 * 1024, ' ');
2393 large_body_string.append("\r\n");
2394
2395 MockRead data_reads1[] = {
2396 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2397 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2398 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2399 // 5134 = 12 + 5 * 1024 + 2
2400 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062401 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322402
2403 // Lastly, the server responds with the actual content.
2404 MockRead("HTTP/1.1 200 OK\r\n"),
2405 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502406 MockRead("Content-Length: 5\r\n\r\n"),
2407 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322408 };
2409
[email protected]2d0a4f92011-05-05 16:38:462410 // An incorrect reconnect would cause this to be read.
2411 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062412 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462413 };
2414
[email protected]31a2bfe2010-02-09 08:03:392415 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2416 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462417 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2418 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072419 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2420 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322421
[email protected]49639fa2011-12-20 23:22:412422 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322423
[email protected]262eec82013-03-19 21:01:362424 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502425 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412426 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422427 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322428
2429 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422430 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322431
[email protected]1c773ea12009-04-28 19:58:422432 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502433 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042434 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322435
[email protected]49639fa2011-12-20 23:22:412436 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322437
[email protected]49639fa2011-12-20 23:22:412438 rv = trans->RestartWithAuth(
2439 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422440 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322441
2442 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422443 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322444
2445 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502446 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322447 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502448 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322449}
2450
2451// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312452// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022453TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312454 HttpRequestInfo request;
2455 request.method = "GET";
bncce36dca22015-04-21 22:11:232456 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312457 request.load_flags = 0;
2458
mmenkee65e7af2015-10-13 17:16:422459 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272460
[email protected]11203f012009-11-12 23:02:312461 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232462 MockWrite(
2463 "GET / HTTP/1.1\r\n"
2464 "Host: www.example.org\r\n"
2465 "Connection: keep-alive\r\n\r\n"),
2466 // This simulates the seemingly successful write to a closed connection
2467 // if the bug is not fixed.
2468 MockWrite(
2469 "GET / HTTP/1.1\r\n"
2470 "Host: www.example.org\r\n"
2471 "Connection: keep-alive\r\n"
2472 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312473 };
2474
2475 MockRead data_reads1[] = {
2476 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2477 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2478 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2479 MockRead("Content-Length: 14\r\n\r\n"),
2480 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062481 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312482 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062483 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312484 };
2485
2486 // After calling trans->RestartWithAuth(), this is the request we should
2487 // be issuing -- the final header line contains the credentials.
2488 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232489 MockWrite(
2490 "GET / HTTP/1.1\r\n"
2491 "Host: www.example.org\r\n"
2492 "Connection: keep-alive\r\n"
2493 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312494 };
2495
2496 // Lastly, the server responds with the actual content.
2497 MockRead data_reads2[] = {
2498 MockRead("HTTP/1.1 200 OK\r\n"),
2499 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502500 MockRead("Content-Length: 5\r\n\r\n"),
2501 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312502 };
2503
[email protected]31a2bfe2010-02-09 08:03:392504 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2505 data_writes1, arraysize(data_writes1));
2506 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2507 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072508 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2509 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312510
[email protected]49639fa2011-12-20 23:22:412511 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312512
[email protected]262eec82013-03-19 21:01:362513 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502514 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412515 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312516 EXPECT_EQ(ERR_IO_PENDING, rv);
2517
2518 rv = callback1.WaitForResult();
2519 EXPECT_EQ(OK, rv);
2520
2521 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502522 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042523 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312524
[email protected]49639fa2011-12-20 23:22:412525 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312526
[email protected]49639fa2011-12-20 23:22:412527 rv = trans->RestartWithAuth(
2528 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312529 EXPECT_EQ(ERR_IO_PENDING, rv);
2530
2531 rv = callback2.WaitForResult();
2532 EXPECT_EQ(OK, rv);
2533
2534 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502535 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312536 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502537 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312538}
2539
[email protected]394816e92010-08-03 07:38:592540// Test the request-challenge-retry sequence for basic auth, over a connection
2541// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012542TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2543 HttpRequestInfo request;
2544 request.method = "GET";
bncce36dca22015-04-21 22:11:232545 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012546 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292547 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012548
2549 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032550 session_deps_.proxy_service =
2551 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512552 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012553 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422554 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012555
2556 // Since we have proxy, should try to establish tunnel.
2557 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542558 MockWrite("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"),
ttuttle34f63b52015-03-05 04:33:012561 };
2562
mmenkee71e15332015-10-07 16:39:542563 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012564 // connection.
2565 MockRead data_reads1[] = {
2566 // No credentials.
2567 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2568 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542569 };
ttuttle34f63b52015-03-05 04:33:012570
mmenkee71e15332015-10-07 16:39:542571 // Since the first connection couldn't be reused, need to establish another
2572 // once given credentials.
2573 MockWrite data_writes2[] = {
2574 // After calling trans->RestartWithAuth(), this is the request we should
2575 // be issuing -- the final header line contains the credentials.
2576 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2577 "Host: www.example.org\r\n"
2578 "Proxy-Connection: keep-alive\r\n"
2579 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2580
2581 MockWrite("GET / HTTP/1.1\r\n"
2582 "Host: www.example.org\r\n"
2583 "Connection: keep-alive\r\n\r\n"),
2584 };
2585
2586 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012587 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2588
2589 MockRead("HTTP/1.1 200 OK\r\n"),
2590 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2591 MockRead("Content-Length: 5\r\n\r\n"),
2592 MockRead(SYNCHRONOUS, "hello"),
2593 };
2594
2595 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2596 data_writes1, arraysize(data_writes1));
2597 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542598 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2599 data_writes2, arraysize(data_writes2));
2600 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012601 SSLSocketDataProvider ssl(ASYNC, OK);
2602 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2603
2604 TestCompletionCallback callback1;
2605
2606 scoped_ptr<HttpTransaction> trans(
2607 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2608
2609 int rv = trans->Start(&request, callback1.callback(), log.bound());
2610 EXPECT_EQ(ERR_IO_PENDING, rv);
2611
2612 rv = callback1.WaitForResult();
2613 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462614 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012615 log.GetEntries(&entries);
2616 size_t pos = ExpectLogContainsSomewhere(
2617 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2618 NetLog::PHASE_NONE);
2619 ExpectLogContainsSomewhere(
2620 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2621 NetLog::PHASE_NONE);
2622
2623 const HttpResponseInfo* response = trans->GetResponseInfo();
2624 ASSERT_TRUE(response != NULL);
2625 EXPECT_FALSE(response->headers->IsKeepAlive());
2626 ASSERT_FALSE(response->headers.get() == NULL);
2627 EXPECT_EQ(407, response->headers->response_code());
2628 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2629 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2630
2631 LoadTimingInfo load_timing_info;
2632 // CONNECT requests and responses are handled at the connect job level, so
2633 // the transaction does not yet have a connection.
2634 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2635
2636 TestCompletionCallback callback2;
2637
2638 rv =
2639 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2640 EXPECT_EQ(ERR_IO_PENDING, rv);
2641
2642 rv = callback2.WaitForResult();
2643 EXPECT_EQ(OK, rv);
2644
2645 response = trans->GetResponseInfo();
2646 ASSERT_TRUE(response != NULL);
2647
2648 EXPECT_TRUE(response->headers->IsKeepAlive());
2649 EXPECT_EQ(200, response->headers->response_code());
2650 EXPECT_EQ(5, response->headers->GetContentLength());
2651 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2652
2653 // The password prompt info should not be set.
2654 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2655
2656 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2657 TestLoadTimingNotReusedWithPac(load_timing_info,
2658 CONNECT_TIMING_HAS_SSL_TIMES);
2659
2660 trans.reset();
2661 session->CloseAllConnections();
2662}
2663
2664// Test the request-challenge-retry sequence for basic auth, over a connection
2665// that requires a restart when setting up an SSL tunnel.
2666TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592667 HttpRequestInfo request;
2668 request.method = "GET";
bncce36dca22015-04-21 22:11:232669 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592670 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292671 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592672
[email protected]cb9bf6ca2011-01-28 13:15:272673 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032674 session_deps_.proxy_service =
2675 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512676 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072677 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422678 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272679
[email protected]394816e92010-08-03 07:38:592680 // Since we have proxy, should try to establish tunnel.
2681 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542682 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2683 "Host: www.example.org\r\n"
2684 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:112685 };
2686
mmenkee71e15332015-10-07 16:39:542687 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:082688 // connection.
2689 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:542690 // No credentials.
2691 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2692 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2693 MockRead("Proxy-Connection: close\r\n\r\n"),
2694 };
mmenkee0b5c882015-08-26 20:29:112695
mmenkee71e15332015-10-07 16:39:542696 MockWrite data_writes2[] = {
2697 // After calling trans->RestartWithAuth(), this is the request we should
2698 // be issuing -- the final header line contains the credentials.
2699 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2700 "Host: www.example.org\r\n"
2701 "Proxy-Connection: keep-alive\r\n"
2702 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:082703
mmenkee71e15332015-10-07 16:39:542704 MockWrite("GET / HTTP/1.1\r\n"
2705 "Host: www.example.org\r\n"
2706 "Connection: keep-alive\r\n\r\n"),
2707 };
2708
2709 MockRead data_reads2[] = {
2710 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2711
2712 MockRead("HTTP/1.1 200 OK\r\n"),
2713 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2714 MockRead("Content-Length: 5\r\n\r\n"),
2715 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592716 };
2717
2718 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2719 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072720 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542721 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2722 data_writes2, arraysize(data_writes2));
2723 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:062724 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072725 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592726
[email protected]49639fa2011-12-20 23:22:412727 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592728
[email protected]262eec82013-03-19 21:01:362729 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502730 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502731
[email protected]49639fa2011-12-20 23:22:412732 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592733 EXPECT_EQ(ERR_IO_PENDING, rv);
2734
2735 rv = callback1.WaitForResult();
2736 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462737 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402738 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592739 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402740 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592741 NetLog::PHASE_NONE);
2742 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402743 entries, pos,
[email protected]394816e92010-08-03 07:38:592744 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2745 NetLog::PHASE_NONE);
2746
2747 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502748 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012749 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502750 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592751 EXPECT_EQ(407, response->headers->response_code());
2752 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042753 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592754
[email protected]029c83b62013-01-24 05:28:202755 LoadTimingInfo load_timing_info;
2756 // CONNECT requests and responses are handled at the connect job level, so
2757 // the transaction does not yet have a connection.
2758 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2759
[email protected]49639fa2011-12-20 23:22:412760 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592761
[email protected]49639fa2011-12-20 23:22:412762 rv = trans->RestartWithAuth(
2763 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592764 EXPECT_EQ(ERR_IO_PENDING, rv);
2765
2766 rv = callback2.WaitForResult();
2767 EXPECT_EQ(OK, rv);
2768
2769 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502770 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592771
2772 EXPECT_TRUE(response->headers->IsKeepAlive());
2773 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502774 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592775 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2776
2777 // The password prompt info should not be set.
2778 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502779
[email protected]029c83b62013-01-24 05:28:202780 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2781 TestLoadTimingNotReusedWithPac(load_timing_info,
2782 CONNECT_TIMING_HAS_SSL_TIMES);
2783
[email protected]0b0bf032010-09-21 18:08:502784 trans.reset();
[email protected]102e27c2011-02-23 01:01:312785 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592786}
2787
[email protected]11203f012009-11-12 23:02:312788// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012789// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2790TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2791 HttpRequestInfo request;
2792 request.method = "GET";
bncce36dca22015-04-21 22:11:232793 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012794 // Ensure that proxy authentication is attempted even
2795 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292796 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012797
2798 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032799 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:512800 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012801 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422802 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012803
2804 scoped_ptr<HttpTransaction> trans(
2805 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2806
2807 // Since we have proxy, should try to establish tunnel.
2808 MockWrite data_writes1[] = {
2809 MockWrite(
bncce36dca22015-04-21 22:11:232810 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2811 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012812 "Proxy-Connection: keep-alive\r\n\r\n"),
2813
2814 // After calling trans->RestartWithAuth(), this is the request we should
2815 // be issuing -- the final header line contains the credentials.
2816 MockWrite(
bncce36dca22015-04-21 22:11:232817 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2818 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012819 "Proxy-Connection: keep-alive\r\n"
2820 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2821 };
2822
2823 // The proxy responds to the connect with a 407, using a persistent
2824 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2825 MockRead data_reads1[] = {
2826 // No credentials.
2827 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2828 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2829 MockRead("Proxy-Connection: keep-alive\r\n"),
2830 MockRead("Content-Length: 10\r\n\r\n"),
2831 MockRead("0123456789"),
2832
2833 // Wrong credentials (wrong password).
2834 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2835 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2836 MockRead("Proxy-Connection: keep-alive\r\n"),
2837 MockRead("Content-Length: 10\r\n\r\n"),
2838 // No response body because the test stops reading here.
2839 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2840 };
2841
2842 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2843 data_writes1, arraysize(data_writes1));
2844 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2845
2846 TestCompletionCallback callback1;
2847
2848 int rv = trans->Start(&request, callback1.callback(), log.bound());
2849 EXPECT_EQ(ERR_IO_PENDING, rv);
2850
2851 rv = callback1.WaitForResult();
2852 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462853 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012854 log.GetEntries(&entries);
2855 size_t pos = ExpectLogContainsSomewhere(
2856 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2857 NetLog::PHASE_NONE);
2858 ExpectLogContainsSomewhere(
2859 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2860 NetLog::PHASE_NONE);
2861
2862 const HttpResponseInfo* response = trans->GetResponseInfo();
2863 ASSERT_TRUE(response);
2864 ASSERT_TRUE(response->headers);
2865 EXPECT_TRUE(response->headers->IsKeepAlive());
2866 EXPECT_EQ(407, response->headers->response_code());
2867 EXPECT_EQ(10, response->headers->GetContentLength());
2868 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2869 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2870
2871 TestCompletionCallback callback2;
2872
2873 // Wrong password (should be "bar").
2874 rv =
2875 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2876 EXPECT_EQ(ERR_IO_PENDING, rv);
2877
2878 rv = callback2.WaitForResult();
2879 EXPECT_EQ(OK, rv);
2880
2881 response = trans->GetResponseInfo();
2882 ASSERT_TRUE(response);
2883 ASSERT_TRUE(response->headers);
2884 EXPECT_TRUE(response->headers->IsKeepAlive());
2885 EXPECT_EQ(407, response->headers->response_code());
2886 EXPECT_EQ(10, response->headers->GetContentLength());
2887 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2888 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2889
2890 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2891 // out of scope.
2892 session->CloseAllConnections();
2893}
2894
2895// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2896// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2897TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272898 HttpRequestInfo request;
2899 request.method = "GET";
bncce36dca22015-04-21 22:11:232900 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272901 // Ensure that proxy authentication is attempted even
2902 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292903 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:272904
[email protected]2d2697f92009-02-18 21:00:322905 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032906 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:512907 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072908 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422909 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322910
[email protected]262eec82013-03-19 21:01:362911 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502912 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322913
[email protected]2d2697f92009-02-18 21:00:322914 // Since we have proxy, should try to establish tunnel.
2915 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232916 MockWrite(
2917 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2918 "Host: www.example.org\r\n"
2919 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322920
bncce36dca22015-04-21 22:11:232921 // After calling trans->RestartWithAuth(), this is the request we should
2922 // be issuing -- the final header line contains the credentials.
2923 MockWrite(
2924 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2925 "Host: www.example.org\r\n"
2926 "Proxy-Connection: keep-alive\r\n"
2927 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322928 };
2929
2930 // The proxy responds to the connect with a 407, using a persistent
2931 // connection.
2932 MockRead data_reads1[] = {
2933 // No credentials.
2934 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2935 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2936 MockRead("Content-Length: 10\r\n\r\n"),
2937 MockRead("0123456789"),
2938
2939 // Wrong credentials (wrong password).
2940 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2941 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2942 MockRead("Content-Length: 10\r\n\r\n"),
2943 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062944 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322945 };
2946
[email protected]31a2bfe2010-02-09 08:03:392947 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2948 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072949 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322950
[email protected]49639fa2011-12-20 23:22:412951 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322952
[email protected]49639fa2011-12-20 23:22:412953 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422954 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322955
2956 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422957 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462958 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402959 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392960 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402961 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392962 NetLog::PHASE_NONE);
2963 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402964 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392965 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2966 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322967
[email protected]1c773ea12009-04-28 19:58:422968 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242969 ASSERT_TRUE(response);
2970 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322971 EXPECT_TRUE(response->headers->IsKeepAlive());
2972 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012973 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422974 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042975 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322976
[email protected]49639fa2011-12-20 23:22:412977 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322978
2979 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412980 rv = trans->RestartWithAuth(
2981 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422982 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322983
2984 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422985 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322986
2987 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242988 ASSERT_TRUE(response);
2989 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322990 EXPECT_TRUE(response->headers->IsKeepAlive());
2991 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012992 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422993 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042994 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132995
[email protected]e60e47a2010-07-14 03:37:182996 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2997 // out of scope.
[email protected]102e27c2011-02-23 01:01:312998 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322999}
3000
mmenkee71e15332015-10-07 16:39:543001// Test the case a proxy closes a socket while the challenge body is being
3002// drained.
3003TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
3004 HttpRequestInfo request;
3005 request.method = "GET";
3006 request.url = GURL("https://www.example.org/");
3007 // Ensure that proxy authentication is attempted even
3008 // when the no authentication data flag is set.
3009 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3010
3011 // Configure against proxy server "myproxy:70".
3012 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:423013 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543014
3015 scoped_ptr<HttpTransaction> trans(
3016 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3017
3018 // Since we have proxy, should try to establish tunnel.
3019 MockWrite data_writes1[] = {
3020 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3021 "Host: www.example.org\r\n"
3022 "Proxy-Connection: keep-alive\r\n\r\n"),
3023 };
3024
3025 // The proxy responds to the connect with a 407, using a persistent
3026 // connection.
3027 MockRead data_reads1[] = {
3028 // No credentials.
3029 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3030 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3031 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3032 // Server hands up in the middle of the body.
3033 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3034 };
3035
3036 MockWrite data_writes2[] = {
3037 // After calling trans->RestartWithAuth(), this is the request we should
3038 // be issuing -- the final header line contains the credentials.
3039 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3040 "Host: www.example.org\r\n"
3041 "Proxy-Connection: keep-alive\r\n"
3042 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3043
3044 MockWrite("GET / HTTP/1.1\r\n"
3045 "Host: www.example.org\r\n"
3046 "Connection: keep-alive\r\n\r\n"),
3047 };
3048
3049 MockRead data_reads2[] = {
3050 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3051
3052 MockRead("HTTP/1.1 200 OK\r\n"),
3053 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3054 MockRead("Content-Length: 5\r\n\r\n"),
3055 MockRead(SYNCHRONOUS, "hello"),
3056 };
3057
3058 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3059 data_writes1, arraysize(data_writes1));
3060 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3061 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3062 data_writes2, arraysize(data_writes2));
3063 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3064 SSLSocketDataProvider ssl(ASYNC, OK);
3065 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3066
3067 TestCompletionCallback callback;
3068
3069 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3070 EXPECT_EQ(OK, callback.GetResult(rv));
3071
3072 const HttpResponseInfo* response = trans->GetResponseInfo();
3073 ASSERT_TRUE(response);
3074 ASSERT_TRUE(response->headers);
3075 EXPECT_TRUE(response->headers->IsKeepAlive());
3076 EXPECT_EQ(407, response->headers->response_code());
3077 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3078
3079 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
3080 EXPECT_EQ(OK, callback.GetResult(rv));
3081
3082 response = trans->GetResponseInfo();
3083 ASSERT_TRUE(response);
3084 ASSERT_TRUE(response->headers);
3085 EXPECT_TRUE(response->headers->IsKeepAlive());
3086 EXPECT_EQ(200, response->headers->response_code());
3087 std::string body;
3088 EXPECT_EQ(OK, ReadTransaction(trans.get(), &body));
3089 EXPECT_EQ("hello", body);
3090}
3091
[email protected]a8e9b162009-03-12 00:06:443092// Test that we don't read the response body when we fail to establish a tunnel,
3093// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:023094TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273095 HttpRequestInfo request;
3096 request.method = "GET";
bncce36dca22015-04-21 22:11:233097 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273098 request.load_flags = 0;
3099
[email protected]a8e9b162009-03-12 00:06:443100 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033101 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443102
mmenkee65e7af2015-10-13 17:16:423103 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443104
[email protected]262eec82013-03-19 21:01:363105 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503106 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:443107
[email protected]a8e9b162009-03-12 00:06:443108 // Since we have proxy, should try to establish tunnel.
3109 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:233110 MockWrite(
3111 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3112 "Host: www.example.org\r\n"
3113 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443114 };
3115
3116 // The proxy responds to the connect with a 407.
3117 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243118 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3119 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3120 MockRead("Content-Length: 10\r\n\r\n"),
3121 MockRead("0123456789"), // Should not be reached.
3122 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443123 };
3124
[email protected]31a2bfe2010-02-09 08:03:393125 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3126 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073127 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443128
[email protected]49639fa2011-12-20 23:22:413129 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443130
[email protected]49639fa2011-12-20 23:22:413131 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423132 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:443133
3134 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423135 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:443136
[email protected]1c773ea12009-04-28 19:58:423137 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243138 ASSERT_TRUE(response);
3139 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443140 EXPECT_TRUE(response->headers->IsKeepAlive());
3141 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423142 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443143
3144 std::string response_data;
3145 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423146 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:183147
3148 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313149 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443150}
3151
ttuttle7933c112015-01-06 00:55:243152// Test that we don't pass extraneous headers from the proxy's response to the
3153// caller when the proxy responds to CONNECT with 407.
3154TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
3155 HttpRequestInfo request;
3156 request.method = "GET";
bncce36dca22015-04-21 22:11:233157 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243158 request.load_flags = 0;
3159
3160 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033161 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243162
mmenkee65e7af2015-10-13 17:16:423163 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243164
3165 scoped_ptr<HttpTransaction> trans(
3166 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3167
3168 // Since we have proxy, should try to establish tunnel.
3169 MockWrite data_writes[] = {
3170 MockWrite(
bncce36dca22015-04-21 22:11:233171 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3172 "Host: www.example.org\r\n"
ttuttle7933c112015-01-06 00:55:243173 "Proxy-Connection: keep-alive\r\n\r\n"),
3174 };
3175
3176 // The proxy responds to the connect with a 407.
3177 MockRead data_reads[] = {
3178 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3179 MockRead("X-Foo: bar\r\n"),
3180 MockRead("Set-Cookie: foo=bar\r\n"),
3181 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3182 MockRead("Content-Length: 10\r\n\r\n"),
3183 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
3184 };
3185
3186 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3187 arraysize(data_writes));
3188 session_deps_.socket_factory->AddSocketDataProvider(&data);
3189
3190 TestCompletionCallback callback;
3191
3192 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3193 EXPECT_EQ(ERR_IO_PENDING, rv);
3194
3195 rv = callback.WaitForResult();
3196 EXPECT_EQ(OK, rv);
3197
3198 const HttpResponseInfo* response = trans->GetResponseInfo();
3199 ASSERT_TRUE(response);
3200 ASSERT_TRUE(response->headers);
3201 EXPECT_TRUE(response->headers->IsKeepAlive());
3202 EXPECT_EQ(407, response->headers->response_code());
3203 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3204 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3205 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3206
3207 std::string response_data;
3208 rv = ReadTransaction(trans.get(), &response_data);
3209 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3210
3211 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3212 session->CloseAllConnections();
3213}
3214
[email protected]8fdbcd22010-05-05 02:54:523215// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3216// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:023217TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523218 HttpRequestInfo request;
3219 request.method = "GET";
bncce36dca22015-04-21 22:11:233220 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523221 request.load_flags = 0;
3222
[email protected]cb9bf6ca2011-01-28 13:15:273223 // We are using a DIRECT connection (i.e. no proxy) for this session.
mmenkee65e7af2015-10-13 17:16:423224 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273225 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:413226 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:273227
[email protected]8fdbcd22010-05-05 02:54:523228 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233229 MockWrite(
3230 "GET / HTTP/1.1\r\n"
3231 "Host: www.example.org\r\n"
3232 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523233 };
3234
3235 MockRead data_reads1[] = {
3236 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3237 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3238 // Large content-length -- won't matter, as connection will be reset.
3239 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063240 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523241 };
3242
3243 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3244 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073245 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523246
[email protected]49639fa2011-12-20 23:22:413247 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523248
[email protected]49639fa2011-12-20 23:22:413249 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523250 EXPECT_EQ(ERR_IO_PENDING, rv);
3251
3252 rv = callback.WaitForResult();
3253 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3254}
3255
[email protected]7a67a8152010-11-05 18:31:103256// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3257// through a non-authenticating proxy. The request should fail with
3258// ERR_UNEXPECTED_PROXY_AUTH.
3259// Note that it is impossible to detect if an HTTP server returns a 407 through
3260// a non-authenticating proxy - there is nothing to indicate whether the
3261// response came from the proxy or the server, so it is treated as if the proxy
3262// issued the challenge.
[email protected]23e482282013-06-14 16:08:023263TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233264 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273265 HttpRequestInfo request;
3266 request.method = "GET";
bncce36dca22015-04-21 22:11:233267 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273268
rdsmith82957ad2015-09-16 19:42:033269 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513270 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073271 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423272 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103273
[email protected]7a67a8152010-11-05 18:31:103274 // Since we have proxy, should try to establish tunnel.
3275 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233276 MockWrite(
3277 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3278 "Host: www.example.org\r\n"
3279 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103280
bncce36dca22015-04-21 22:11:233281 MockWrite(
3282 "GET / HTTP/1.1\r\n"
3283 "Host: www.example.org\r\n"
3284 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103285 };
3286
3287 MockRead data_reads1[] = {
3288 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3289
3290 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3291 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3292 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063293 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103294 };
3295
3296 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3297 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073298 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063299 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073300 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103301
[email protected]49639fa2011-12-20 23:22:413302 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103303
[email protected]262eec82013-03-19 21:01:363304 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503305 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103306
[email protected]49639fa2011-12-20 23:22:413307 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103308 EXPECT_EQ(ERR_IO_PENDING, rv);
3309
3310 rv = callback1.WaitForResult();
3311 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463312 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403313 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103314 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403315 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103316 NetLog::PHASE_NONE);
3317 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403318 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103319 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3320 NetLog::PHASE_NONE);
3321}
[email protected]2df19bb2010-08-25 20:13:463322
mmenke2a1781d2015-10-07 19:25:333323// Test a proxy auth scheme that allows default credentials and a proxy server
3324// that uses non-persistent connections.
3325TEST_P(HttpNetworkTransactionTest,
3326 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3327 HttpRequestInfo request;
3328 request.method = "GET";
3329 request.url = GURL("https://www.example.org/");
3330
3331 // Configure against proxy server "myproxy:70".
3332 session_deps_.proxy_service =
3333 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3334
3335 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3336 new HttpAuthHandlerMock::Factory());
3337 auth_handler_factory->set_do_init_from_challenge(true);
3338 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3339 mock_handler->set_allows_default_credentials(true);
3340 auth_handler_factory->AddMockHandler(mock_handler.release(),
3341 HttpAuth::AUTH_PROXY);
3342 session_deps_.http_auth_handler_factory = auth_handler_factory.Pass();
3343
3344 // Add NetLog just so can verify load timing information gets a NetLog ID.
3345 NetLog net_log;
3346 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423347 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333348
3349 // Since we have proxy, should try to establish tunnel.
3350 MockWrite data_writes1[] = {
3351 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3352 "Host: www.example.org\r\n"
3353 "Proxy-Connection: keep-alive\r\n\r\n"),
3354 };
3355
3356 // The proxy responds to the connect with a 407, using a non-persistent
3357 // connection.
3358 MockRead data_reads1[] = {
3359 // No credentials.
3360 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3361 MockRead("Proxy-Authenticate: Mock\r\n"),
3362 MockRead("Proxy-Connection: close\r\n\r\n"),
3363 };
3364
3365 // Since the first connection couldn't be reused, need to establish another
3366 // once given credentials.
3367 MockWrite data_writes2[] = {
3368 // After calling trans->RestartWithAuth(), this is the request we should
3369 // be issuing -- the final header line contains the credentials.
3370 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3371 "Host: www.example.org\r\n"
3372 "Proxy-Connection: keep-alive\r\n"
3373 "Proxy-Authorization: auth_token\r\n\r\n"),
3374
3375 MockWrite("GET / HTTP/1.1\r\n"
3376 "Host: www.example.org\r\n"
3377 "Connection: keep-alive\r\n\r\n"),
3378 };
3379
3380 MockRead data_reads2[] = {
3381 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3382
3383 MockRead("HTTP/1.1 200 OK\r\n"),
3384 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3385 MockRead("Content-Length: 5\r\n\r\n"),
3386 MockRead(SYNCHRONOUS, "hello"),
3387 };
3388
3389 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3390 data_writes1, arraysize(data_writes1));
3391 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3392 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3393 data_writes2, arraysize(data_writes2));
3394 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3395 SSLSocketDataProvider ssl(ASYNC, OK);
3396 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3397
3398 scoped_ptr<HttpTransaction> trans(
3399 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3400
3401 TestCompletionCallback callback;
3402 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3403 EXPECT_EQ(OK, callback.GetResult(rv));
3404
3405 const HttpResponseInfo* response = trans->GetResponseInfo();
3406 ASSERT_TRUE(response);
3407 ASSERT_TRUE(response->headers);
3408 EXPECT_FALSE(response->headers->IsKeepAlive());
3409 EXPECT_EQ(407, response->headers->response_code());
3410 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3411 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3412 EXPECT_FALSE(response->auth_challenge.get());
3413
3414 LoadTimingInfo load_timing_info;
3415 // CONNECT requests and responses are handled at the connect job level, so
3416 // the transaction does not yet have a connection.
3417 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3418
3419 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3420 EXPECT_EQ(OK, callback.GetResult(rv));
3421 response = trans->GetResponseInfo();
3422 ASSERT_TRUE(response);
3423 ASSERT_TRUE(response->headers);
3424 EXPECT_TRUE(response->headers->IsKeepAlive());
3425 EXPECT_EQ(200, response->headers->response_code());
3426 EXPECT_EQ(5, response->headers->GetContentLength());
3427 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3428
3429 // The password prompt info should not be set.
3430 EXPECT_FALSE(response->auth_challenge);
3431
3432 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3433 TestLoadTimingNotReusedWithPac(load_timing_info,
3434 CONNECT_TIMING_HAS_SSL_TIMES);
3435
3436 trans.reset();
3437 session->CloseAllConnections();
3438}
3439
3440// Test a proxy auth scheme that allows default credentials and a proxy server
3441// that hangs up when credentials are initially sent.
3442TEST_P(HttpNetworkTransactionTest,
3443 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3444 HttpRequestInfo request;
3445 request.method = "GET";
3446 request.url = GURL("https://www.example.org/");
3447
3448 // Configure against proxy server "myproxy:70".
3449 session_deps_.proxy_service =
3450 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3451
3452 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3453 new HttpAuthHandlerMock::Factory());
3454 auth_handler_factory->set_do_init_from_challenge(true);
3455 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3456 mock_handler->set_allows_default_credentials(true);
3457 auth_handler_factory->AddMockHandler(mock_handler.release(),
3458 HttpAuth::AUTH_PROXY);
3459 session_deps_.http_auth_handler_factory = auth_handler_factory.Pass();
3460
3461 // Add NetLog just so can verify load timing information gets a NetLog ID.
3462 NetLog net_log;
3463 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423464 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333465
3466 // Should try to establish tunnel.
3467 MockWrite data_writes1[] = {
3468 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3469 "Host: www.example.org\r\n"
3470 "Proxy-Connection: keep-alive\r\n\r\n"),
3471
3472 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3473 "Host: www.example.org\r\n"
3474 "Proxy-Connection: keep-alive\r\n"
3475 "Proxy-Authorization: auth_token\r\n\r\n"),
3476 };
3477
3478 // The proxy responds to the connect with a 407, using a non-persistent
3479 // connection.
3480 MockRead data_reads1[] = {
3481 // No credentials.
3482 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3483 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3484 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3485 };
3486
3487 // Since the first connection was closed, need to establish another once given
3488 // credentials.
3489 MockWrite data_writes2[] = {
3490 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3491 "Host: www.example.org\r\n"
3492 "Proxy-Connection: keep-alive\r\n"
3493 "Proxy-Authorization: auth_token\r\n\r\n"),
3494
3495 MockWrite("GET / HTTP/1.1\r\n"
3496 "Host: www.example.org\r\n"
3497 "Connection: keep-alive\r\n\r\n"),
3498 };
3499
3500 MockRead data_reads2[] = {
3501 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3502
3503 MockRead("HTTP/1.1 200 OK\r\n"),
3504 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3505 MockRead("Content-Length: 5\r\n\r\n"),
3506 MockRead(SYNCHRONOUS, "hello"),
3507 };
3508
3509 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3510 data_writes1, arraysize(data_writes1));
3511 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3512 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3513 data_writes2, arraysize(data_writes2));
3514 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3515 SSLSocketDataProvider ssl(ASYNC, OK);
3516 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3517
3518 scoped_ptr<HttpTransaction> trans(
3519 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3520
3521 TestCompletionCallback callback;
3522 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3523 EXPECT_EQ(OK, callback.GetResult(rv));
3524
3525 const HttpResponseInfo* response = trans->GetResponseInfo();
3526 ASSERT_TRUE(response);
3527 ASSERT_TRUE(response->headers);
3528 EXPECT_TRUE(response->headers->IsKeepAlive());
3529 EXPECT_EQ(407, response->headers->response_code());
3530 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3531 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3532 EXPECT_FALSE(response->auth_challenge);
3533
3534 LoadTimingInfo load_timing_info;
3535 // CONNECT requests and responses are handled at the connect job level, so
3536 // the transaction does not yet have a connection.
3537 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3538
3539 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3540 EXPECT_EQ(OK, callback.GetResult(rv));
3541
3542 response = trans->GetResponseInfo();
3543 ASSERT_TRUE(response);
3544 ASSERT_TRUE(response->headers);
3545 EXPECT_TRUE(response->headers->IsKeepAlive());
3546 EXPECT_EQ(200, response->headers->response_code());
3547 EXPECT_EQ(5, response->headers->GetContentLength());
3548 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3549
3550 // The password prompt info should not be set.
3551 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3552
3553 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3554 TestLoadTimingNotReusedWithPac(load_timing_info,
3555 CONNECT_TIMING_HAS_SSL_TIMES);
3556
3557 trans.reset();
3558 session->CloseAllConnections();
3559}
3560
3561// Test a proxy auth scheme that allows default credentials and a proxy server
3562// that hangs up when credentials are initially sent, and hangs up again when
3563// they are retried.
3564TEST_P(HttpNetworkTransactionTest,
3565 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
3566 HttpRequestInfo request;
3567 request.method = "GET";
3568 request.url = GURL("https://www.example.org/");
3569
3570 // Configure against proxy server "myproxy:70".
3571 session_deps_.proxy_service =
3572 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3573
3574 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3575 new HttpAuthHandlerMock::Factory());
3576 auth_handler_factory->set_do_init_from_challenge(true);
3577 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3578 mock_handler->set_allows_default_credentials(true);
3579 auth_handler_factory->AddMockHandler(mock_handler.release(),
3580 HttpAuth::AUTH_PROXY);
3581 session_deps_.http_auth_handler_factory = auth_handler_factory.Pass();
3582
3583 // Add NetLog just so can verify load timing information gets a NetLog ID.
3584 NetLog net_log;
3585 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423586 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333587
3588 // Should try to establish tunnel.
3589 MockWrite data_writes1[] = {
3590 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3591 "Host: www.example.org\r\n"
3592 "Proxy-Connection: keep-alive\r\n\r\n"),
3593
3594 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3595 "Host: www.example.org\r\n"
3596 "Proxy-Connection: keep-alive\r\n"
3597 "Proxy-Authorization: auth_token\r\n\r\n"),
3598 };
3599
3600 // The proxy responds to the connect with a 407, and then hangs up after the
3601 // second request is sent.
3602 MockRead data_reads1[] = {
3603 // No credentials.
3604 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3605 MockRead("Content-Length: 0\r\n"),
3606 MockRead("Proxy-Connection: keep-alive\r\n"),
3607 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3608 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3609 };
3610
3611 // HttpNetworkTransaction sees a reused connection that was closed with
3612 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
3613 // request.
3614 MockWrite data_writes2[] = {
3615 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3616 "Host: www.example.org\r\n"
3617 "Proxy-Connection: keep-alive\r\n\r\n"),
3618 };
3619
3620 // The proxy, having had more than enough of us, just hangs up.
3621 MockRead data_reads2[] = {
3622 // No credentials.
3623 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3624 };
3625
3626 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3627 data_writes1, arraysize(data_writes1));
3628 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3629 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3630 data_writes2, arraysize(data_writes2));
3631 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3632
3633 scoped_ptr<HttpTransaction> trans(
3634 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3635
3636 TestCompletionCallback callback;
3637 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3638 EXPECT_EQ(OK, callback.GetResult(rv));
3639
3640 const HttpResponseInfo* response = trans->GetResponseInfo();
3641 ASSERT_TRUE(response);
3642 ASSERT_TRUE(response->headers);
3643 EXPECT_TRUE(response->headers->IsKeepAlive());
3644 EXPECT_EQ(407, response->headers->response_code());
3645 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3646 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3647 EXPECT_FALSE(response->auth_challenge);
3648
3649 LoadTimingInfo load_timing_info;
3650 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3651
3652 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3653 EXPECT_EQ(ERR_EMPTY_RESPONSE, callback.GetResult(rv));
3654
3655 trans.reset();
3656 session->CloseAllConnections();
3657}
3658
3659// Test a proxy auth scheme that allows default credentials and a proxy server
3660// that hangs up when credentials are initially sent, and sends a challenge
3661// again they are retried.
3662TEST_P(HttpNetworkTransactionTest,
3663 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
3664 HttpRequestInfo request;
3665 request.method = "GET";
3666 request.url = GURL("https://www.example.org/");
3667
3668 // Configure against proxy server "myproxy:70".
3669 session_deps_.proxy_service =
3670 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3671
3672 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3673 new HttpAuthHandlerMock::Factory());
3674 auth_handler_factory->set_do_init_from_challenge(true);
3675 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3676 mock_handler->set_allows_default_credentials(true);
3677 auth_handler_factory->AddMockHandler(mock_handler.release(),
3678 HttpAuth::AUTH_PROXY);
3679 // Add another handler for the second challenge. It supports default
3680 // credentials, but they shouldn't be used, since they were already tried.
3681 mock_handler.reset(new HttpAuthHandlerMock());
3682 mock_handler->set_allows_default_credentials(true);
3683 auth_handler_factory->AddMockHandler(mock_handler.release(),
3684 HttpAuth::AUTH_PROXY);
3685 session_deps_.http_auth_handler_factory = auth_handler_factory.Pass();
3686
3687 // Add NetLog just so can verify load timing information gets a NetLog ID.
3688 NetLog net_log;
3689 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423690 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333691
3692 // Should try to establish tunnel.
3693 MockWrite data_writes1[] = {
3694 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3695 "Host: www.example.org\r\n"
3696 "Proxy-Connection: keep-alive\r\n\r\n"),
3697 };
3698
3699 // The proxy responds to the connect with a 407, using a non-persistent
3700 // connection.
3701 MockRead data_reads1[] = {
3702 // No credentials.
3703 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3704 MockRead("Proxy-Authenticate: Mock\r\n"),
3705 MockRead("Proxy-Connection: close\r\n\r\n"),
3706 };
3707
3708 // Since the first connection was closed, need to establish another once given
3709 // credentials.
3710 MockWrite data_writes2[] = {
3711 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3712 "Host: www.example.org\r\n"
3713 "Proxy-Connection: keep-alive\r\n"
3714 "Proxy-Authorization: auth_token\r\n\r\n"),
3715 };
3716
3717 MockRead data_reads2[] = {
3718 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3719 MockRead("Proxy-Authenticate: Mock\r\n"),
3720 MockRead("Proxy-Connection: close\r\n\r\n"),
3721 };
3722
3723 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3724 data_writes1, arraysize(data_writes1));
3725 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3726 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3727 data_writes2, arraysize(data_writes2));
3728 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3729 SSLSocketDataProvider ssl(ASYNC, OK);
3730 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3731
3732 scoped_ptr<HttpTransaction> trans(
3733 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3734
3735 TestCompletionCallback callback;
3736 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3737 EXPECT_EQ(OK, callback.GetResult(rv));
3738
3739 const HttpResponseInfo* response = trans->GetResponseInfo();
3740 ASSERT_TRUE(response);
3741 ASSERT_TRUE(response->headers);
3742 EXPECT_EQ(407, response->headers->response_code());
3743 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3744 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3745 EXPECT_FALSE(response->auth_challenge);
3746
3747 LoadTimingInfo load_timing_info;
3748 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3749
3750 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3751 EXPECT_EQ(OK, callback.GetResult(rv));
3752 response = trans->GetResponseInfo();
3753 ASSERT_TRUE(response);
3754 ASSERT_TRUE(response->headers);
3755 EXPECT_EQ(407, response->headers->response_code());
3756 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3757 EXPECT_TRUE(response->auth_challenge);
3758
3759 trans.reset();
3760 session->CloseAllConnections();
3761}
3762
[email protected]029c83b62013-01-24 05:28:203763// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023764TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203765 HttpRequestInfo request1;
3766 request1.method = "GET";
bncce36dca22015-04-21 22:11:233767 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203768
3769 HttpRequestInfo request2;
3770 request2.method = "GET";
bncce36dca22015-04-21 22:11:233771 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203772
3773 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033774 session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513775 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073776 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423777 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203778
3779 // Since we have proxy, should try to establish tunnel.
3780 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233781 MockWrite(
3782 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3783 "Host: www.example.org\r\n"
3784 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203785
bncce36dca22015-04-21 22:11:233786 MockWrite(
3787 "GET /1 HTTP/1.1\r\n"
3788 "Host: www.example.org\r\n"
3789 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203790
bncce36dca22015-04-21 22:11:233791 MockWrite(
3792 "GET /2 HTTP/1.1\r\n"
3793 "Host: www.example.org\r\n"
3794 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203795 };
3796
3797 // The proxy responds to the connect with a 407, using a persistent
3798 // connection.
3799 MockRead data_reads1[] = {
3800 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3801
3802 MockRead("HTTP/1.1 200 OK\r\n"),
3803 MockRead("Content-Length: 1\r\n\r\n"),
3804 MockRead(SYNCHRONOUS, "1"),
3805
3806 MockRead("HTTP/1.1 200 OK\r\n"),
3807 MockRead("Content-Length: 2\r\n\r\n"),
3808 MockRead(SYNCHRONOUS, "22"),
3809 };
3810
3811 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3812 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073813 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203814 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073815 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203816
3817 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363818 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503819 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203820
3821 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3822 EXPECT_EQ(ERR_IO_PENDING, rv);
3823
3824 rv = callback1.WaitForResult();
3825 EXPECT_EQ(OK, rv);
3826
3827 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3828 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503829 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203830 EXPECT_EQ(1, response1->headers->GetContentLength());
3831
3832 LoadTimingInfo load_timing_info1;
3833 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3834 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3835
3836 trans1.reset();
3837
3838 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363839 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503840 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203841
3842 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3843 EXPECT_EQ(ERR_IO_PENDING, rv);
3844
3845 rv = callback2.WaitForResult();
3846 EXPECT_EQ(OK, rv);
3847
3848 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3849 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503850 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203851 EXPECT_EQ(2, response2->headers->GetContentLength());
3852
3853 LoadTimingInfo load_timing_info2;
3854 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3855 TestLoadTimingReused(load_timing_info2);
3856
3857 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3858
3859 trans2.reset();
3860 session->CloseAllConnections();
3861}
3862
3863// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023864TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203865 HttpRequestInfo request1;
3866 request1.method = "GET";
bncce36dca22015-04-21 22:11:233867 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203868
3869 HttpRequestInfo request2;
3870 request2.method = "GET";
bncce36dca22015-04-21 22:11:233871 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203872
3873 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033874 session_deps_.proxy_service =
3875 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513876 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073877 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423878 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203879
3880 // Since we have proxy, should try to establish tunnel.
3881 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233882 MockWrite(
3883 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3884 "Host: www.example.org\r\n"
3885 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203886
bncce36dca22015-04-21 22:11:233887 MockWrite(
3888 "GET /1 HTTP/1.1\r\n"
3889 "Host: www.example.org\r\n"
3890 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203891
bncce36dca22015-04-21 22:11:233892 MockWrite(
3893 "GET /2 HTTP/1.1\r\n"
3894 "Host: www.example.org\r\n"
3895 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203896 };
3897
3898 // The proxy responds to the connect with a 407, using a persistent
3899 // connection.
3900 MockRead data_reads1[] = {
3901 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3902
3903 MockRead("HTTP/1.1 200 OK\r\n"),
3904 MockRead("Content-Length: 1\r\n\r\n"),
3905 MockRead(SYNCHRONOUS, "1"),
3906
3907 MockRead("HTTP/1.1 200 OK\r\n"),
3908 MockRead("Content-Length: 2\r\n\r\n"),
3909 MockRead(SYNCHRONOUS, "22"),
3910 };
3911
3912 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3913 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073914 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203915 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073916 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203917
3918 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363919 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503920 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203921
3922 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3923 EXPECT_EQ(ERR_IO_PENDING, rv);
3924
3925 rv = callback1.WaitForResult();
3926 EXPECT_EQ(OK, rv);
3927
3928 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3929 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503930 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203931 EXPECT_EQ(1, response1->headers->GetContentLength());
3932
3933 LoadTimingInfo load_timing_info1;
3934 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3935 TestLoadTimingNotReusedWithPac(load_timing_info1,
3936 CONNECT_TIMING_HAS_SSL_TIMES);
3937
3938 trans1.reset();
3939
3940 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363941 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503942 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203943
3944 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3945 EXPECT_EQ(ERR_IO_PENDING, rv);
3946
3947 rv = callback2.WaitForResult();
3948 EXPECT_EQ(OK, rv);
3949
3950 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3951 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503952 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203953 EXPECT_EQ(2, response2->headers->GetContentLength());
3954
3955 LoadTimingInfo load_timing_info2;
3956 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3957 TestLoadTimingReusedWithPac(load_timing_info2);
3958
3959 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3960
3961 trans2.reset();
3962 session->CloseAllConnections();
3963}
3964
[email protected]2df19bb2010-08-25 20:13:463965// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023966TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273967 HttpRequestInfo request;
3968 request.method = "GET";
bncce36dca22015-04-21 22:11:233969 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273970
[email protected]2df19bb2010-08-25 20:13:463971 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033972 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513973 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073974 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423975 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463976
[email protected]2df19bb2010-08-25 20:13:463977 // Since we have proxy, should use full url
3978 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233979 MockWrite(
3980 "GET http://www.example.org/ HTTP/1.1\r\n"
3981 "Host: www.example.org\r\n"
3982 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:463983 };
3984
3985 MockRead data_reads1[] = {
3986 MockRead("HTTP/1.1 200 OK\r\n"),
3987 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3988 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063989 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463990 };
3991
3992 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3993 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073994 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063995 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073996 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463997
[email protected]49639fa2011-12-20 23:22:413998 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463999
[email protected]262eec82013-03-19 21:01:364000 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504001 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504002
[email protected]49639fa2011-12-20 23:22:414003 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464004 EXPECT_EQ(ERR_IO_PENDING, rv);
4005
4006 rv = callback1.WaitForResult();
4007 EXPECT_EQ(OK, rv);
4008
[email protected]58e32bb2013-01-21 18:23:254009 LoadTimingInfo load_timing_info;
4010 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4011 TestLoadTimingNotReused(load_timing_info,
4012 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4013
[email protected]2df19bb2010-08-25 20:13:464014 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504015 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464016
4017 EXPECT_TRUE(response->headers->IsKeepAlive());
4018 EXPECT_EQ(200, response->headers->response_code());
4019 EXPECT_EQ(100, response->headers->GetContentLength());
4020 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4021
4022 // The password prompt info should not be set.
4023 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4024}
4025
[email protected]7642b5ae2010-09-01 20:55:174026// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024027TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274028 HttpRequestInfo request;
4029 request.method = "GET";
bncce36dca22015-04-21 22:11:234030 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274031 request.load_flags = 0;
4032
[email protected]7642b5ae2010-09-01 20:55:174033 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034034 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514035 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074036 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424037 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174038
bncce36dca22015-04-21 22:11:234039 // fetch http://www.example.org/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:464040 scoped_ptr<SpdyFrame> req(
4041 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134042 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174043
[email protected]23e482282013-06-14 16:08:024044 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4045 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174046 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134047 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174048 };
4049
rch8e6c6c42015-05-01 14:05:134050 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4051 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074052 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174053
[email protected]8ddf8322012-02-23 18:08:064054 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024055 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074056 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174057
[email protected]49639fa2011-12-20 23:22:414058 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174059
[email protected]262eec82013-03-19 21:01:364060 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504061 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504062
[email protected]49639fa2011-12-20 23:22:414063 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:174064 EXPECT_EQ(ERR_IO_PENDING, rv);
4065
4066 rv = callback1.WaitForResult();
4067 EXPECT_EQ(OK, rv);
4068
[email protected]58e32bb2013-01-21 18:23:254069 LoadTimingInfo load_timing_info;
4070 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4071 TestLoadTimingNotReused(load_timing_info,
4072 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4073
[email protected]7642b5ae2010-09-01 20:55:174074 const HttpResponseInfo* response = trans->GetResponseInfo();
4075 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504076 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:174077 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4078
4079 std::string response_data;
4080 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234081 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174082}
4083
[email protected]1c173852014-06-19 12:51:504084// Verifies that a session which races and wins against the owning transaction
4085// (completing prior to host resolution), doesn't fail the transaction.
4086// Regression test for crbug.com/334413.
4087TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
4088 HttpRequestInfo request;
4089 request.method = "GET";
bncce36dca22015-04-21 22:11:234090 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504091 request.load_flags = 0;
4092
4093 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034094 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514095 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504096 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424097 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504098
bncce36dca22015-04-21 22:11:234099 // Fetch http://www.example.org/ through the SPDY proxy.
[email protected]1c173852014-06-19 12:51:504100 scoped_ptr<SpdyFrame> req(
4101 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134102 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:504103
4104 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4105 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
4106 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134107 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504108 };
4109
rch8e6c6c42015-05-01 14:05:134110 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4111 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504112 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4113
4114 SSLSocketDataProvider ssl(ASYNC, OK);
4115 ssl.SetNextProto(GetParam());
4116 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4117
4118 TestCompletionCallback callback1;
4119
4120 scoped_ptr<HttpTransaction> trans(
4121 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4122
4123 // Stall the hostname resolution begun by the transaction.
4124 session_deps_.host_resolver->set_synchronous_mode(false);
4125 session_deps_.host_resolver->set_ondemand_mode(true);
4126
4127 int rv = trans->Start(&request, callback1.callback(), log.bound());
4128 EXPECT_EQ(ERR_IO_PENDING, rv);
4129
4130 // Race a session to the proxy, which completes first.
4131 session_deps_.host_resolver->set_ondemand_mode(false);
4132 SpdySessionKey key(
4133 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4134 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424135 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504136
4137 // Unstall the resolution begun by the transaction.
4138 session_deps_.host_resolver->set_ondemand_mode(true);
4139 session_deps_.host_resolver->ResolveAllPending();
4140
4141 EXPECT_FALSE(callback1.have_result());
4142 rv = callback1.WaitForResult();
4143 EXPECT_EQ(OK, rv);
4144
4145 const HttpResponseInfo* response = trans->GetResponseInfo();
4146 ASSERT_TRUE(response != NULL);
4147 ASSERT_TRUE(response->headers.get() != NULL);
4148 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4149
4150 std::string response_data;
4151 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4152 EXPECT_EQ(kUploadData, response_data);
4153}
4154
[email protected]dc7bd1c52010-11-12 00:01:134155// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024156TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274157 HttpRequestInfo request;
4158 request.method = "GET";
bncce36dca22015-04-21 22:11:234159 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274160 request.load_flags = 0;
4161
[email protected]79cb5c12011-09-12 13:12:044162 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034163 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514164 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074165 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424166 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134167
[email protected]dc7bd1c52010-11-12 00:01:134168 // The first request will be a bare GET, the second request will be a
4169 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:194170 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:464171 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134172 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464173 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134174 };
[email protected]ff98d7f02012-03-22 21:44:194175 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:464176 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
4177 arraysize(kExtraAuthorizationHeaders) / 2,
4178 false,
4179 3,
4180 LOWEST,
4181 false));
[email protected]dc7bd1c52010-11-12 00:01:134182 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134183 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134184 };
4185
4186 // The first response is a 407 proxy authentication challenge, and the second
4187 // response will be a 200 response since the second request includes a valid
4188 // Authorization header.
4189 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464190 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134191 };
[email protected]ff98d7f02012-03-22 21:44:194192 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:024193 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:134194 "407 Proxy Authentication Required",
4195 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
4196 1));
[email protected]ff98d7f02012-03-22 21:44:194197 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:024198 spdy_util_.ConstructSpdyBodyFrame(1, true));
4199 scoped_ptr<SpdyFrame> resp_data(
4200 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4201 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134202 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134203 CreateMockRead(*resp_authentication, 1),
4204 CreateMockRead(*body_authentication, 2),
4205 CreateMockRead(*resp_data, 4),
4206 CreateMockRead(*body_data, 5),
4207 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134208 };
4209
rch8e6c6c42015-05-01 14:05:134210 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4211 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074212 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134213
[email protected]8ddf8322012-02-23 18:08:064214 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024215 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074216 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134217
[email protected]49639fa2011-12-20 23:22:414218 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134219
[email protected]262eec82013-03-19 21:01:364220 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504221 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:134222
[email protected]49639fa2011-12-20 23:22:414223 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:134224 EXPECT_EQ(ERR_IO_PENDING, rv);
4225
4226 rv = callback1.WaitForResult();
4227 EXPECT_EQ(OK, rv);
4228
4229 const HttpResponseInfo* const response = trans->GetResponseInfo();
4230
4231 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504232 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:134233 EXPECT_EQ(407, response->headers->response_code());
4234 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:044235 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134236
[email protected]49639fa2011-12-20 23:22:414237 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134238
[email protected]49639fa2011-12-20 23:22:414239 rv = trans->RestartWithAuth(
4240 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:134241 EXPECT_EQ(ERR_IO_PENDING, rv);
4242
4243 rv = callback2.WaitForResult();
4244 EXPECT_EQ(OK, rv);
4245
4246 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
4247
4248 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:504249 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:134250 EXPECT_EQ(200, response_restart->headers->response_code());
4251 // The password prompt info should not be set.
4252 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
4253}
4254
[email protected]d9da5fe2010-10-13 22:37:164255// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:024256TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274257 HttpRequestInfo request;
4258 request.method = "GET";
bncce36dca22015-04-21 22:11:234259 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274260 request.load_flags = 0;
4261
[email protected]d9da5fe2010-10-13 22:37:164262 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034263 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514264 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074265 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424266 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164267
[email protected]262eec82013-03-19 21:01:364268 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164270
bncce36dca22015-04-21 22:11:234271 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:344272 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234273 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4274 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164275
bncce36dca22015-04-21 22:11:234276 const char get[] =
4277 "GET / HTTP/1.1\r\n"
4278 "Host: www.example.org\r\n"
4279 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:194280 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:024281 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
4282 scoped_ptr<SpdyFrame> conn_resp(
4283 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164284 const char resp[] = "HTTP/1.1 200 OK\r\n"
4285 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:194286 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024287 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:194288 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:024289 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:194290 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204291 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:044292
4293 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134294 CreateMockWrite(*connect, 0),
4295 CreateMockWrite(*wrapped_get, 2),
4296 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044297 };
4298
[email protected]d9da5fe2010-10-13 22:37:164299 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134300 CreateMockRead(*conn_resp, 1, ASYNC),
4301 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
4302 CreateMockRead(*wrapped_body, 4, ASYNC),
4303 CreateMockRead(*wrapped_body, 5, ASYNC),
4304 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164305 };
4306
rch8e6c6c42015-05-01 14:05:134307 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4308 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074309 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164310
[email protected]8ddf8322012-02-23 18:08:064311 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024312 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074313 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064314 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074315 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164316
[email protected]49639fa2011-12-20 23:22:414317 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164318
[email protected]49639fa2011-12-20 23:22:414319 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164320 EXPECT_EQ(ERR_IO_PENDING, rv);
4321
4322 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:134323 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:164324
[email protected]58e32bb2013-01-21 18:23:254325 LoadTimingInfo load_timing_info;
4326 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4327 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4328
[email protected]d9da5fe2010-10-13 22:37:164329 const HttpResponseInfo* response = trans->GetResponseInfo();
4330 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504331 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:164332 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4333
4334 std::string response_data;
4335 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4336 EXPECT_EQ("1234567890", response_data);
4337}
4338
4339// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:024340TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:274341 HttpRequestInfo request;
4342 request.method = "GET";
bncce36dca22015-04-21 22:11:234343 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274344 request.load_flags = 0;
4345
[email protected]d9da5fe2010-10-13 22:37:164346 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034347 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514348 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074349 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424350 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164351
[email protected]262eec82013-03-19 21:01:364352 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504353 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164354
bncce36dca22015-04-21 22:11:234355 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:344356 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234357 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4358 // fetch https://www.example.org/ via SPDY
4359 const char kMyUrl[] = "https://www.example.org/";
[email protected]cdf8f7e72013-05-23 10:56:464360 scoped_ptr<SpdyFrame> get(
4361 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:024362 scoped_ptr<SpdyFrame> wrapped_get(
4363 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
4364 scoped_ptr<SpdyFrame> conn_resp(
4365 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4366 scoped_ptr<SpdyFrame> get_resp(
4367 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:194368 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024369 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
4370 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4371 scoped_ptr<SpdyFrame> wrapped_body(
4372 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:194373 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:204374 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:194375 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:204376 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:044377
4378 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:094379 CreateMockWrite(*connect, 0),
4380 CreateMockWrite(*wrapped_get, 2),
4381 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:044382 CreateMockWrite(*window_update_body, 7),
4383 };
4384
[email protected]d9da5fe2010-10-13 22:37:164385 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:094386 CreateMockRead(*conn_resp, 1, ASYNC),
4387 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:134388 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:094389 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134390 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164391 };
4392
rch32320842015-05-16 15:57:094393 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4394 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074395 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164396
[email protected]8ddf8322012-02-23 18:08:064397 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024398 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074399 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064400 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024401 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074402 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164403
[email protected]49639fa2011-12-20 23:22:414404 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164405
[email protected]49639fa2011-12-20 23:22:414406 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164407 EXPECT_EQ(ERR_IO_PENDING, rv);
4408
rch32320842015-05-16 15:57:094409 // Allow the SpdyProxyClientSocket's write callback to complete.
4410 base::MessageLoop::current()->RunUntilIdle();
4411 // Now allow the read of the response to complete.
4412 spdy_data.CompleteRead();
[email protected]d9da5fe2010-10-13 22:37:164413 rv = callback1.WaitForResult();
4414 EXPECT_EQ(OK, rv);
4415
[email protected]58e32bb2013-01-21 18:23:254416 LoadTimingInfo load_timing_info;
4417 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4418 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4419
[email protected]d9da5fe2010-10-13 22:37:164420 const HttpResponseInfo* response = trans->GetResponseInfo();
4421 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504422 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:164423 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4424
4425 std::string response_data;
4426 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234427 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:164428}
4429
4430// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024431TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:274432 HttpRequestInfo request;
4433 request.method = "GET";
bncce36dca22015-04-21 22:11:234434 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274435 request.load_flags = 0;
4436
[email protected]d9da5fe2010-10-13 22:37:164437 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034438 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514439 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074440 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424441 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164442
[email protected]262eec82013-03-19 21:01:364443 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504444 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164445
bncce36dca22015-04-21 22:11:234446 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:344447 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234448 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:204449 scoped_ptr<SpdyFrame> get(
4450 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:164451
4452 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134453 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:164454 };
4455
[email protected]23e482282013-06-14 16:08:024456 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
4457 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:164458 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134459 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:164460 };
4461
rch8e6c6c42015-05-01 14:05:134462 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4463 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074464 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164465
[email protected]8ddf8322012-02-23 18:08:064466 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024467 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064469 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024470 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074471 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164472
[email protected]49639fa2011-12-20 23:22:414473 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164474
[email protected]49639fa2011-12-20 23:22:414475 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164476 EXPECT_EQ(ERR_IO_PENDING, rv);
4477
4478 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:174479 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:164480
[email protected]4eddbc732012-08-09 05:40:174481 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:164482}
4483
[email protected]f6c63db52013-02-02 00:35:224484// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4485// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024486TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224487 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
4488 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034489 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514490 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074491 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424492 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504493 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224494
4495 HttpRequestInfo request1;
4496 request1.method = "GET";
bncce36dca22015-04-21 22:11:234497 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224498 request1.load_flags = 0;
4499
4500 HttpRequestInfo request2;
4501 request2.method = "GET";
bncce36dca22015-04-21 22:11:234502 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224503 request2.load_flags = 0;
4504
bncce36dca22015-04-21 22:11:234505 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:344506 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234507 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:024508 scoped_ptr<SpdyFrame> conn_resp1(
4509 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224510
bncce36dca22015-04-21 22:11:234511 // Fetch https://www.example.org/ via HTTP.
4512 const char get1[] =
4513 "GET / HTTP/1.1\r\n"
4514 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224515 "Connection: keep-alive\r\n\r\n";
4516 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024517 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224518 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4519 "Content-Length: 1\r\n\r\n";
4520 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024521 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
4522 scoped_ptr<SpdyFrame> wrapped_body1(
4523 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:224524 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204525 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224526
bncce36dca22015-04-21 22:11:234527 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:294528 SpdyHeaderBlock connect2_block;
bnc7ecc1122015-09-28 13:22:494529 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]745aa9c2014-06-27 02:21:294530 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnc9b79a572015-09-02 12:25:034531 if (GetParam() == kProtoHTTP2) {
bnc6b996d532015-07-29 10:51:324532 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
4533 } else {
bnc6b996d532015-07-29 10:51:324534 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
bnc7ecc1122015-09-28 13:22:494535 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
bnc6b996d532015-07-29 10:51:324536 }
[email protected]f6c63db52013-02-02 00:35:224537 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:294538 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:394539
[email protected]23e482282013-06-14 16:08:024540 scoped_ptr<SpdyFrame> conn_resp2(
4541 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:224542
bncce36dca22015-04-21 22:11:234543 // Fetch https://mail.example.org/ via HTTP.
4544 const char get2[] =
4545 "GET / HTTP/1.1\r\n"
4546 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224547 "Connection: keep-alive\r\n\r\n";
4548 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024549 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224550 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4551 "Content-Length: 2\r\n\r\n";
4552 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024553 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224554 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024555 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224556
4557 MockWrite spdy_writes[] = {
4558 CreateMockWrite(*connect1, 0),
4559 CreateMockWrite(*wrapped_get1, 2),
4560 CreateMockWrite(*connect2, 5),
4561 CreateMockWrite(*wrapped_get2, 7),
4562 };
4563
4564 MockRead spdy_reads[] = {
4565 CreateMockRead(*conn_resp1, 1, ASYNC),
4566 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4567 CreateMockRead(*wrapped_body1, 4, ASYNC),
4568 CreateMockRead(*conn_resp2, 6, ASYNC),
4569 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
4570 CreateMockRead(*wrapped_body2, 9, ASYNC),
4571 MockRead(ASYNC, 0, 10),
4572 };
4573
mmenke11eb5152015-06-09 14:50:504574 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4575 arraysize(spdy_writes));
4576 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224577
4578 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024579 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504580 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224581 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504582 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224583 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504584 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:224585
4586 TestCompletionCallback callback;
4587
[email protected]262eec82013-03-19 21:01:364588 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504589 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224590 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504591 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224592
4593 LoadTimingInfo load_timing_info;
4594 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4595 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4596
4597 const HttpResponseInfo* response = trans->GetResponseInfo();
4598 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504599 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224600 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4601
4602 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294603 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504604 rv = trans->Read(buf.get(), 256, callback.callback());
4605 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224606
[email protected]262eec82013-03-19 21:01:364607 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504608 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224609 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504610 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224611
4612 LoadTimingInfo load_timing_info2;
4613 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4614 // Even though the SPDY connection is reused, a new tunnelled connection has
4615 // to be created, so the socket's load timing looks like a fresh connection.
4616 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
4617
4618 // The requests should have different IDs, since they each are using their own
4619 // separate stream.
4620 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4621
mmenke11eb5152015-06-09 14:50:504622 rv = trans2->Read(buf.get(), 256, callback.callback());
4623 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224624}
4625
4626// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4627// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:024628TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224629 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
4630 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034631 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514632 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074633 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424634 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504635 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224636
4637 HttpRequestInfo request1;
4638 request1.method = "GET";
bncce36dca22015-04-21 22:11:234639 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224640 request1.load_flags = 0;
4641
4642 HttpRequestInfo request2;
4643 request2.method = "GET";
bncce36dca22015-04-21 22:11:234644 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:224645 request2.load_flags = 0;
4646
bncce36dca22015-04-21 22:11:234647 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:344648 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234649 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:024650 scoped_ptr<SpdyFrame> conn_resp1(
4651 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224652
bncce36dca22015-04-21 22:11:234653 // Fetch https://www.example.org/ via HTTP.
4654 const char get1[] =
4655 "GET / HTTP/1.1\r\n"
4656 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224657 "Connection: keep-alive\r\n\r\n";
4658 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024659 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224660 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4661 "Content-Length: 1\r\n\r\n";
4662 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024663 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
4664 scoped_ptr<SpdyFrame> wrapped_body1(
4665 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:224666 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204667 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224668
bncce36dca22015-04-21 22:11:234669 // Fetch https://www.example.org/2 via HTTP.
4670 const char get2[] =
4671 "GET /2 HTTP/1.1\r\n"
4672 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224673 "Connection: keep-alive\r\n\r\n";
4674 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024675 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224676 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4677 "Content-Length: 2\r\n\r\n";
4678 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024679 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224680 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024681 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224682
4683 MockWrite spdy_writes[] = {
4684 CreateMockWrite(*connect1, 0),
4685 CreateMockWrite(*wrapped_get1, 2),
4686 CreateMockWrite(*wrapped_get2, 5),
4687 };
4688
4689 MockRead spdy_reads[] = {
4690 CreateMockRead(*conn_resp1, 1, ASYNC),
4691 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4692 CreateMockRead(*wrapped_body1, 4, ASYNC),
4693 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4694 CreateMockRead(*wrapped_body2, 7, ASYNC),
4695 MockRead(ASYNC, 0, 8),
4696 };
4697
mmenke11eb5152015-06-09 14:50:504698 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4699 arraysize(spdy_writes));
4700 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224701
4702 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024703 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504704 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224705 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504706 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224707
4708 TestCompletionCallback callback;
4709
[email protected]262eec82013-03-19 21:01:364710 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504711 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224712 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4713 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:224714
4715 rv = callback.WaitForResult();
4716 EXPECT_EQ(OK, rv);
4717
4718 LoadTimingInfo load_timing_info;
4719 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4720 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4721
4722 const HttpResponseInfo* response = trans->GetResponseInfo();
4723 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504724 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224725 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4726
4727 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294728 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504729 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224730 trans.reset();
4731
[email protected]262eec82013-03-19 21:01:364732 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504733 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224734 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4735 EXPECT_EQ(ERR_IO_PENDING, rv);
4736
[email protected]f6c63db52013-02-02 00:35:224737 rv = callback.WaitForResult();
4738 EXPECT_EQ(OK, rv);
4739
4740 LoadTimingInfo load_timing_info2;
4741 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4742 TestLoadTimingReused(load_timing_info2);
4743
4744 // The requests should have the same ID.
4745 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4746
[email protected]90499482013-06-01 00:39:504747 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224748}
4749
4750// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4751// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:504752TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:224753 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034754 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514755 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074756 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424757 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504758 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224759
4760 HttpRequestInfo request1;
4761 request1.method = "GET";
bncce36dca22015-04-21 22:11:234762 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224763 request1.load_flags = 0;
4764
4765 HttpRequestInfo request2;
4766 request2.method = "GET";
bncce36dca22015-04-21 22:11:234767 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224768 request2.load_flags = 0;
4769
bncce36dca22015-04-21 22:11:234770 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024771 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234772 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294773 scoped_ptr<SpdyFrame> get1(
4774 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024775 scoped_ptr<SpdyFrame> get_resp1(
4776 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4777 scoped_ptr<SpdyFrame> body1(
4778 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224779
bncce36dca22015-04-21 22:11:234780 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024781 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234782 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294783 scoped_ptr<SpdyFrame> get2(
4784 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024785 scoped_ptr<SpdyFrame> get_resp2(
4786 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4787 scoped_ptr<SpdyFrame> body2(
4788 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224789
4790 MockWrite spdy_writes[] = {
4791 CreateMockWrite(*get1, 0),
4792 CreateMockWrite(*get2, 3),
4793 };
4794
4795 MockRead spdy_reads[] = {
4796 CreateMockRead(*get_resp1, 1, ASYNC),
4797 CreateMockRead(*body1, 2, ASYNC),
4798 CreateMockRead(*get_resp2, 4, ASYNC),
4799 CreateMockRead(*body2, 5, ASYNC),
4800 MockRead(ASYNC, 0, 6),
4801 };
4802
mmenke11eb5152015-06-09 14:50:504803 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4804 arraysize(spdy_writes));
4805 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224806
4807 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024808 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504809 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224810
4811 TestCompletionCallback callback;
4812
[email protected]262eec82013-03-19 21:01:364813 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504814 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224815 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504816 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224817
4818 LoadTimingInfo load_timing_info;
4819 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4820 TestLoadTimingNotReused(load_timing_info,
4821 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4822
4823 const HttpResponseInfo* response = trans->GetResponseInfo();
4824 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504825 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224826 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4827
4828 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294829 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504830 rv = trans->Read(buf.get(), 256, callback.callback());
4831 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224832 // Delete the first request, so the second one can reuse the socket.
4833 trans.reset();
4834
[email protected]262eec82013-03-19 21:01:364835 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504836 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224837 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504838 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224839
4840 LoadTimingInfo load_timing_info2;
4841 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4842 TestLoadTimingReused(load_timing_info2);
4843
4844 // The requests should have the same ID.
4845 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4846
mmenke11eb5152015-06-09 14:50:504847 rv = trans2->Read(buf.get(), 256, callback.callback());
4848 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224849}
4850
[email protected]2df19bb2010-08-25 20:13:464851// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024852TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464853 HttpRequestInfo request;
4854 request.method = "GET";
bncce36dca22015-04-21 22:11:234855 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464856 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294857 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464858
[email protected]79cb5c12011-09-12 13:12:044859 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034860 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514861 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074862 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424863 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274864
[email protected]2df19bb2010-08-25 20:13:464865 // Since we have proxy, should use full url
4866 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234867 MockWrite(
4868 "GET http://www.example.org/ HTTP/1.1\r\n"
4869 "Host: www.example.org\r\n"
4870 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464871
bncce36dca22015-04-21 22:11:234872 // After calling trans->RestartWithAuth(), this is the request we should
4873 // be issuing -- the final header line contains the credentials.
4874 MockWrite(
4875 "GET http://www.example.org/ HTTP/1.1\r\n"
4876 "Host: www.example.org\r\n"
4877 "Proxy-Connection: keep-alive\r\n"
4878 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464879 };
4880
4881 // The proxy responds to the GET with a 407, using a persistent
4882 // connection.
4883 MockRead data_reads1[] = {
4884 // No credentials.
4885 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4886 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4887 MockRead("Proxy-Connection: keep-alive\r\n"),
4888 MockRead("Content-Length: 0\r\n\r\n"),
4889
4890 MockRead("HTTP/1.1 200 OK\r\n"),
4891 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4892 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064893 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464894 };
4895
4896 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4897 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074898 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064899 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074900 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464901
[email protected]49639fa2011-12-20 23:22:414902 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464903
[email protected]262eec82013-03-19 21:01:364904 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504905 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504906
[email protected]49639fa2011-12-20 23:22:414907 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464908 EXPECT_EQ(ERR_IO_PENDING, rv);
4909
4910 rv = callback1.WaitForResult();
4911 EXPECT_EQ(OK, rv);
4912
[email protected]58e32bb2013-01-21 18:23:254913 LoadTimingInfo load_timing_info;
4914 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4915 TestLoadTimingNotReused(load_timing_info,
4916 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4917
[email protected]2df19bb2010-08-25 20:13:464918 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504919 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504920 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464921 EXPECT_EQ(407, response->headers->response_code());
4922 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044923 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464924
[email protected]49639fa2011-12-20 23:22:414925 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464926
[email protected]49639fa2011-12-20 23:22:414927 rv = trans->RestartWithAuth(
4928 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464929 EXPECT_EQ(ERR_IO_PENDING, rv);
4930
4931 rv = callback2.WaitForResult();
4932 EXPECT_EQ(OK, rv);
4933
[email protected]58e32bb2013-01-21 18:23:254934 load_timing_info = LoadTimingInfo();
4935 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4936 // Retrying with HTTP AUTH is considered to be reusing a socket.
4937 TestLoadTimingReused(load_timing_info);
4938
[email protected]2df19bb2010-08-25 20:13:464939 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504940 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464941
4942 EXPECT_TRUE(response->headers->IsKeepAlive());
4943 EXPECT_EQ(200, response->headers->response_code());
4944 EXPECT_EQ(100, response->headers->GetContentLength());
4945 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4946
4947 // The password prompt info should not be set.
4948 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4949}
4950
[email protected]23e482282013-06-14 16:08:024951void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084952 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424953 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084954 request.method = "GET";
bncce36dca22015-04-21 22:11:234955 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084956 request.load_flags = 0;
4957
[email protected]cb9bf6ca2011-01-28 13:15:274958 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034959 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:424960 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274961
[email protected]c744cf22009-02-27 07:28:084962 // Since we have proxy, should try to establish tunnel.
4963 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:234964 MockWrite(
4965 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4966 "Host: www.example.org\r\n"
4967 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084968 };
4969
4970 MockRead data_reads[] = {
4971 status,
4972 MockRead("Content-Length: 10\r\n\r\n"),
4973 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064974 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084975 };
4976
[email protected]31a2bfe2010-02-09 08:03:394977 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4978 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074979 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084980
[email protected]49639fa2011-12-20 23:22:414981 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084982
[email protected]262eec82013-03-19 21:01:364983 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504984 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504985
[email protected]49639fa2011-12-20 23:22:414986 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424987 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084988
4989 rv = callback.WaitForResult();
4990 EXPECT_EQ(expected_status, rv);
4991}
4992
[email protected]23e482282013-06-14 16:08:024993void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234994 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084995 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424996 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084997}
4998
[email protected]23e482282013-06-14 16:08:024999TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085000 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5001}
5002
[email protected]23e482282013-06-14 16:08:025003TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085004 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5005}
5006
[email protected]23e482282013-06-14 16:08:025007TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085008 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5009}
5010
[email protected]23e482282013-06-14 16:08:025011TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085012 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5013}
5014
[email protected]23e482282013-06-14 16:08:025015TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085016 ConnectStatusHelper(
5017 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5018}
5019
[email protected]23e482282013-06-14 16:08:025020TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085021 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5022}
5023
[email protected]23e482282013-06-14 16:08:025024TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085025 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5026}
5027
[email protected]23e482282013-06-14 16:08:025028TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085029 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5030}
5031
[email protected]23e482282013-06-14 16:08:025032TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085033 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5034}
5035
[email protected]23e482282013-06-14 16:08:025036TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085037 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5038}
5039
[email protected]23e482282013-06-14 16:08:025040TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085041 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5042}
5043
[email protected]23e482282013-06-14 16:08:025044TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085045 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5046}
5047
[email protected]23e482282013-06-14 16:08:025048TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085049 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5050}
5051
[email protected]23e482282013-06-14 16:08:025052TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085053 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5054}
5055
[email protected]23e482282013-06-14 16:08:025056TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085057 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5058}
5059
[email protected]23e482282013-06-14 16:08:025060TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085061 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5062}
5063
[email protected]0a17aab32014-04-24 03:32:375064TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
5065 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5066}
5067
[email protected]23e482282013-06-14 16:08:025068TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085069 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5070}
5071
[email protected]23e482282013-06-14 16:08:025072TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085073 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5074}
5075
[email protected]23e482282013-06-14 16:08:025076TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085077 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5078}
5079
[email protected]23e482282013-06-14 16:08:025080TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085081 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5082}
5083
[email protected]23e482282013-06-14 16:08:025084TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085085 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5086}
5087
[email protected]23e482282013-06-14 16:08:025088TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085089 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5090}
5091
[email protected]23e482282013-06-14 16:08:025092TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085093 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5094}
5095
[email protected]23e482282013-06-14 16:08:025096TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085097 ConnectStatusHelperWithExpectedStatus(
5098 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545099 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085100}
5101
[email protected]23e482282013-06-14 16:08:025102TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085103 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5104}
5105
[email protected]23e482282013-06-14 16:08:025106TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085107 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5108}
5109
[email protected]23e482282013-06-14 16:08:025110TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085111 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5112}
5113
[email protected]23e482282013-06-14 16:08:025114TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085115 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5116}
5117
[email protected]23e482282013-06-14 16:08:025118TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085119 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5120}
5121
[email protected]23e482282013-06-14 16:08:025122TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085123 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5124}
5125
[email protected]23e482282013-06-14 16:08:025126TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085127 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5128}
5129
[email protected]23e482282013-06-14 16:08:025130TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085131 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5132}
5133
[email protected]23e482282013-06-14 16:08:025134TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085135 ConnectStatusHelper(
5136 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5137}
5138
[email protected]23e482282013-06-14 16:08:025139TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085140 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5141}
5142
[email protected]23e482282013-06-14 16:08:025143TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085144 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5145}
5146
[email protected]23e482282013-06-14 16:08:025147TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085148 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5149}
5150
[email protected]23e482282013-06-14 16:08:025151TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085152 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5153}
5154
[email protected]23e482282013-06-14 16:08:025155TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085156 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5157}
5158
[email protected]23e482282013-06-14 16:08:025159TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085160 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5161}
5162
[email protected]23e482282013-06-14 16:08:025163TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085164 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5165}
5166
[email protected]038e9a32008-10-08 22:40:165167// Test the flow when both the proxy server AND origin server require
5168// authentication. Again, this uses basic auth for both since that is
5169// the simplest to mock.
[email protected]23e482282013-06-14 16:08:025170TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275171 HttpRequestInfo request;
5172 request.method = "GET";
bncce36dca22015-04-21 22:11:235173 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275174 request.load_flags = 0;
5175
[email protected]038e9a32008-10-08 22:40:165176 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035177 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:425178 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075179
5180 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415181 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:165182
[email protected]f9ee6b52008-11-08 06:46:235183 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235184 MockWrite(
5185 "GET http://www.example.org/ HTTP/1.1\r\n"
5186 "Host: www.example.org\r\n"
5187 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235188 };
5189
[email protected]038e9a32008-10-08 22:40:165190 MockRead data_reads1[] = {
5191 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5192 // Give a couple authenticate options (only the middle one is actually
5193 // supported).
[email protected]22927ad2009-09-21 19:56:195194 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165195 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5196 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5197 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5198 // Large content-length -- won't matter, as connection will be reset.
5199 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065200 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165201 };
5202
5203 // After calling trans->RestartWithAuth() the first time, this is the
5204 // request we should be issuing -- the final header line contains the
5205 // proxy's credentials.
5206 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235207 MockWrite(
5208 "GET http://www.example.org/ HTTP/1.1\r\n"
5209 "Host: www.example.org\r\n"
5210 "Proxy-Connection: keep-alive\r\n"
5211 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165212 };
5213
5214 // Now the proxy server lets the request pass through to origin server.
5215 // The origin server responds with a 401.
5216 MockRead data_reads2[] = {
5217 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5218 // Note: We are using the same realm-name as the proxy server. This is
5219 // completely valid, as realms are unique across hosts.
5220 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5221 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5222 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065223 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165224 };
5225
5226 // After calling trans->RestartWithAuth() the second time, we should send
5227 // the credentials for both the proxy and origin server.
5228 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235229 MockWrite(
5230 "GET http://www.example.org/ HTTP/1.1\r\n"
5231 "Host: www.example.org\r\n"
5232 "Proxy-Connection: keep-alive\r\n"
5233 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5234 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165235 };
5236
5237 // Lastly we get the desired content.
5238 MockRead data_reads3[] = {
5239 MockRead("HTTP/1.0 200 OK\r\n"),
5240 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5241 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065242 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165243 };
5244
[email protected]31a2bfe2010-02-09 08:03:395245 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5246 data_writes1, arraysize(data_writes1));
5247 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5248 data_writes2, arraysize(data_writes2));
5249 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5250 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075251 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5252 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5253 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165254
[email protected]49639fa2011-12-20 23:22:415255 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165256
[email protected]49639fa2011-12-20 23:22:415257 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425258 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165259
5260 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425261 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165262
[email protected]1c773ea12009-04-28 19:58:425263 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505264 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045265 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165266
[email protected]49639fa2011-12-20 23:22:415267 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165268
[email protected]49639fa2011-12-20 23:22:415269 rv = trans->RestartWithAuth(
5270 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425271 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165272
5273 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425274 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165275
5276 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505277 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045278 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165279
[email protected]49639fa2011-12-20 23:22:415280 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165281
[email protected]49639fa2011-12-20 23:22:415282 rv = trans->RestartWithAuth(
5283 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425284 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165285
5286 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425287 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165288
5289 response = trans->GetResponseInfo();
5290 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5291 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165292}
[email protected]4ddaf2502008-10-23 18:26:195293
[email protected]ea9dc9a2009-09-05 00:43:325294// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5295// can't hook into its internals to cause it to generate predictable NTLM
5296// authorization headers.
5297#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295298// The NTLM authentication unit tests were generated by capturing the HTTP
5299// requests and responses using Fiddler 2 and inspecting the generated random
5300// bytes in the debugger.
5301
5302// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:025303TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425304 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245305 request.method = "GET";
5306 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545307
5308 // Ensure load is not disrupted by flags which suppress behaviour specific
5309 // to other auth schemes.
5310 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245311
[email protected]cb9bf6ca2011-01-28 13:15:275312 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5313 MockGetHostName);
mmenkee65e7af2015-10-13 17:16:425314 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275315
[email protected]3f918782009-02-28 01:29:245316 MockWrite data_writes1[] = {
5317 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5318 "Host: 172.22.68.17\r\n"
5319 "Connection: keep-alive\r\n\r\n"),
5320 };
5321
5322 MockRead data_reads1[] = {
5323 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045324 // Negotiate and NTLM are often requested together. However, we only want
5325 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5326 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245327 MockRead("WWW-Authenticate: NTLM\r\n"),
5328 MockRead("Connection: close\r\n"),
5329 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365330 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245331 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065332 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245333 };
5334
5335 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225336 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:245337 // request we should be issuing -- the final header line contains a Type
5338 // 1 message.
5339 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5340 "Host: 172.22.68.17\r\n"
5341 "Connection: keep-alive\r\n"
5342 "Authorization: NTLM "
5343 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5344
5345 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5346 // (the credentials for the origin server). The second request continues
5347 // on the same connection.
5348 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5349 "Host: 172.22.68.17\r\n"
5350 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:295351 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5352 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5353 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5354 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5355 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245356 };
5357
5358 MockRead data_reads2[] = {
5359 // The origin server responds with a Type 2 message.
5360 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5361 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295362 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245363 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5364 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5365 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5366 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5367 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5368 "BtAAAAAAA=\r\n"),
5369 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365370 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245371 MockRead("You are not authorized to view this page\r\n"),
5372
5373 // Lastly we get the desired content.
5374 MockRead("HTTP/1.1 200 OK\r\n"),
5375 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5376 MockRead("Content-Length: 13\r\n\r\n"),
5377 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065378 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245379 };
5380
[email protected]31a2bfe2010-02-09 08:03:395381 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5382 data_writes1, arraysize(data_writes1));
5383 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5384 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075385 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5386 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245387
[email protected]49639fa2011-12-20 23:22:415388 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245389
[email protected]262eec82013-03-19 21:01:365390 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505391 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505392
[email protected]49639fa2011-12-20 23:22:415393 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425394 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245395
5396 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425397 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245398
[email protected]0757e7702009-03-27 04:00:225399 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5400
[email protected]1c773ea12009-04-28 19:58:425401 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:045402 ASSERT_FALSE(response == NULL);
5403 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245404
[email protected]49639fa2011-12-20 23:22:415405 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255406
[email protected]f3cf9802011-10-28 18:44:585407 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415408 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:255409 EXPECT_EQ(ERR_IO_PENDING, rv);
5410
5411 rv = callback2.WaitForResult();
5412 EXPECT_EQ(OK, rv);
5413
5414 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5415
5416 response = trans->GetResponseInfo();
5417 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:255418 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5419
[email protected]49639fa2011-12-20 23:22:415420 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245421
[email protected]49639fa2011-12-20 23:22:415422 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425423 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245424
[email protected]0757e7702009-03-27 04:00:225425 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425426 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245427
5428 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505429 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:245430 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5431 EXPECT_EQ(13, response->headers->GetContentLength());
5432}
5433
[email protected]385a4672009-03-11 22:21:295434// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:025435TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425436 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295437 request.method = "GET";
5438 request.url = GURL("http://172.22.68.17/kids/login.aspx");
5439 request.load_flags = 0;
5440
[email protected]cb9bf6ca2011-01-28 13:15:275441 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5442 MockGetHostName);
mmenkee65e7af2015-10-13 17:16:425443 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275444
[email protected]385a4672009-03-11 22:21:295445 MockWrite data_writes1[] = {
5446 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5447 "Host: 172.22.68.17\r\n"
5448 "Connection: keep-alive\r\n\r\n"),
5449 };
5450
5451 MockRead data_reads1[] = {
5452 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045453 // Negotiate and NTLM are often requested together. However, we only want
5454 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5455 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:295456 MockRead("WWW-Authenticate: NTLM\r\n"),
5457 MockRead("Connection: close\r\n"),
5458 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365459 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295460 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065461 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295462 };
5463
5464 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225465 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295466 // request we should be issuing -- the final header line contains a Type
5467 // 1 message.
5468 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5469 "Host: 172.22.68.17\r\n"
5470 "Connection: keep-alive\r\n"
5471 "Authorization: NTLM "
5472 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5473
5474 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5475 // (the credentials for the origin server). The second request continues
5476 // on the same connection.
5477 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5478 "Host: 172.22.68.17\r\n"
5479 "Connection: keep-alive\r\n"
5480 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5481 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5482 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
5483 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
5484 "4Ww7b7E=\r\n\r\n"),
5485 };
5486
5487 MockRead data_reads2[] = {
5488 // The origin server responds with a Type 2 message.
5489 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5490 MockRead("WWW-Authenticate: NTLM "
5491 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
5492 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5493 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5494 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5495 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5496 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5497 "BtAAAAAAA=\r\n"),
5498 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365499 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295500 MockRead("You are not authorized to view this page\r\n"),
5501
5502 // Wrong password.
5503 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:295504 MockRead("WWW-Authenticate: NTLM\r\n"),
5505 MockRead("Connection: close\r\n"),
5506 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365507 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295508 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065509 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295510 };
5511
5512 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:225513 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295514 // request we should be issuing -- the final header line contains a Type
5515 // 1 message.
5516 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5517 "Host: 172.22.68.17\r\n"
5518 "Connection: keep-alive\r\n"
5519 "Authorization: NTLM "
5520 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5521
5522 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5523 // (the credentials for the origin server). The second request continues
5524 // on the same connection.
5525 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5526 "Host: 172.22.68.17\r\n"
5527 "Connection: keep-alive\r\n"
5528 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5529 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5530 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
5531 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
5532 "+4MUm7c=\r\n\r\n"),
5533 };
5534
5535 MockRead data_reads3[] = {
5536 // The origin server responds with a Type 2 message.
5537 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5538 MockRead("WWW-Authenticate: NTLM "
5539 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
5540 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5541 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5542 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5543 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5544 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5545 "BtAAAAAAA=\r\n"),
5546 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365547 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295548 MockRead("You are not authorized to view this page\r\n"),
5549
5550 // Lastly we get the desired content.
5551 MockRead("HTTP/1.1 200 OK\r\n"),
5552 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5553 MockRead("Content-Length: 13\r\n\r\n"),
5554 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065555 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:295556 };
5557
[email protected]31a2bfe2010-02-09 08:03:395558 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5559 data_writes1, arraysize(data_writes1));
5560 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5561 data_writes2, arraysize(data_writes2));
5562 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5563 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075564 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5565 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5566 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:295567
[email protected]49639fa2011-12-20 23:22:415568 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:295569
[email protected]262eec82013-03-19 21:01:365570 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505571 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505572
[email protected]49639fa2011-12-20 23:22:415573 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425574 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295575
5576 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425577 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295578
[email protected]0757e7702009-03-27 04:00:225579 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:295580
[email protected]1c773ea12009-04-28 19:58:425581 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505582 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045583 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:295584
[email protected]49639fa2011-12-20 23:22:415585 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:295586
[email protected]0757e7702009-03-27 04:00:225587 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:585588 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:415589 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425590 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295591
[email protected]10af5fe72011-01-31 16:17:255592 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425593 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295594
[email protected]0757e7702009-03-27 04:00:225595 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415596 TestCompletionCallback callback3;
5597 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425598 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:255599 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425600 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225601 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5602
5603 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:045604 ASSERT_FALSE(response == NULL);
5605 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:225606
[email protected]49639fa2011-12-20 23:22:415607 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:225608
5609 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:585610 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415611 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:255612 EXPECT_EQ(ERR_IO_PENDING, rv);
5613
5614 rv = callback4.WaitForResult();
5615 EXPECT_EQ(OK, rv);
5616
5617 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5618
[email protected]49639fa2011-12-20 23:22:415619 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:255620
5621 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:415622 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:425623 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225624
5625 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425626 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225627
[email protected]385a4672009-03-11 22:21:295628 response = trans->GetResponseInfo();
5629 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5630 EXPECT_EQ(13, response->headers->GetContentLength());
5631}
[email protected]ea9dc9a2009-09-05 00:43:325632#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:295633
[email protected]4ddaf2502008-10-23 18:26:195634// Test reading a server response which has only headers, and no body.
5635// After some maximum number of bytes is consumed, the transaction should
5636// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:025637TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:425638 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:195639 request.method = "GET";
bncce36dca22015-04-21 22:11:235640 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:195641 request.load_flags = 0;
5642
mmenkee65e7af2015-10-13 17:16:425643 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275644 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415645 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275646
[email protected]b75b7b2f2009-10-06 00:54:535647 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:435648 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:535649 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:195650
5651 MockRead data_reads[] = {
5652 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065653 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:195654 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:065655 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:195656 };
[email protected]31a2bfe2010-02-09 08:03:395657 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075658 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:195659
[email protected]49639fa2011-12-20 23:22:415660 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:195661
[email protected]49639fa2011-12-20 23:22:415662 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425663 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:195664
5665 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425666 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:195667}
[email protected]f4e426b2008-11-05 00:24:495668
5669// Make sure that we don't try to reuse a TCPClientSocket when failing to
5670// establish tunnel.
5671// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:025672TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:235673 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275674 HttpRequestInfo request;
5675 request.method = "GET";
bncce36dca22015-04-21 22:11:235676 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275677 request.load_flags = 0;
5678
[email protected]f4e426b2008-11-05 00:24:495679 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035680 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:015681
mmenkee65e7af2015-10-13 17:16:425682 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495683
[email protected]262eec82013-03-19 21:01:365684 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505685 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495686
[email protected]f4e426b2008-11-05 00:24:495687 // Since we have proxy, should try to establish tunnel.
5688 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235689 MockWrite(
5690 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5691 "Host: www.example.org\r\n"
5692 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495693 };
5694
[email protected]77848d12008-11-14 00:00:225695 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495696 // connection. Usually a proxy would return 501 (not implemented),
5697 // or 200 (tunnel established).
5698 MockRead data_reads1[] = {
5699 MockRead("HTTP/1.1 404 Not Found\r\n"),
5700 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065701 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495702 };
5703
[email protected]31a2bfe2010-02-09 08:03:395704 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5705 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075706 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495707
[email protected]49639fa2011-12-20 23:22:415708 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495709
[email protected]49639fa2011-12-20 23:22:415710 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425711 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495712
5713 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425714 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495715
[email protected]b4404c02009-04-10 16:38:525716 // Empty the current queue. This is necessary because idle sockets are
5717 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345718 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525719
[email protected]f4e426b2008-11-05 00:24:495720 // We now check to make sure the TCPClientSocket was not added back to
5721 // the pool.
[email protected]90499482013-06-01 00:39:505722 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495723 trans.reset();
[email protected]2da659e2013-05-23 20:51:345724 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495725 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505726 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495727}
[email protected]372d34a2008-11-05 21:30:515728
[email protected]1b157c02009-04-21 01:55:405729// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025730TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425731 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405732 request.method = "GET";
bncce36dca22015-04-21 22:11:235733 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405734 request.load_flags = 0;
5735
mmenkee65e7af2015-10-13 17:16:425736 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275737
[email protected]262eec82013-03-19 21:01:365738 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505739 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275740
[email protected]1b157c02009-04-21 01:55:405741 MockRead data_reads[] = {
5742 // A part of the response body is received with the response headers.
5743 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5744 // The rest of the response body is received in two parts.
5745 MockRead("lo"),
5746 MockRead(" world"),
5747 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065748 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405749 };
5750
[email protected]31a2bfe2010-02-09 08:03:395751 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075752 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405753
[email protected]49639fa2011-12-20 23:22:415754 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405755
[email protected]49639fa2011-12-20 23:22:415756 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425757 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405758
5759 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425760 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405761
[email protected]1c773ea12009-04-28 19:58:425762 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505763 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405764
[email protected]90499482013-06-01 00:39:505765 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405766 std::string status_line = response->headers->GetStatusLine();
5767 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5768
[email protected]90499482013-06-01 00:39:505769 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405770
5771 std::string response_data;
5772 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425773 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405774 EXPECT_EQ("hello world", response_data);
5775
5776 // Empty the current queue. This is necessary because idle sockets are
5777 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345778 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405779
5780 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505781 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405782}
5783
[email protected]76a505b2010-08-25 06:23:005784// Make sure that we recycle a SSL socket after reading all of the response
5785// body.
[email protected]23e482282013-06-14 16:08:025786TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005787 HttpRequestInfo request;
5788 request.method = "GET";
bncce36dca22015-04-21 22:11:235789 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005790 request.load_flags = 0;
5791
5792 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235793 MockWrite(
5794 "GET / HTTP/1.1\r\n"
5795 "Host: www.example.org\r\n"
5796 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005797 };
5798
5799 MockRead data_reads[] = {
5800 MockRead("HTTP/1.1 200 OK\r\n"),
5801 MockRead("Content-Length: 11\r\n\r\n"),
5802 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065803 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005804 };
5805
[email protected]8ddf8322012-02-23 18:08:065806 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075807 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005808
5809 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5810 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075811 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005812
[email protected]49639fa2011-12-20 23:22:415813 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005814
mmenkee65e7af2015-10-13 17:16:425815 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365816 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505817 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005818
[email protected]49639fa2011-12-20 23:22:415819 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005820
5821 EXPECT_EQ(ERR_IO_PENDING, rv);
5822 EXPECT_EQ(OK, callback.WaitForResult());
5823
5824 const HttpResponseInfo* response = trans->GetResponseInfo();
5825 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505826 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005827 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5828
[email protected]90499482013-06-01 00:39:505829 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005830
5831 std::string response_data;
5832 rv = ReadTransaction(trans.get(), &response_data);
5833 EXPECT_EQ(OK, rv);
5834 EXPECT_EQ("hello world", response_data);
5835
5836 // Empty the current queue. This is necessary because idle sockets are
5837 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345838 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005839
5840 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505841 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005842}
5843
5844// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5845// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025846TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005847 HttpRequestInfo request;
5848 request.method = "GET";
bncce36dca22015-04-21 22:11:235849 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005850 request.load_flags = 0;
5851
5852 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235853 MockWrite(
5854 "GET / HTTP/1.1\r\n"
5855 "Host: www.example.org\r\n"
5856 "Connection: keep-alive\r\n\r\n"),
5857 MockWrite(
5858 "GET / HTTP/1.1\r\n"
5859 "Host: www.example.org\r\n"
5860 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005861 };
5862
5863 MockRead data_reads[] = {
5864 MockRead("HTTP/1.1 200 OK\r\n"),
5865 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065866 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005867 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065868 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005869 };
5870
[email protected]8ddf8322012-02-23 18:08:065871 SSLSocketDataProvider ssl(ASYNC, OK);
5872 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075873 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005875
5876 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5877 data_writes, arraysize(data_writes));
5878 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5879 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075880 session_deps_.socket_factory->AddSocketDataProvider(&data);
5881 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005882
[email protected]49639fa2011-12-20 23:22:415883 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005884
mmenkee65e7af2015-10-13 17:16:425885 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365886 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505887 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005888
[email protected]49639fa2011-12-20 23:22:415889 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005890
5891 EXPECT_EQ(ERR_IO_PENDING, rv);
5892 EXPECT_EQ(OK, callback.WaitForResult());
5893
5894 const HttpResponseInfo* response = trans->GetResponseInfo();
5895 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505896 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005897 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5898
[email protected]90499482013-06-01 00:39:505899 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005900
5901 std::string response_data;
5902 rv = ReadTransaction(trans.get(), &response_data);
5903 EXPECT_EQ(OK, rv);
5904 EXPECT_EQ("hello world", response_data);
5905
5906 // Empty the current queue. This is necessary because idle sockets are
5907 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345908 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005909
5910 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505911 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005912
5913 // Now start the second transaction, which should reuse the previous socket.
5914
[email protected]90499482013-06-01 00:39:505915 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005916
[email protected]49639fa2011-12-20 23:22:415917 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005918
5919 EXPECT_EQ(ERR_IO_PENDING, rv);
5920 EXPECT_EQ(OK, callback.WaitForResult());
5921
5922 response = trans->GetResponseInfo();
5923 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505924 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005925 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5926
[email protected]90499482013-06-01 00:39:505927 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005928
5929 rv = ReadTransaction(trans.get(), &response_data);
5930 EXPECT_EQ(OK, rv);
5931 EXPECT_EQ("hello world", response_data);
5932
5933 // Empty the current queue. This is necessary because idle sockets are
5934 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345935 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005936
5937 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505938 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005939}
5940
[email protected]b4404c02009-04-10 16:38:525941// Make sure that we recycle a socket after a zero-length response.
5942// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025943TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425944 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525945 request.method = "GET";
bncce36dca22015-04-21 22:11:235946 request.url = GURL(
5947 "http://www.example.org/csi?v=3&s=web&action=&"
5948 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5949 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5950 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525951 request.load_flags = 0;
5952
mmenkee65e7af2015-10-13 17:16:425953 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275954
[email protected]262eec82013-03-19 21:01:365955 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505956 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275957
[email protected]b4404c02009-04-10 16:38:525958 MockRead data_reads[] = {
5959 MockRead("HTTP/1.1 204 No Content\r\n"
5960 "Content-Length: 0\r\n"
5961 "Content-Type: text/html\r\n\r\n"),
5962 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065963 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525964 };
5965
[email protected]31a2bfe2010-02-09 08:03:395966 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075967 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525968
[email protected]49639fa2011-12-20 23:22:415969 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525970
[email protected]49639fa2011-12-20 23:22:415971 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425972 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525973
5974 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425975 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525976
[email protected]1c773ea12009-04-28 19:58:425977 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505978 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525979
[email protected]90499482013-06-01 00:39:505980 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525981 std::string status_line = response->headers->GetStatusLine();
5982 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5983
[email protected]90499482013-06-01 00:39:505984 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525985
5986 std::string response_data;
5987 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425988 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525989 EXPECT_EQ("", response_data);
5990
5991 // Empty the current queue. This is necessary because idle sockets are
5992 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345993 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525994
5995 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505996 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525997}
5998
[email protected]23e482282013-06-14 16:08:025999TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:066000 ScopedVector<UploadElementReader> element_readers;
6001 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:076002 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:276003
[email protected]1c773ea12009-04-28 19:58:426004 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516005 // Transaction 1: a GET request that succeeds. The socket is recycled
6006 // after use.
6007 request[0].method = "GET";
6008 request[0].url = GURL("http://www.google.com/");
6009 request[0].load_flags = 0;
6010 // Transaction 2: a POST request. Reuses the socket kept alive from
6011 // transaction 1. The first attempts fails when writing the POST data.
6012 // This causes the transaction to retry with a new socket. The second
6013 // attempt succeeds.
6014 request[1].method = "POST";
6015 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276016 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516017 request[1].load_flags = 0;
6018
mmenkee65e7af2015-10-13 17:16:426019 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516020
6021 // The first socket is used for transaction 1 and the first attempt of
6022 // transaction 2.
6023
6024 // The response of transaction 1.
6025 MockRead data_reads1[] = {
6026 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6027 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066028 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516029 };
6030 // The mock write results of transaction 1 and the first attempt of
6031 // transaction 2.
6032 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066033 MockWrite(SYNCHRONOUS, 64), // GET
6034 MockWrite(SYNCHRONOUS, 93), // POST
6035 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516036 };
[email protected]31a2bfe2010-02-09 08:03:396037 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6038 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516039
6040 // The second socket is used for the second attempt of transaction 2.
6041
6042 // The response of transaction 2.
6043 MockRead data_reads2[] = {
6044 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6045 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066046 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516047 };
6048 // The mock write results of the second attempt of transaction 2.
6049 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066050 MockWrite(SYNCHRONOUS, 93), // POST
6051 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516052 };
[email protected]31a2bfe2010-02-09 08:03:396053 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6054 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516055
[email protected]bb88e1d32013-05-03 23:11:076056 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6057 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516058
thestig9d3bb0c2015-01-24 00:49:516059 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516060 "hello world", "welcome"
6061 };
6062
6063 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:426064 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506065 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:516066
[email protected]49639fa2011-12-20 23:22:416067 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516068
[email protected]49639fa2011-12-20 23:22:416069 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426070 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:516071
6072 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426073 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516074
[email protected]1c773ea12009-04-28 19:58:426075 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506076 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:516077
[email protected]90499482013-06-01 00:39:506078 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:516079 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6080
6081 std::string response_data;
6082 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426083 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516084 EXPECT_EQ(kExpectedResponseData[i], response_data);
6085 }
6086}
[email protected]f9ee6b52008-11-08 06:46:236087
6088// Test the request-challenge-retry sequence for basic auth when there is
6089// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166090// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:026091TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426092 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236093 request.method = "GET";
bncce36dca22015-04-21 22:11:236094 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416095 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296096
mmenkee65e7af2015-10-13 17:16:426097 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276098 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416099 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276100
[email protected]a97cca42009-08-14 01:00:296101 // The password contains an escaped character -- for this test to pass it
6102 // will need to be unescaped by HttpNetworkTransaction.
6103 EXPECT_EQ("b%40r", request.url.password());
6104
[email protected]f9ee6b52008-11-08 06:46:236105 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236106 MockWrite(
6107 "GET / HTTP/1.1\r\n"
6108 "Host: www.example.org\r\n"
6109 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236110 };
6111
6112 MockRead data_reads1[] = {
6113 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6114 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6115 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066116 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236117 };
6118
[email protected]2262e3a2012-05-22 16:08:166119 // After the challenge above, the transaction will be restarted using the
6120 // identity from the url (foo, b@r) to answer the challenge.
6121 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236122 MockWrite(
6123 "GET / HTTP/1.1\r\n"
6124 "Host: www.example.org\r\n"
6125 "Connection: keep-alive\r\n"
6126 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166127 };
6128
6129 MockRead data_reads2[] = {
6130 MockRead("HTTP/1.0 200 OK\r\n"),
6131 MockRead("Content-Length: 100\r\n\r\n"),
6132 MockRead(SYNCHRONOUS, OK),
6133 };
6134
[email protected]31a2bfe2010-02-09 08:03:396135 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6136 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166137 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6138 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076139 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6140 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236141
[email protected]49639fa2011-12-20 23:22:416142 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:416143 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426144 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236145 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426146 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:166147 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6148
6149 TestCompletionCallback callback2;
6150 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6151 EXPECT_EQ(ERR_IO_PENDING, rv);
6152 rv = callback2.WaitForResult();
6153 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226154 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6155
[email protected]2262e3a2012-05-22 16:08:166156 const HttpResponseInfo* response = trans->GetResponseInfo();
6157 ASSERT_TRUE(response != NULL);
6158
6159 // There is no challenge info, since the identity in URL worked.
6160 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6161
6162 EXPECT_EQ(100, response->headers->GetContentLength());
6163
6164 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:346165 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166166}
6167
6168// Test the request-challenge-retry sequence for basic auth when there is an
6169// incorrect identity in the URL. The identity from the URL should be used only
6170// once.
[email protected]23e482282013-06-14 16:08:026171TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166172 HttpRequestInfo request;
6173 request.method = "GET";
6174 // Note: the URL has a username:password in it. The password "baz" is
6175 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236176 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166177
6178 request.load_flags = LOAD_NORMAL;
6179
mmenkee65e7af2015-10-13 17:16:426180 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:166181 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416182 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:166183
6184 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236185 MockWrite(
6186 "GET / HTTP/1.1\r\n"
6187 "Host: www.example.org\r\n"
6188 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166189 };
6190
6191 MockRead data_reads1[] = {
6192 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6193 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6194 MockRead("Content-Length: 10\r\n\r\n"),
6195 MockRead(SYNCHRONOUS, ERR_FAILED),
6196 };
6197
6198 // After the challenge above, the transaction will be restarted using the
6199 // identity from the url (foo, baz) to answer the challenge.
6200 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236201 MockWrite(
6202 "GET / HTTP/1.1\r\n"
6203 "Host: www.example.org\r\n"
6204 "Connection: keep-alive\r\n"
6205 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166206 };
6207
6208 MockRead data_reads2[] = {
6209 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6210 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6211 MockRead("Content-Length: 10\r\n\r\n"),
6212 MockRead(SYNCHRONOUS, ERR_FAILED),
6213 };
6214
6215 // After the challenge above, the transaction will be restarted using the
6216 // identity supplied by the user (foo, bar) to answer the challenge.
6217 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236218 MockWrite(
6219 "GET / HTTP/1.1\r\n"
6220 "Host: www.example.org\r\n"
6221 "Connection: keep-alive\r\n"
6222 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166223 };
6224
6225 MockRead data_reads3[] = {
6226 MockRead("HTTP/1.0 200 OK\r\n"),
6227 MockRead("Content-Length: 100\r\n\r\n"),
6228 MockRead(SYNCHRONOUS, OK),
6229 };
6230
6231 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6232 data_writes1, arraysize(data_writes1));
6233 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6234 data_writes2, arraysize(data_writes2));
6235 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6236 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076237 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6238 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6239 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166240
6241 TestCompletionCallback callback1;
6242
6243 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6244 EXPECT_EQ(ERR_IO_PENDING, rv);
6245
6246 rv = callback1.WaitForResult();
6247 EXPECT_EQ(OK, rv);
6248
6249 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6250 TestCompletionCallback callback2;
6251 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6252 EXPECT_EQ(ERR_IO_PENDING, rv);
6253 rv = callback2.WaitForResult();
6254 EXPECT_EQ(OK, rv);
6255 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6256
6257 const HttpResponseInfo* response = trans->GetResponseInfo();
6258 ASSERT_TRUE(response != NULL);
6259 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6260
6261 TestCompletionCallback callback3;
6262 rv = trans->RestartWithAuth(
6263 AuthCredentials(kFoo, kBar), callback3.callback());
6264 EXPECT_EQ(ERR_IO_PENDING, rv);
6265 rv = callback3.WaitForResult();
6266 EXPECT_EQ(OK, rv);
6267 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6268
6269 response = trans->GetResponseInfo();
6270 ASSERT_TRUE(response != NULL);
6271
6272 // There is no challenge info, since the identity worked.
6273 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6274
6275 EXPECT_EQ(100, response->headers->GetContentLength());
6276
[email protected]ea9dc9a2009-09-05 00:43:326277 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:346278 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326279}
6280
[email protected]2217aa22013-10-11 03:03:546281
6282// Test the request-challenge-retry sequence for basic auth when there is a
6283// correct identity in the URL, but its use is being suppressed. The identity
6284// from the URL should never be used.
6285TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
6286 HttpRequestInfo request;
6287 request.method = "GET";
bncce36dca22015-04-21 22:11:236288 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546289 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6290
mmenkee65e7af2015-10-13 17:16:426291 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:546292 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416293 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:546294
6295 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236296 MockWrite(
6297 "GET / HTTP/1.1\r\n"
6298 "Host: www.example.org\r\n"
6299 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546300 };
6301
6302 MockRead data_reads1[] = {
6303 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6304 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6305 MockRead("Content-Length: 10\r\n\r\n"),
6306 MockRead(SYNCHRONOUS, ERR_FAILED),
6307 };
6308
6309 // After the challenge above, the transaction will be restarted using the
6310 // identity supplied by the user, not the one in the URL, to answer the
6311 // challenge.
6312 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236313 MockWrite(
6314 "GET / HTTP/1.1\r\n"
6315 "Host: www.example.org\r\n"
6316 "Connection: keep-alive\r\n"
6317 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546318 };
6319
6320 MockRead data_reads3[] = {
6321 MockRead("HTTP/1.0 200 OK\r\n"),
6322 MockRead("Content-Length: 100\r\n\r\n"),
6323 MockRead(SYNCHRONOUS, OK),
6324 };
6325
6326 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6327 data_writes1, arraysize(data_writes1));
6328 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6329 data_writes3, arraysize(data_writes3));
6330 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6331 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6332
6333 TestCompletionCallback callback1;
6334 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6335 EXPECT_EQ(ERR_IO_PENDING, rv);
6336 rv = callback1.WaitForResult();
6337 EXPECT_EQ(OK, rv);
6338 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6339
6340 const HttpResponseInfo* response = trans->GetResponseInfo();
6341 ASSERT_TRUE(response != NULL);
6342 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6343
6344 TestCompletionCallback callback3;
6345 rv = trans->RestartWithAuth(
6346 AuthCredentials(kFoo, kBar), callback3.callback());
6347 EXPECT_EQ(ERR_IO_PENDING, rv);
6348 rv = callback3.WaitForResult();
6349 EXPECT_EQ(OK, rv);
6350 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6351
6352 response = trans->GetResponseInfo();
6353 ASSERT_TRUE(response != NULL);
6354
6355 // There is no challenge info, since the identity worked.
6356 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6357 EXPECT_EQ(100, response->headers->GetContentLength());
6358
6359 // Empty the current queue.
6360 base::MessageLoop::current()->RunUntilIdle();
6361}
6362
[email protected]f9ee6b52008-11-08 06:46:236363// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:026364TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
mmenkee65e7af2015-10-13 17:16:426365 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:236366
6367 // Transaction 1: authenticate (foo, bar) on MyRealm1
6368 {
[email protected]1c773ea12009-04-28 19:58:426369 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236370 request.method = "GET";
bncce36dca22015-04-21 22:11:236371 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:236372 request.load_flags = 0;
6373
[email protected]262eec82013-03-19 21:01:366374 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506375 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276376
[email protected]f9ee6b52008-11-08 06:46:236377 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236378 MockWrite(
6379 "GET /x/y/z HTTP/1.1\r\n"
6380 "Host: www.example.org\r\n"
6381 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236382 };
6383
6384 MockRead data_reads1[] = {
6385 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6386 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6387 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066388 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236389 };
6390
6391 // Resend with authorization (username=foo, password=bar)
6392 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236393 MockWrite(
6394 "GET /x/y/z HTTP/1.1\r\n"
6395 "Host: www.example.org\r\n"
6396 "Connection: keep-alive\r\n"
6397 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236398 };
6399
6400 // Sever accepts the authorization.
6401 MockRead data_reads2[] = {
6402 MockRead("HTTP/1.0 200 OK\r\n"),
6403 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066404 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236405 };
6406
[email protected]31a2bfe2010-02-09 08:03:396407 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6408 data_writes1, arraysize(data_writes1));
6409 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6410 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076411 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6412 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236413
[email protected]49639fa2011-12-20 23:22:416414 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236415
[email protected]49639fa2011-12-20 23:22:416416 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426417 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236418
6419 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426420 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236421
[email protected]1c773ea12009-04-28 19:58:426422 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506423 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046424 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236425
[email protected]49639fa2011-12-20 23:22:416426 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236427
[email protected]49639fa2011-12-20 23:22:416428 rv = trans->RestartWithAuth(
6429 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426430 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236431
6432 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426433 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236434
6435 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506436 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236437 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6438 EXPECT_EQ(100, response->headers->GetContentLength());
6439 }
6440
6441 // ------------------------------------------------------------------------
6442
6443 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
6444 {
[email protected]1c773ea12009-04-28 19:58:426445 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236446 request.method = "GET";
6447 // Note that Transaction 1 was at /x/y/z, so this is in the same
6448 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:236449 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:236450 request.load_flags = 0;
6451
[email protected]262eec82013-03-19 21:01:366452 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506453 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276454
[email protected]f9ee6b52008-11-08 06:46:236455 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236456 MockWrite(
6457 "GET /x/y/a/b HTTP/1.1\r\n"
6458 "Host: www.example.org\r\n"
6459 "Connection: keep-alive\r\n"
6460 // Send preemptive authorization for MyRealm1
6461 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236462 };
6463
6464 // The server didn't like the preemptive authorization, and
6465 // challenges us for a different realm (MyRealm2).
6466 MockRead data_reads1[] = {
6467 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6468 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
6469 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066470 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236471 };
6472
6473 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
6474 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236475 MockWrite(
6476 "GET /x/y/a/b HTTP/1.1\r\n"
6477 "Host: www.example.org\r\n"
6478 "Connection: keep-alive\r\n"
6479 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236480 };
6481
6482 // Sever accepts the authorization.
6483 MockRead data_reads2[] = {
6484 MockRead("HTTP/1.0 200 OK\r\n"),
6485 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066486 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236487 };
6488
[email protected]31a2bfe2010-02-09 08:03:396489 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6490 data_writes1, arraysize(data_writes1));
6491 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6492 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076493 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6494 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236495
[email protected]49639fa2011-12-20 23:22:416496 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236497
[email protected]49639fa2011-12-20 23:22:416498 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426499 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236500
6501 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426502 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236503
[email protected]1c773ea12009-04-28 19:58:426504 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506505 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046506 ASSERT_TRUE(response->auth_challenge.get());
6507 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:236508 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:046509 response->auth_challenge->challenger.ToString());
6510 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
6511 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:236512
[email protected]49639fa2011-12-20 23:22:416513 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236514
[email protected]49639fa2011-12-20 23:22:416515 rv = trans->RestartWithAuth(
6516 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426517 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236518
6519 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426520 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236521
6522 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506523 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236524 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6525 EXPECT_EQ(100, response->headers->GetContentLength());
6526 }
6527
6528 // ------------------------------------------------------------------------
6529
6530 // Transaction 3: Resend a request in MyRealm's protection space --
6531 // succeed with preemptive authorization.
6532 {
[email protected]1c773ea12009-04-28 19:58:426533 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236534 request.method = "GET";
bncce36dca22015-04-21 22:11:236535 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:236536 request.load_flags = 0;
6537
[email protected]262eec82013-03-19 21:01:366538 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506539 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276540
[email protected]f9ee6b52008-11-08 06:46:236541 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236542 MockWrite(
6543 "GET /x/y/z2 HTTP/1.1\r\n"
6544 "Host: www.example.org\r\n"
6545 "Connection: keep-alive\r\n"
6546 // The authorization for MyRealm1 gets sent preemptively
6547 // (since the url is in the same protection space)
6548 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236549 };
6550
6551 // Sever accepts the preemptive authorization
6552 MockRead data_reads1[] = {
6553 MockRead("HTTP/1.0 200 OK\r\n"),
6554 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066555 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236556 };
6557
[email protected]31a2bfe2010-02-09 08:03:396558 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6559 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076560 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:236561
[email protected]49639fa2011-12-20 23:22:416562 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236563
[email protected]49639fa2011-12-20 23:22:416564 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426565 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236566
6567 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426568 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236569
[email protected]1c773ea12009-04-28 19:58:426570 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506571 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236572
6573 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6574 EXPECT_EQ(100, response->headers->GetContentLength());
6575 }
6576
6577 // ------------------------------------------------------------------------
6578
6579 // Transaction 4: request another URL in MyRealm (however the
6580 // url is not known to belong to the protection space, so no pre-auth).
6581 {
[email protected]1c773ea12009-04-28 19:58:426582 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236583 request.method = "GET";
bncce36dca22015-04-21 22:11:236584 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:236585 request.load_flags = 0;
6586
[email protected]262eec82013-03-19 21:01:366587 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506588 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276589
[email protected]f9ee6b52008-11-08 06:46:236590 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236591 MockWrite(
6592 "GET /x/1 HTTP/1.1\r\n"
6593 "Host: www.example.org\r\n"
6594 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236595 };
6596
6597 MockRead data_reads1[] = {
6598 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6599 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6600 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066601 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236602 };
6603
6604 // Resend with authorization from MyRealm's cache.
6605 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236606 MockWrite(
6607 "GET /x/1 HTTP/1.1\r\n"
6608 "Host: www.example.org\r\n"
6609 "Connection: keep-alive\r\n"
6610 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236611 };
6612
6613 // Sever accepts the authorization.
6614 MockRead data_reads2[] = {
6615 MockRead("HTTP/1.0 200 OK\r\n"),
6616 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066617 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236618 };
6619
[email protected]31a2bfe2010-02-09 08:03:396620 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6621 data_writes1, arraysize(data_writes1));
6622 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6623 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076624 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6625 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236626
[email protected]49639fa2011-12-20 23:22:416627 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236628
[email protected]49639fa2011-12-20 23:22:416629 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426630 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236631
6632 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426633 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236634
[email protected]0757e7702009-03-27 04:00:226635 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416636 TestCompletionCallback callback2;
6637 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426638 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226639 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426640 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226641 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6642
[email protected]1c773ea12009-04-28 19:58:426643 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506644 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236645 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6646 EXPECT_EQ(100, response->headers->GetContentLength());
6647 }
6648
6649 // ------------------------------------------------------------------------
6650
6651 // Transaction 5: request a URL in MyRealm, but the server rejects the
6652 // cached identity. Should invalidate and re-prompt.
6653 {
[email protected]1c773ea12009-04-28 19:58:426654 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236655 request.method = "GET";
bncce36dca22015-04-21 22:11:236656 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:236657 request.load_flags = 0;
6658
[email protected]262eec82013-03-19 21:01:366659 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506660 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276661
[email protected]f9ee6b52008-11-08 06:46:236662 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236663 MockWrite(
6664 "GET /p/q/t HTTP/1.1\r\n"
6665 "Host: www.example.org\r\n"
6666 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236667 };
6668
6669 MockRead data_reads1[] = {
6670 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6671 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6672 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066673 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236674 };
6675
6676 // Resend with authorization from cache for MyRealm.
6677 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236678 MockWrite(
6679 "GET /p/q/t HTTP/1.1\r\n"
6680 "Host: www.example.org\r\n"
6681 "Connection: keep-alive\r\n"
6682 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236683 };
6684
6685 // Sever rejects the authorization.
6686 MockRead data_reads2[] = {
6687 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6688 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6689 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066690 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236691 };
6692
6693 // At this point we should prompt for new credentials for MyRealm.
6694 // Restart with username=foo3, password=foo4.
6695 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236696 MockWrite(
6697 "GET /p/q/t HTTP/1.1\r\n"
6698 "Host: www.example.org\r\n"
6699 "Connection: keep-alive\r\n"
6700 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236701 };
6702
6703 // Sever accepts the authorization.
6704 MockRead data_reads3[] = {
6705 MockRead("HTTP/1.0 200 OK\r\n"),
6706 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066707 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236708 };
6709
[email protected]31a2bfe2010-02-09 08:03:396710 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6711 data_writes1, arraysize(data_writes1));
6712 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6713 data_writes2, arraysize(data_writes2));
6714 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6715 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076716 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6717 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6718 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236719
[email protected]49639fa2011-12-20 23:22:416720 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236721
[email protected]49639fa2011-12-20 23:22:416722 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426723 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236724
6725 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426726 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236727
[email protected]0757e7702009-03-27 04:00:226728 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416729 TestCompletionCallback callback2;
6730 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426731 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226732 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426733 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226734 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6735
[email protected]1c773ea12009-04-28 19:58:426736 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506737 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046738 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236739
[email protected]49639fa2011-12-20 23:22:416740 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236741
[email protected]49639fa2011-12-20 23:22:416742 rv = trans->RestartWithAuth(
6743 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426744 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236745
[email protected]0757e7702009-03-27 04:00:226746 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426747 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236748
6749 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506750 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236751 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6752 EXPECT_EQ(100, response->headers->GetContentLength());
6753 }
6754}
[email protected]89ceba9a2009-03-21 03:46:066755
[email protected]3c32c5f2010-05-18 15:18:126756// Tests that nonce count increments when multiple auth attempts
6757// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026758TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446759 HttpAuthHandlerDigest::Factory* digest_factory =
6760 new HttpAuthHandlerDigest::Factory();
6761 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6762 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6763 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076764 session_deps_.http_auth_handler_factory.reset(digest_factory);
mmenkee65e7af2015-10-13 17:16:426765 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126766
6767 // Transaction 1: authenticate (foo, bar) on MyRealm1
6768 {
[email protected]3c32c5f2010-05-18 15:18:126769 HttpRequestInfo request;
6770 request.method = "GET";
bncce36dca22015-04-21 22:11:236771 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126772 request.load_flags = 0;
6773
[email protected]262eec82013-03-19 21:01:366774 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506775 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276776
[email protected]3c32c5f2010-05-18 15:18:126777 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236778 MockWrite(
6779 "GET /x/y/z HTTP/1.1\r\n"
6780 "Host: www.example.org\r\n"
6781 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126782 };
6783
6784 MockRead data_reads1[] = {
6785 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6786 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6787 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066788 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126789 };
6790
6791 // Resend with authorization (username=foo, password=bar)
6792 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236793 MockWrite(
6794 "GET /x/y/z HTTP/1.1\r\n"
6795 "Host: www.example.org\r\n"
6796 "Connection: keep-alive\r\n"
6797 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6798 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6799 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6800 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126801 };
6802
6803 // Sever accepts the authorization.
6804 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:086805 MockRead("HTTP/1.0 200 OK\r\n"),
6806 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126807 };
6808
6809 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6810 data_writes1, arraysize(data_writes1));
6811 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6812 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076813 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6814 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126815
[email protected]49639fa2011-12-20 23:22:416816 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126817
[email protected]49639fa2011-12-20 23:22:416818 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126819 EXPECT_EQ(ERR_IO_PENDING, rv);
6820
6821 rv = callback1.WaitForResult();
6822 EXPECT_EQ(OK, rv);
6823
6824 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506825 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046826 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126827
[email protected]49639fa2011-12-20 23:22:416828 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126829
[email protected]49639fa2011-12-20 23:22:416830 rv = trans->RestartWithAuth(
6831 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126832 EXPECT_EQ(ERR_IO_PENDING, rv);
6833
6834 rv = callback2.WaitForResult();
6835 EXPECT_EQ(OK, rv);
6836
6837 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506838 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126839 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6840 }
6841
6842 // ------------------------------------------------------------------------
6843
6844 // Transaction 2: Request another resource in digestive's protection space.
6845 // This will preemptively add an Authorization header which should have an
6846 // "nc" value of 2 (as compared to 1 in the first use.
6847 {
[email protected]3c32c5f2010-05-18 15:18:126848 HttpRequestInfo request;
6849 request.method = "GET";
6850 // Note that Transaction 1 was at /x/y/z, so this is in the same
6851 // protection space as digest.
bncce36dca22015-04-21 22:11:236852 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126853 request.load_flags = 0;
6854
[email protected]262eec82013-03-19 21:01:366855 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506856 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276857
[email protected]3c32c5f2010-05-18 15:18:126858 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236859 MockWrite(
6860 "GET /x/y/a/b HTTP/1.1\r\n"
6861 "Host: www.example.org\r\n"
6862 "Connection: keep-alive\r\n"
6863 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6864 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6865 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6866 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126867 };
6868
6869 // Sever accepts the authorization.
6870 MockRead data_reads1[] = {
6871 MockRead("HTTP/1.0 200 OK\r\n"),
6872 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066873 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126874 };
6875
6876 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6877 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076878 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126879
[email protected]49639fa2011-12-20 23:22:416880 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126881
[email protected]49639fa2011-12-20 23:22:416882 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126883 EXPECT_EQ(ERR_IO_PENDING, rv);
6884
6885 rv = callback1.WaitForResult();
6886 EXPECT_EQ(OK, rv);
6887
6888 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506889 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126890 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6891 }
6892}
6893
[email protected]89ceba9a2009-03-21 03:46:066894// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026895TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066896 // Create a transaction (the dependencies aren't important).
mmenkee65e7af2015-10-13 17:16:426897 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406898 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416899 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066900
6901 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066902 trans->read_buf_ = new IOBuffer(15);
6903 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206904 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066905
6906 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146907 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576908 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086909 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576910 response->response_time = base::Time::Now();
6911 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066912
6913 { // Setup state for response_.vary_data
6914 HttpRequestInfo request;
6915 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6916 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276917 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436918 request.extra_headers.SetHeader("Foo", "1");
6919 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506920 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066921 }
6922
6923 // Cause the above state to be reset.
6924 trans->ResetStateForRestart();
6925
6926 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076927 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066928 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206929 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576930 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6931 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046932 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086933 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576934 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066935}
6936
[email protected]bacff652009-03-31 17:50:336937// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026938TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336939 HttpRequestInfo request;
6940 request.method = "GET";
bncce36dca22015-04-21 22:11:236941 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336942 request.load_flags = 0;
6943
mmenkee65e7af2015-10-13 17:16:426944 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276945 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416946 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276947
[email protected]bacff652009-03-31 17:50:336948 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236949 MockWrite(
6950 "GET / HTTP/1.1\r\n"
6951 "Host: www.example.org\r\n"
6952 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336953 };
6954
6955 MockRead data_reads[] = {
6956 MockRead("HTTP/1.0 200 OK\r\n"),
6957 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6958 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066959 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336960 };
6961
[email protected]5ecc992a42009-11-11 01:41:596962 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396963 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6964 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066965 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6966 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336967
[email protected]bb88e1d32013-05-03 23:11:076968 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6969 session_deps_.socket_factory->AddSocketDataProvider(&data);
6970 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6971 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336972
[email protected]49639fa2011-12-20 23:22:416973 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336974
[email protected]49639fa2011-12-20 23:22:416975 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336976 EXPECT_EQ(ERR_IO_PENDING, rv);
6977
6978 rv = callback.WaitForResult();
6979 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6980
[email protected]49639fa2011-12-20 23:22:416981 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336982 EXPECT_EQ(ERR_IO_PENDING, rv);
6983
6984 rv = callback.WaitForResult();
6985 EXPECT_EQ(OK, rv);
6986
6987 const HttpResponseInfo* response = trans->GetResponseInfo();
6988
[email protected]fe2255a2011-09-20 19:37:506989 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336990 EXPECT_EQ(100, response->headers->GetContentLength());
6991}
6992
6993// Test HTTPS connections to a site with a bad certificate, going through a
6994// proxy
[email protected]23e482282013-06-14 16:08:026995TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:036996 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:336997
6998 HttpRequestInfo request;
6999 request.method = "GET";
bncce36dca22015-04-21 22:11:237000 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337001 request.load_flags = 0;
7002
7003 MockWrite proxy_writes[] = {
bncce36dca22015-04-21 22:11:237004 MockWrite(
7005 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7006 "Host: www.example.org\r\n"
7007 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337008 };
7009
7010 MockRead proxy_reads[] = {
7011 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067012 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337013 };
7014
7015 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237016 MockWrite(
7017 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7018 "Host: www.example.org\r\n"
7019 "Proxy-Connection: keep-alive\r\n\r\n"),
7020 MockWrite(
7021 "GET / HTTP/1.1\r\n"
7022 "Host: www.example.org\r\n"
7023 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337024 };
7025
7026 MockRead data_reads[] = {
7027 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7028 MockRead("HTTP/1.0 200 OK\r\n"),
7029 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7030 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067031 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337032 };
7033
[email protected]31a2bfe2010-02-09 08:03:397034 StaticSocketDataProvider ssl_bad_certificate(
7035 proxy_reads, arraysize(proxy_reads),
7036 proxy_writes, arraysize(proxy_writes));
7037 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7038 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067039 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7040 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337041
[email protected]bb88e1d32013-05-03 23:11:077042 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7043 session_deps_.socket_factory->AddSocketDataProvider(&data);
7044 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7045 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337046
[email protected]49639fa2011-12-20 23:22:417047 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337048
7049 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077050 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337051
mmenkee65e7af2015-10-13 17:16:427052 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:407053 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417054 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:337055
[email protected]49639fa2011-12-20 23:22:417056 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:337057 EXPECT_EQ(ERR_IO_PENDING, rv);
7058
7059 rv = callback.WaitForResult();
7060 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7061
[email protected]49639fa2011-12-20 23:22:417062 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337063 EXPECT_EQ(ERR_IO_PENDING, rv);
7064
7065 rv = callback.WaitForResult();
7066 EXPECT_EQ(OK, rv);
7067
7068 const HttpResponseInfo* response = trans->GetResponseInfo();
7069
[email protected]fe2255a2011-09-20 19:37:507070 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:337071 EXPECT_EQ(100, response->headers->GetContentLength());
7072 }
7073}
7074
[email protected]2df19bb2010-08-25 20:13:467075
7076// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:027077TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037078 session_deps_.proxy_service =
7079 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517080 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077081 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467082
7083 HttpRequestInfo request;
7084 request.method = "GET";
bncce36dca22015-04-21 22:11:237085 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467086 request.load_flags = 0;
7087
7088 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237089 MockWrite(
7090 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7091 "Host: www.example.org\r\n"
7092 "Proxy-Connection: keep-alive\r\n\r\n"),
7093 MockWrite(
7094 "GET / HTTP/1.1\r\n"
7095 "Host: www.example.org\r\n"
7096 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467097 };
7098
7099 MockRead data_reads[] = {
7100 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7101 MockRead("HTTP/1.1 200 OK\r\n"),
7102 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7103 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067104 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467105 };
7106
7107 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7108 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067109 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7110 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467111
[email protected]bb88e1d32013-05-03 23:11:077112 session_deps_.socket_factory->AddSocketDataProvider(&data);
7113 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7114 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467115
[email protected]49639fa2011-12-20 23:22:417116 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467117
mmenkee65e7af2015-10-13 17:16:427118 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467119 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417120 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467121
[email protected]49639fa2011-12-20 23:22:417122 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467123 EXPECT_EQ(ERR_IO_PENDING, rv);
7124
7125 rv = callback.WaitForResult();
7126 EXPECT_EQ(OK, rv);
7127 const HttpResponseInfo* response = trans->GetResponseInfo();
7128
[email protected]fe2255a2011-09-20 19:37:507129 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467130
7131 EXPECT_TRUE(response->headers->IsKeepAlive());
7132 EXPECT_EQ(200, response->headers->response_code());
7133 EXPECT_EQ(100, response->headers->GetContentLength());
7134 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207135
7136 LoadTimingInfo load_timing_info;
7137 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7138 TestLoadTimingNotReusedWithPac(load_timing_info,
7139 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467140}
7141
[email protected]511f6f52010-12-17 03:58:297142// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027143TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037144 session_deps_.proxy_service =
7145 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517146 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077147 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297148
7149 HttpRequestInfo request;
7150 request.method = "GET";
bncce36dca22015-04-21 22:11:237151 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297152 request.load_flags = 0;
7153
7154 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237155 MockWrite(
7156 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7157 "Host: www.example.org\r\n"
7158 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297159 };
7160
7161 MockRead data_reads[] = {
7162 MockRead("HTTP/1.1 302 Redirect\r\n"),
7163 MockRead("Location: http://login.example.com/\r\n"),
7164 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067165 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297166 };
7167
7168 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7169 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067170 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297171
[email protected]bb88e1d32013-05-03 23:11:077172 session_deps_.socket_factory->AddSocketDataProvider(&data);
7173 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297174
[email protected]49639fa2011-12-20 23:22:417175 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297176
mmenkee65e7af2015-10-13 17:16:427177 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297178 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417179 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297180
[email protected]49639fa2011-12-20 23:22:417181 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297182 EXPECT_EQ(ERR_IO_PENDING, rv);
7183
7184 rv = callback.WaitForResult();
7185 EXPECT_EQ(OK, rv);
7186 const HttpResponseInfo* response = trans->GetResponseInfo();
7187
[email protected]fe2255a2011-09-20 19:37:507188 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:297189
7190 EXPECT_EQ(302, response->headers->response_code());
7191 std::string url;
7192 EXPECT_TRUE(response->headers->IsRedirect(&url));
7193 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207194
7195 // In the case of redirects from proxies, HttpNetworkTransaction returns
7196 // timing for the proxy connection instead of the connection to the host,
7197 // and no send / receive times.
7198 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7199 LoadTimingInfo load_timing_info;
7200 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7201
7202 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:297203 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207204
7205 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7206 EXPECT_LE(load_timing_info.proxy_resolve_start,
7207 load_timing_info.proxy_resolve_end);
7208 EXPECT_LE(load_timing_info.proxy_resolve_end,
7209 load_timing_info.connect_timing.connect_start);
7210 ExpectConnectTimingHasTimes(
7211 load_timing_info.connect_timing,
7212 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7213
7214 EXPECT_TRUE(load_timing_info.send_start.is_null());
7215 EXPECT_TRUE(load_timing_info.send_end.is_null());
7216 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297217}
7218
7219// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027220TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037221 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297222
7223 HttpRequestInfo request;
7224 request.method = "GET";
bncce36dca22015-04-21 22:11:237225 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297226 request.load_flags = 0;
7227
lgarrona91df87f2014-12-05 00:51:347228 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237229 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:207230 scoped_ptr<SpdyFrame> goaway(
7231 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297232 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137233 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
7234 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297235 };
7236
7237 static const char* const kExtraHeaders[] = {
7238 "location",
7239 "http://login.example.com/",
7240 };
[email protected]ff98d7f02012-03-22 21:44:197241 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:027242 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:297243 arraysize(kExtraHeaders)/2, 1));
7244 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137245 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297246 };
7247
rch8e6c6c42015-05-01 14:05:137248 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7249 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067250 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:027251 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:297252
[email protected]bb88e1d32013-05-03 23:11:077253 session_deps_.socket_factory->AddSocketDataProvider(&data);
7254 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297255
[email protected]49639fa2011-12-20 23:22:417256 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297257
mmenkee65e7af2015-10-13 17:16:427258 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297259 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417260 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297261
[email protected]49639fa2011-12-20 23:22:417262 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297263 EXPECT_EQ(ERR_IO_PENDING, rv);
7264
7265 rv = callback.WaitForResult();
7266 EXPECT_EQ(OK, rv);
7267 const HttpResponseInfo* response = trans->GetResponseInfo();
7268
[email protected]fe2255a2011-09-20 19:37:507269 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:297270
7271 EXPECT_EQ(302, response->headers->response_code());
7272 std::string url;
7273 EXPECT_TRUE(response->headers->IsRedirect(&url));
7274 EXPECT_EQ("http://login.example.com/", url);
7275}
7276
[email protected]4eddbc732012-08-09 05:40:177277// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027278TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177279 ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037280 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297281
7282 HttpRequestInfo request;
7283 request.method = "GET";
bncce36dca22015-04-21 22:11:237284 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297285 request.load_flags = 0;
7286
7287 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237288 MockWrite(
7289 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7290 "Host: www.example.org\r\n"
7291 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297292 };
7293
7294 MockRead data_reads[] = {
7295 MockRead("HTTP/1.1 404 Not Found\r\n"),
7296 MockRead("Content-Length: 23\r\n\r\n"),
7297 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067298 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297299 };
7300
7301 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7302 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067303 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297304
[email protected]bb88e1d32013-05-03 23:11:077305 session_deps_.socket_factory->AddSocketDataProvider(&data);
7306 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297307
[email protected]49639fa2011-12-20 23:22:417308 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297309
mmenkee65e7af2015-10-13 17:16:427310 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297311 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417312 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297313
[email protected]49639fa2011-12-20 23:22:417314 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297315 EXPECT_EQ(ERR_IO_PENDING, rv);
7316
7317 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177318 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297319
[email protected]4eddbc732012-08-09 05:40:177320 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297321}
7322
[email protected]4eddbc732012-08-09 05:40:177323// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027324TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177325 ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037326 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297327
7328 HttpRequestInfo request;
7329 request.method = "GET";
bncce36dca22015-04-21 22:11:237330 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297331 request.load_flags = 0;
7332
lgarrona91df87f2014-12-05 00:51:347333 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237334 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:207335 scoped_ptr<SpdyFrame> rst(
7336 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297337 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137338 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:297339 };
7340
7341 static const char* const kExtraHeaders[] = {
7342 "location",
7343 "http://login.example.com/",
7344 };
[email protected]ff98d7f02012-03-22 21:44:197345 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:027346 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:297347 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:197348 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:027349 spdy_util_.ConstructSpdyBodyFrame(
7350 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297351 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137352 CreateMockRead(*resp.get(), 1),
7353 CreateMockRead(*body.get(), 2),
7354 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297355 };
7356
rch8e6c6c42015-05-01 14:05:137357 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7358 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067359 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:027360 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:297361
[email protected]bb88e1d32013-05-03 23:11:077362 session_deps_.socket_factory->AddSocketDataProvider(&data);
7363 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297364
[email protected]49639fa2011-12-20 23:22:417365 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297366
mmenkee65e7af2015-10-13 17:16:427367 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297368 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417369 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297370
[email protected]49639fa2011-12-20 23:22:417371 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297372 EXPECT_EQ(ERR_IO_PENDING, rv);
7373
7374 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177375 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297376
[email protected]4eddbc732012-08-09 05:40:177377 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297378}
7379
[email protected]0c5fb722012-02-28 11:50:357380// Test the request-challenge-retry sequence for basic auth, through
7381// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:027382TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:357383 HttpRequestInfo request;
7384 request.method = "GET";
bncce36dca22015-04-21 22:11:237385 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:357386 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:297387 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:357388
7389 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037390 session_deps_.proxy_service =
7391 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:517392 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077393 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:427394 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:357395
7396 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:347397 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237398 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:207399 scoped_ptr<SpdyFrame> rst(
7400 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:357401
7402 // After calling trans->RestartWithAuth(), this is the request we should
7403 // be issuing -- the final header line contains the credentials.
7404 const char* const kAuthCredentials[] = {
7405 "proxy-authorization", "Basic Zm9vOmJhcg==",
7406 };
[email protected]fba2dbde2013-05-24 16:09:017407 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:347408 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:237409 HostPortPair("www.example.org", 443)));
7410 // fetch https://www.example.org/ via HTTP
7411 const char get[] =
7412 "GET / HTTP/1.1\r\n"
7413 "Host: www.example.org\r\n"
7414 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:197415 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:027416 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:357417
7418 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137419 CreateMockWrite(*req, 0, ASYNC),
7420 CreateMockWrite(*rst, 2, ASYNC),
7421 CreateMockWrite(*connect2, 3),
7422 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:357423 };
7424
7425 // The proxy responds to the connect with a 407, using a persistent
7426 // connection.
thestig9d3bb0c2015-01-24 00:49:517427 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:357428 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:357429 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
7430 };
[email protected]745aa9c2014-06-27 02:21:297431 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
7432 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:357433
[email protected]23e482282013-06-14 16:08:027434 scoped_ptr<SpdyFrame> conn_resp(
7435 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:357436 const char resp[] = "HTTP/1.1 200 OK\r\n"
7437 "Content-Length: 5\r\n\r\n";
7438
[email protected]ff98d7f02012-03-22 21:44:197439 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:027440 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:197441 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:027442 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:357443 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137444 CreateMockRead(*conn_auth_resp, 1, ASYNC),
7445 CreateMockRead(*conn_resp, 4, ASYNC),
7446 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
7447 CreateMockRead(*wrapped_body, 7, ASYNC),
7448 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:357449 };
7450
rch8e6c6c42015-05-01 14:05:137451 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7452 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077453 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:357454 // Negotiate SPDY to the proxy
7455 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027456 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077457 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:357458 // Vanilla SSL to the server
7459 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077460 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:357461
7462 TestCompletionCallback callback1;
7463
[email protected]262eec82013-03-19 21:01:367464 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507465 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:357466
7467 int rv = trans->Start(&request, callback1.callback(), log.bound());
7468 EXPECT_EQ(ERR_IO_PENDING, rv);
7469
7470 rv = callback1.WaitForResult();
7471 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:467472 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:357473 log.GetEntries(&entries);
7474 size_t pos = ExpectLogContainsSomewhere(
7475 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
7476 NetLog::PHASE_NONE);
7477 ExpectLogContainsSomewhere(
7478 entries, pos,
7479 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
7480 NetLog::PHASE_NONE);
7481
7482 const HttpResponseInfo* response = trans->GetResponseInfo();
7483 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507484 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:357485 EXPECT_EQ(407, response->headers->response_code());
7486 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7487 EXPECT_TRUE(response->auth_challenge.get() != NULL);
7488 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
7489
7490 TestCompletionCallback callback2;
7491
7492 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
7493 callback2.callback());
7494 EXPECT_EQ(ERR_IO_PENDING, rv);
7495
7496 rv = callback2.WaitForResult();
7497 EXPECT_EQ(OK, rv);
7498
7499 response = trans->GetResponseInfo();
7500 ASSERT_TRUE(response != NULL);
7501
7502 EXPECT_TRUE(response->headers->IsKeepAlive());
7503 EXPECT_EQ(200, response->headers->response_code());
7504 EXPECT_EQ(5, response->headers->GetContentLength());
7505 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7506
7507 // The password prompt info should not be set.
7508 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7509
[email protected]029c83b62013-01-24 05:28:207510 LoadTimingInfo load_timing_info;
7511 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7512 TestLoadTimingNotReusedWithPac(load_timing_info,
7513 CONNECT_TIMING_HAS_SSL_TIMES);
7514
[email protected]0c5fb722012-02-28 11:50:357515 trans.reset();
7516 session->CloseAllConnections();
7517}
7518
[email protected]7c6f7ba2012-04-03 04:09:297519// Test that an explicitly trusted SPDY proxy can push a resource from an
7520// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:027521TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:297522 HttpRequestInfo request;
7523 HttpRequestInfo push_request;
7524
[email protected]7c6f7ba2012-04-03 04:09:297525 request.method = "GET";
bncce36dca22015-04-21 22:11:237526 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:297527 push_request.method = "GET";
7528 push_request.url = GURL("http://www.another-origin.com/foo.dat");
7529
[email protected]7c6f7ba2012-04-03 04:09:297530 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037531 session_deps_.proxy_service =
7532 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:517533 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077534 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507535
7536 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:077537 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:507538
mmenkee65e7af2015-10-13 17:16:427539 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:297540
[email protected]cdf8f7e72013-05-23 10:56:467541 scoped_ptr<SpdyFrame> stream1_syn(
7542 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:297543
7544 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137545 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:297546 };
7547
7548 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027549 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:297550
7551 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027552 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:297553
7554 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027555 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:297556 0,
7557 2,
7558 1,
7559 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:437560 const char kPushedData[] = "pushed";
7561 scoped_ptr<SpdyFrame> stream2_body(
7562 spdy_util_.ConstructSpdyBodyFrame(
7563 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:297564
7565 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137566 CreateMockRead(*stream1_reply, 1, ASYNC),
7567 CreateMockRead(*stream2_syn, 2, ASYNC),
7568 CreateMockRead(*stream1_body, 3, ASYNC),
7569 CreateMockRead(*stream2_body, 4, ASYNC),
7570 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:297571 };
7572
rch8e6c6c42015-05-01 14:05:137573 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7574 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077575 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:297576 // Negotiate SPDY to the proxy
7577 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027578 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077579 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:297580
[email protected]262eec82013-03-19 21:01:367581 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507582 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:297583 TestCompletionCallback callback;
7584 int rv = trans->Start(&request, callback.callback(), log.bound());
7585 EXPECT_EQ(ERR_IO_PENDING, rv);
7586
7587 rv = callback.WaitForResult();
7588 EXPECT_EQ(OK, rv);
7589 const HttpResponseInfo* response = trans->GetResponseInfo();
7590
[email protected]262eec82013-03-19 21:01:367591 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:507592 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7593 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:297594 EXPECT_EQ(ERR_IO_PENDING, rv);
7595
7596 rv = callback.WaitForResult();
7597 EXPECT_EQ(OK, rv);
7598 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
7599
7600 ASSERT_TRUE(response != NULL);
7601 EXPECT_TRUE(response->headers->IsKeepAlive());
7602
7603 EXPECT_EQ(200, response->headers->response_code());
7604 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7605
7606 std::string response_data;
7607 rv = ReadTransaction(trans.get(), &response_data);
7608 EXPECT_EQ(OK, rv);
7609 EXPECT_EQ("hello!", response_data);
7610
[email protected]029c83b62013-01-24 05:28:207611 LoadTimingInfo load_timing_info;
7612 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7613 TestLoadTimingNotReusedWithPac(load_timing_info,
7614 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7615
[email protected]7c6f7ba2012-04-03 04:09:297616 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:507617 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:297618 EXPECT_EQ(200, push_response->headers->response_code());
7619
7620 rv = ReadTransaction(push_trans.get(), &response_data);
7621 EXPECT_EQ(OK, rv);
7622 EXPECT_EQ("pushed", response_data);
7623
[email protected]029c83b62013-01-24 05:28:207624 LoadTimingInfo push_load_timing_info;
7625 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
7626 TestLoadTimingReusedWithPac(push_load_timing_info);
7627 // The transactions should share a socket ID, despite being for different
7628 // origins.
7629 EXPECT_EQ(load_timing_info.socket_log_id,
7630 push_load_timing_info.socket_log_id);
7631
[email protected]7c6f7ba2012-04-03 04:09:297632 trans.reset();
7633 push_trans.reset();
7634 session->CloseAllConnections();
7635}
7636
[email protected]8c843192012-04-05 07:15:007637// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:027638TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:007639 HttpRequestInfo request;
7640
7641 request.method = "GET";
bncce36dca22015-04-21 22:11:237642 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:007643
[email protected]8c843192012-04-05 07:15:007644 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037645 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:517646 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077647 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507648
7649 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:077650 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:507651
mmenkee65e7af2015-10-13 17:16:427652 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:007653
[email protected]cdf8f7e72013-05-23 10:56:467654 scoped_ptr<SpdyFrame> stream1_syn(
7655 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:007656
7657 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:207658 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:007659
7660 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137661 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:007662 };
7663
7664 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027665 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:007666
7667 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027668 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:007669
7670 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027671 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:007672 0,
7673 2,
7674 1,
7675 "https://www.another-origin.com/foo.dat"));
7676
7677 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137678 CreateMockRead(*stream1_reply, 1, ASYNC),
7679 CreateMockRead(*stream2_syn, 2, ASYNC),
7680 CreateMockRead(*stream1_body, 4, ASYNC),
7681 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:007682 };
7683
rch8e6c6c42015-05-01 14:05:137684 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7685 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077686 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007687 // Negotiate SPDY to the proxy
7688 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027689 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077690 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007691
[email protected]262eec82013-03-19 21:01:367692 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507693 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007694 TestCompletionCallback callback;
7695 int rv = trans->Start(&request, callback.callback(), log.bound());
7696 EXPECT_EQ(ERR_IO_PENDING, rv);
7697
7698 rv = callback.WaitForResult();
7699 EXPECT_EQ(OK, rv);
7700 const HttpResponseInfo* response = trans->GetResponseInfo();
7701
7702 ASSERT_TRUE(response != NULL);
7703 EXPECT_TRUE(response->headers->IsKeepAlive());
7704
7705 EXPECT_EQ(200, response->headers->response_code());
7706 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7707
7708 std::string response_data;
7709 rv = ReadTransaction(trans.get(), &response_data);
7710 EXPECT_EQ(OK, rv);
7711 EXPECT_EQ("hello!", response_data);
7712
7713 trans.reset();
7714 session->CloseAllConnections();
7715}
7716
[email protected]2df19bb2010-08-25 20:13:467717// Test HTTPS connections to a site with a bad certificate, going through an
7718// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027719TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037720 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:467721
7722 HttpRequestInfo request;
7723 request.method = "GET";
bncce36dca22015-04-21 22:11:237724 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467725 request.load_flags = 0;
7726
7727 // Attempt to fetch the URL from a server with a bad cert
7728 MockWrite bad_cert_writes[] = {
bncce36dca22015-04-21 22:11:237729 MockWrite(
7730 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7731 "Host: www.example.org\r\n"
7732 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467733 };
7734
7735 MockRead bad_cert_reads[] = {
7736 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067737 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467738 };
7739
7740 // Attempt to fetch the URL with a good cert
7741 MockWrite good_data_writes[] = {
bncce36dca22015-04-21 22:11:237742 MockWrite(
7743 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7744 "Host: www.example.org\r\n"
7745 "Proxy-Connection: keep-alive\r\n\r\n"),
7746 MockWrite(
7747 "GET / HTTP/1.1\r\n"
7748 "Host: www.example.org\r\n"
7749 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467750 };
7751
7752 MockRead good_cert_reads[] = {
7753 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7754 MockRead("HTTP/1.0 200 OK\r\n"),
7755 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7756 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067757 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467758 };
7759
7760 StaticSocketDataProvider ssl_bad_certificate(
7761 bad_cert_reads, arraysize(bad_cert_reads),
7762 bad_cert_writes, arraysize(bad_cert_writes));
7763 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7764 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067765 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7766 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467767
7768 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077769 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7770 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7771 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467772
7773 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077774 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7775 session_deps_.socket_factory->AddSocketDataProvider(&data);
7776 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467777
[email protected]49639fa2011-12-20 23:22:417778 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467779
mmenkee65e7af2015-10-13 17:16:427780 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467781 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417782 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467783
[email protected]49639fa2011-12-20 23:22:417784 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467785 EXPECT_EQ(ERR_IO_PENDING, rv);
7786
7787 rv = callback.WaitForResult();
7788 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7789
[email protected]49639fa2011-12-20 23:22:417790 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467791 EXPECT_EQ(ERR_IO_PENDING, rv);
7792
7793 rv = callback.WaitForResult();
7794 EXPECT_EQ(OK, rv);
7795
7796 const HttpResponseInfo* response = trans->GetResponseInfo();
7797
[email protected]fe2255a2011-09-20 19:37:507798 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467799 EXPECT_EQ(100, response->headers->GetContentLength());
7800}
7801
[email protected]23e482282013-06-14 16:08:027802TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427803 HttpRequestInfo request;
7804 request.method = "GET";
bncce36dca22015-04-21 22:11:237805 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437806 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7807 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427808
mmenkee65e7af2015-10-13 17:16:427809 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277810 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417811 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277812
[email protected]1c773ea12009-04-28 19:58:427813 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237814 MockWrite(
7815 "GET / HTTP/1.1\r\n"
7816 "Host: www.example.org\r\n"
7817 "Connection: keep-alive\r\n"
7818 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427819 };
7820
7821 // Lastly, the server responds with the actual content.
7822 MockRead data_reads[] = {
7823 MockRead("HTTP/1.0 200 OK\r\n"),
7824 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7825 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067826 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427827 };
7828
[email protected]31a2bfe2010-02-09 08:03:397829 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7830 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077831 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427832
[email protected]49639fa2011-12-20 23:22:417833 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427834
[email protected]49639fa2011-12-20 23:22:417835 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427836 EXPECT_EQ(ERR_IO_PENDING, rv);
7837
7838 rv = callback.WaitForResult();
7839 EXPECT_EQ(OK, rv);
7840}
7841
[email protected]23e482282013-06-14 16:08:027842TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297843 HttpRequestInfo request;
7844 request.method = "GET";
bncce36dca22015-04-21 22:11:237845 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297846 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7847 "Chromium Ultra Awesome X Edition");
7848
rdsmith82957ad2015-09-16 19:42:037849 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:427850 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277851 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417852 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277853
[email protected]da81f132010-08-18 23:39:297854 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237855 MockWrite(
7856 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7857 "Host: www.example.org\r\n"
7858 "Proxy-Connection: keep-alive\r\n"
7859 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297860 };
7861 MockRead data_reads[] = {
7862 // Return an error, so the transaction stops here (this test isn't
7863 // interested in the rest).
7864 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7865 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7866 MockRead("Proxy-Connection: close\r\n\r\n"),
7867 };
7868
7869 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7870 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077871 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297872
[email protected]49639fa2011-12-20 23:22:417873 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297874
[email protected]49639fa2011-12-20 23:22:417875 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297876 EXPECT_EQ(ERR_IO_PENDING, rv);
7877
7878 rv = callback.WaitForResult();
7879 EXPECT_EQ(OK, rv);
7880}
7881
[email protected]23e482282013-06-14 16:08:027882TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427883 HttpRequestInfo request;
7884 request.method = "GET";
bncce36dca22015-04-21 22:11:237885 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427886 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167887 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7888 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427889
mmenkee65e7af2015-10-13 17:16:427890 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277891 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417892 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277893
[email protected]1c773ea12009-04-28 19:58:427894 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237895 MockWrite(
7896 "GET / HTTP/1.1\r\n"
7897 "Host: www.example.org\r\n"
7898 "Connection: keep-alive\r\n"
7899 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427900 };
7901
7902 // Lastly, the server responds with the actual content.
7903 MockRead data_reads[] = {
7904 MockRead("HTTP/1.0 200 OK\r\n"),
7905 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7906 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067907 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427908 };
7909
[email protected]31a2bfe2010-02-09 08:03:397910 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7911 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077912 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427913
[email protected]49639fa2011-12-20 23:22:417914 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427915
[email protected]49639fa2011-12-20 23:22:417916 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427917 EXPECT_EQ(ERR_IO_PENDING, rv);
7918
7919 rv = callback.WaitForResult();
7920 EXPECT_EQ(OK, rv);
7921}
7922
[email protected]23e482282013-06-14 16:08:027923TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427924 HttpRequestInfo request;
7925 request.method = "POST";
bncce36dca22015-04-21 22:11:237926 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427927
mmenkee65e7af2015-10-13 17:16:427928 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277929 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417930 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277931
[email protected]1c773ea12009-04-28 19:58:427932 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237933 MockWrite(
7934 "POST / HTTP/1.1\r\n"
7935 "Host: www.example.org\r\n"
7936 "Connection: keep-alive\r\n"
7937 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427938 };
7939
7940 // Lastly, the server responds with the actual content.
7941 MockRead data_reads[] = {
7942 MockRead("HTTP/1.0 200 OK\r\n"),
7943 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7944 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067945 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427946 };
7947
[email protected]31a2bfe2010-02-09 08:03:397948 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7949 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077950 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427951
[email protected]49639fa2011-12-20 23:22:417952 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427953
[email protected]49639fa2011-12-20 23:22:417954 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427955 EXPECT_EQ(ERR_IO_PENDING, rv);
7956
7957 rv = callback.WaitForResult();
7958 EXPECT_EQ(OK, rv);
7959}
7960
[email protected]23e482282013-06-14 16:08:027961TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427962 HttpRequestInfo request;
7963 request.method = "PUT";
bncce36dca22015-04-21 22:11:237964 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427965
mmenkee65e7af2015-10-13 17:16:427966 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277967 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417968 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277969
[email protected]1c773ea12009-04-28 19:58:427970 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237971 MockWrite(
7972 "PUT / HTTP/1.1\r\n"
7973 "Host: www.example.org\r\n"
7974 "Connection: keep-alive\r\n"
7975 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427976 };
7977
7978 // Lastly, the server responds with the actual content.
7979 MockRead data_reads[] = {
7980 MockRead("HTTP/1.0 200 OK\r\n"),
7981 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7982 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067983 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427984 };
7985
[email protected]31a2bfe2010-02-09 08:03:397986 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7987 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077988 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427989
[email protected]49639fa2011-12-20 23:22:417990 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427991
[email protected]49639fa2011-12-20 23:22:417992 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427993 EXPECT_EQ(ERR_IO_PENDING, rv);
7994
7995 rv = callback.WaitForResult();
7996 EXPECT_EQ(OK, rv);
7997}
7998
[email protected]23e482282013-06-14 16:08:027999TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428000 HttpRequestInfo request;
8001 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238002 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428003
mmenkee65e7af2015-10-13 17:16:428004 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278005 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418006 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278007
[email protected]1c773ea12009-04-28 19:58:428008 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138009 MockWrite("HEAD / HTTP/1.1\r\n"
8010 "Host: www.example.org\r\n"
8011 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428012 };
8013
8014 // Lastly, the server responds with the actual content.
8015 MockRead data_reads[] = {
8016 MockRead("HTTP/1.0 200 OK\r\n"),
8017 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8018 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068019 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428020 };
8021
[email protected]31a2bfe2010-02-09 08:03:398022 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8023 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078024 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428025
[email protected]49639fa2011-12-20 23:22:418026 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428027
[email protected]49639fa2011-12-20 23:22:418028 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428029 EXPECT_EQ(ERR_IO_PENDING, rv);
8030
8031 rv = callback.WaitForResult();
8032 EXPECT_EQ(OK, rv);
8033}
8034
[email protected]23e482282013-06-14 16:08:028035TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428036 HttpRequestInfo request;
8037 request.method = "GET";
bncce36dca22015-04-21 22:11:238038 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428039 request.load_flags = LOAD_BYPASS_CACHE;
8040
mmenkee65e7af2015-10-13 17:16:428041 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278042 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418043 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278044
[email protected]1c773ea12009-04-28 19:58:428045 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238046 MockWrite(
8047 "GET / HTTP/1.1\r\n"
8048 "Host: www.example.org\r\n"
8049 "Connection: keep-alive\r\n"
8050 "Pragma: no-cache\r\n"
8051 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428052 };
8053
8054 // Lastly, the server responds with the actual content.
8055 MockRead data_reads[] = {
8056 MockRead("HTTP/1.0 200 OK\r\n"),
8057 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8058 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068059 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428060 };
8061
[email protected]31a2bfe2010-02-09 08:03:398062 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8063 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078064 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428065
[email protected]49639fa2011-12-20 23:22:418066 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428067
[email protected]49639fa2011-12-20 23:22:418068 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428069 EXPECT_EQ(ERR_IO_PENDING, rv);
8070
8071 rv = callback.WaitForResult();
8072 EXPECT_EQ(OK, rv);
8073}
8074
[email protected]23e482282013-06-14 16:08:028075TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:428076 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428077 HttpRequestInfo request;
8078 request.method = "GET";
bncce36dca22015-04-21 22:11:238079 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428080 request.load_flags = LOAD_VALIDATE_CACHE;
8081
mmenkee65e7af2015-10-13 17:16:428082 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278083 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418084 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278085
[email protected]1c773ea12009-04-28 19:58:428086 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238087 MockWrite(
8088 "GET / HTTP/1.1\r\n"
8089 "Host: www.example.org\r\n"
8090 "Connection: keep-alive\r\n"
8091 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428092 };
8093
8094 // Lastly, the server responds with the actual content.
8095 MockRead data_reads[] = {
8096 MockRead("HTTP/1.0 200 OK\r\n"),
8097 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8098 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068099 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428100 };
8101
[email protected]31a2bfe2010-02-09 08:03:398102 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8103 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078104 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428105
[email protected]49639fa2011-12-20 23:22:418106 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428107
[email protected]49639fa2011-12-20 23:22:418108 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428109 EXPECT_EQ(ERR_IO_PENDING, rv);
8110
8111 rv = callback.WaitForResult();
8112 EXPECT_EQ(OK, rv);
8113}
8114
[email protected]23e482282013-06-14 16:08:028115TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428116 HttpRequestInfo request;
8117 request.method = "GET";
bncce36dca22015-04-21 22:11:238118 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438119 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428120
mmenkee65e7af2015-10-13 17:16:428121 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278122 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418123 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278124
[email protected]1c773ea12009-04-28 19:58:428125 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238126 MockWrite(
8127 "GET / HTTP/1.1\r\n"
8128 "Host: www.example.org\r\n"
8129 "Connection: keep-alive\r\n"
8130 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428131 };
8132
8133 // Lastly, the server responds with the actual content.
8134 MockRead data_reads[] = {
8135 MockRead("HTTP/1.0 200 OK\r\n"),
8136 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8137 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068138 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428139 };
8140
[email protected]31a2bfe2010-02-09 08:03:398141 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8142 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078143 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428144
[email protected]49639fa2011-12-20 23:22:418145 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428146
[email protected]49639fa2011-12-20 23:22:418147 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428148 EXPECT_EQ(ERR_IO_PENDING, rv);
8149
8150 rv = callback.WaitForResult();
8151 EXPECT_EQ(OK, rv);
8152}
8153
[email protected]23e482282013-06-14 16:08:028154TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478155 HttpRequestInfo request;
8156 request.method = "GET";
bncce36dca22015-04-21 22:11:238157 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438158 request.extra_headers.SetHeader("referer", "www.foo.com");
8159 request.extra_headers.SetHeader("hEllo", "Kitty");
8160 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478161
mmenkee65e7af2015-10-13 17:16:428162 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278163 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418164 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278165
[email protected]270c6412010-03-29 22:02:478166 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238167 MockWrite(
8168 "GET / HTTP/1.1\r\n"
8169 "Host: www.example.org\r\n"
8170 "Connection: keep-alive\r\n"
8171 "referer: www.foo.com\r\n"
8172 "hEllo: Kitty\r\n"
8173 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478174 };
8175
8176 // Lastly, the server responds with the actual content.
8177 MockRead data_reads[] = {
8178 MockRead("HTTP/1.0 200 OK\r\n"),
8179 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8180 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068181 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478182 };
8183
8184 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8185 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078186 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478187
[email protected]49639fa2011-12-20 23:22:418188 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478189
[email protected]49639fa2011-12-20 23:22:418190 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:478191 EXPECT_EQ(ERR_IO_PENDING, rv);
8192
8193 rv = callback.WaitForResult();
8194 EXPECT_EQ(OK, rv);
8195}
8196
[email protected]23e482282013-06-14 16:08:028197TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278198 HttpRequestInfo request;
8199 request.method = "GET";
bncce36dca22015-04-21 22:11:238200 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278201 request.load_flags = 0;
8202
rdsmith82957ad2015-09-16 19:42:038203 session_deps_.proxy_service =
8204 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518205 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078206 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028207
mmenkee65e7af2015-10-13 17:16:428208 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:028209 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418210 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028211
[email protected]3cd17242009-06-23 02:59:028212 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8213 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8214
8215 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238216 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8217 MockWrite(
8218 "GET / HTTP/1.1\r\n"
8219 "Host: www.example.org\r\n"
8220 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028221
8222 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068223 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028224 MockRead("HTTP/1.0 200 OK\r\n"),
8225 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8226 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068227 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028228 };
8229
[email protected]31a2bfe2010-02-09 08:03:398230 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8231 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078232 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028233
[email protected]49639fa2011-12-20 23:22:418234 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028235
[email protected]49639fa2011-12-20 23:22:418236 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028237 EXPECT_EQ(ERR_IO_PENDING, rv);
8238
8239 rv = callback.WaitForResult();
8240 EXPECT_EQ(OK, rv);
8241
8242 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508243 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:028244
[email protected]029c83b62013-01-24 05:28:208245 LoadTimingInfo load_timing_info;
8246 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8247 TestLoadTimingNotReusedWithPac(load_timing_info,
8248 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8249
[email protected]3cd17242009-06-23 02:59:028250 std::string response_text;
8251 rv = ReadTransaction(trans.get(), &response_text);
8252 EXPECT_EQ(OK, rv);
8253 EXPECT_EQ("Payload", response_text);
8254}
8255
[email protected]23e482282013-06-14 16:08:028256TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278257 HttpRequestInfo request;
8258 request.method = "GET";
bncce36dca22015-04-21 22:11:238259 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278260 request.load_flags = 0;
8261
rdsmith82957ad2015-09-16 19:42:038262 session_deps_.proxy_service =
8263 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518264 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078265 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028266
mmenkee65e7af2015-10-13 17:16:428267 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:028268 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028270
[email protected]3cd17242009-06-23 02:59:028271 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8272 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8273
8274 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238275 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8276 arraysize(write_buffer)),
8277 MockWrite(
8278 "GET / HTTP/1.1\r\n"
8279 "Host: www.example.org\r\n"
8280 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028281
8282 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018283 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8284 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358285 MockRead("HTTP/1.0 200 OK\r\n"),
8286 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8287 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068288 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358289 };
8290
[email protected]31a2bfe2010-02-09 08:03:398291 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8292 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078293 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358294
[email protected]8ddf8322012-02-23 18:08:068295 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078296 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358297
[email protected]49639fa2011-12-20 23:22:418298 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358299
[email protected]49639fa2011-12-20 23:22:418300 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358301 EXPECT_EQ(ERR_IO_PENDING, rv);
8302
8303 rv = callback.WaitForResult();
8304 EXPECT_EQ(OK, rv);
8305
[email protected]029c83b62013-01-24 05:28:208306 LoadTimingInfo load_timing_info;
8307 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8308 TestLoadTimingNotReusedWithPac(load_timing_info,
8309 CONNECT_TIMING_HAS_SSL_TIMES);
8310
[email protected]e0c27be2009-07-15 13:09:358311 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508312 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:358313
8314 std::string response_text;
8315 rv = ReadTransaction(trans.get(), &response_text);
8316 EXPECT_EQ(OK, rv);
8317 EXPECT_EQ("Payload", response_text);
8318}
8319
[email protected]23e482282013-06-14 16:08:028320TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:208321 HttpRequestInfo request;
8322 request.method = "GET";
bncce36dca22015-04-21 22:11:238323 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:208324 request.load_flags = 0;
8325
rdsmith82957ad2015-09-16 19:42:038326 session_deps_.proxy_service =
8327 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518328 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078329 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:208330
mmenkee65e7af2015-10-13 17:16:428331 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:208332 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418333 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:208334
8335 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8336 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8337
8338 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238339 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8340 MockWrite(
8341 "GET / HTTP/1.1\r\n"
8342 "Host: www.example.org\r\n"
8343 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:208344
8345 MockRead data_reads[] = {
8346 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
8347 MockRead("HTTP/1.0 200 OK\r\n"),
8348 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8349 MockRead("Payload"),
8350 MockRead(SYNCHRONOUS, OK)
8351 };
8352
8353 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8354 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078355 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:208356
8357 TestCompletionCallback callback;
8358
8359 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8360 EXPECT_EQ(ERR_IO_PENDING, rv);
8361
8362 rv = callback.WaitForResult();
8363 EXPECT_EQ(OK, rv);
8364
8365 const HttpResponseInfo* response = trans->GetResponseInfo();
8366 ASSERT_TRUE(response != NULL);
8367
8368 LoadTimingInfo load_timing_info;
8369 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8370 TestLoadTimingNotReused(load_timing_info,
8371 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8372
8373 std::string response_text;
8374 rv = ReadTransaction(trans.get(), &response_text);
8375 EXPECT_EQ(OK, rv);
8376 EXPECT_EQ("Payload", response_text);
8377}
8378
[email protected]23e482282013-06-14 16:08:028379TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278380 HttpRequestInfo request;
8381 request.method = "GET";
bncce36dca22015-04-21 22:11:238382 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278383 request.load_flags = 0;
8384
rdsmith82957ad2015-09-16 19:42:038385 session_deps_.proxy_service =
8386 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518387 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078388 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358389
mmenkee65e7af2015-10-13 17:16:428390 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:358391 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418392 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358393
[email protected]e0c27be2009-07-15 13:09:358394 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8395 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378396 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238397 0x05, // Version
8398 0x01, // Command (CONNECT)
8399 0x00, // Reserved.
8400 0x03, // Address type (DOMAINNAME).
8401 0x0F, // Length of domain (15)
8402 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8403 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:378404 };
[email protected]e0c27be2009-07-15 13:09:358405 const char kSOCKS5OkResponse[] =
8406 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
8407
8408 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238409 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8410 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
8411 MockWrite(
8412 "GET / HTTP/1.1\r\n"
8413 "Host: www.example.org\r\n"
8414 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358415
8416 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018417 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8418 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:358419 MockRead("HTTP/1.0 200 OK\r\n"),
8420 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8421 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068422 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358423 };
8424
[email protected]31a2bfe2010-02-09 08:03:398425 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8426 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078427 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358428
[email protected]49639fa2011-12-20 23:22:418429 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358430
[email protected]49639fa2011-12-20 23:22:418431 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358432 EXPECT_EQ(ERR_IO_PENDING, rv);
8433
8434 rv = callback.WaitForResult();
8435 EXPECT_EQ(OK, rv);
8436
8437 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508438 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:358439
[email protected]029c83b62013-01-24 05:28:208440 LoadTimingInfo load_timing_info;
8441 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8442 TestLoadTimingNotReusedWithPac(load_timing_info,
8443 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8444
[email protected]e0c27be2009-07-15 13:09:358445 std::string response_text;
8446 rv = ReadTransaction(trans.get(), &response_text);
8447 EXPECT_EQ(OK, rv);
8448 EXPECT_EQ("Payload", response_text);
8449}
8450
[email protected]23e482282013-06-14 16:08:028451TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278452 HttpRequestInfo request;
8453 request.method = "GET";
bncce36dca22015-04-21 22:11:238454 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278455 request.load_flags = 0;
8456
rdsmith82957ad2015-09-16 19:42:038457 session_deps_.proxy_service =
8458 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518459 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078460 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358461
mmenkee65e7af2015-10-13 17:16:428462 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:358463 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418464 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358465
[email protected]e0c27be2009-07-15 13:09:358466 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8467 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378468 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238469 0x05, // Version
8470 0x01, // Command (CONNECT)
8471 0x00, // Reserved.
8472 0x03, // Address type (DOMAINNAME).
8473 0x0F, // Length of domain (15)
8474 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8475 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:378476 };
8477
[email protected]e0c27be2009-07-15 13:09:358478 const char kSOCKS5OkResponse[] =
8479 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
8480
8481 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238482 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8483 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
8484 arraysize(kSOCKS5OkRequest)),
8485 MockWrite(
8486 "GET / HTTP/1.1\r\n"
8487 "Host: www.example.org\r\n"
8488 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358489
8490 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018491 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8492 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:028493 MockRead("HTTP/1.0 200 OK\r\n"),
8494 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8495 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068496 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028497 };
8498
[email protected]31a2bfe2010-02-09 08:03:398499 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8500 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078501 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028502
[email protected]8ddf8322012-02-23 18:08:068503 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078504 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:028505
[email protected]49639fa2011-12-20 23:22:418506 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028507
[email protected]49639fa2011-12-20 23:22:418508 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028509 EXPECT_EQ(ERR_IO_PENDING, rv);
8510
8511 rv = callback.WaitForResult();
8512 EXPECT_EQ(OK, rv);
8513
8514 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508515 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:028516
[email protected]029c83b62013-01-24 05:28:208517 LoadTimingInfo load_timing_info;
8518 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8519 TestLoadTimingNotReusedWithPac(load_timing_info,
8520 CONNECT_TIMING_HAS_SSL_TIMES);
8521
[email protected]3cd17242009-06-23 02:59:028522 std::string response_text;
8523 rv = ReadTransaction(trans.get(), &response_text);
8524 EXPECT_EQ(OK, rv);
8525 EXPECT_EQ("Payload", response_text);
8526}
8527
[email protected]448d4ca52012-03-04 04:12:238528namespace {
8529
[email protected]04e5be32009-06-26 20:00:318530// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:068531
8532struct GroupNameTest {
8533 std::string proxy_server;
8534 std::string url;
8535 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:188536 bool ssl;
[email protected]2d731a32010-04-29 01:04:068537};
8538
mmenkee65e7af2015-10-13 17:16:428539scoped_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:438540 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:078541 SpdySessionDependencies* session_deps_) {
mmenkee65e7af2015-10-13 17:16:428542 scoped_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:068543
[email protected]30d4c022013-07-18 22:58:168544 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538545 session->http_server_properties();
bnccacc0992015-03-20 20:22:228546 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:258547 AlternateProtocolFromNextProto(next_proto), "", 443);
bnc7dc7e1b42015-07-28 14:43:128548 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:228549 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:128550 HostPortPair("host.with.alternate", 80), alternative_service, 1.0,
8551 expiration);
[email protected]2d731a32010-04-29 01:04:068552
8553 return session;
8554}
8555
mmenkee65e7af2015-10-13 17:16:428556int GroupNameTransactionHelper(const std::string& url,
8557 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:068558 HttpRequestInfo request;
8559 request.method = "GET";
8560 request.url = GURL(url);
8561 request.load_flags = 0;
8562
[email protected]262eec82013-03-19 21:01:368563 scoped_ptr<HttpTransaction> trans(
mmenkee65e7af2015-10-13 17:16:428564 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:278565
[email protected]49639fa2011-12-20 23:22:418566 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:068567
8568 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:418569 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:068570}
8571
[email protected]448d4ca52012-03-04 04:12:238572} // namespace
8573
[email protected]23e482282013-06-14 16:08:028574TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:068575 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238576 {
8577 "", // unused
8578 "http://www.example.org/direct",
8579 "www.example.org:80",
8580 false,
8581 },
8582 {
8583 "", // unused
8584 "http://[2001:1418:13:1::25]/direct",
8585 "[2001:1418:13:1::25]:80",
8586 false,
8587 },
[email protected]04e5be32009-06-26 20:00:318588
bncce36dca22015-04-21 22:11:238589 // SSL Tests
8590 {
8591 "", // unused
8592 "https://www.example.org/direct_ssl",
8593 "ssl/www.example.org:443",
8594 true,
8595 },
8596 {
8597 "", // unused
8598 "https://[2001:1418:13:1::25]/direct",
8599 "ssl/[2001:1418:13:1::25]:443",
8600 true,
8601 },
8602 {
8603 "", // unused
8604 "http://host.with.alternate/direct",
8605 "ssl/host.with.alternate:443",
8606 true,
8607 },
[email protected]2d731a32010-04-29 01:04:068608 };
[email protected]2ff8b312010-04-26 22:20:548609
bnc55ff9da2015-08-19 18:42:358610 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068611
viettrungluue4a8b882014-10-16 06:17:388612 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038613 session_deps_.proxy_service =
8614 ProxyService::CreateFixed(tests[i].proxy_server);
mmenkee65e7af2015-10-13 17:16:428615 scoped_ptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438616 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068617
mmenkee65e7af2015-10-13 17:16:428618 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:288619 CaptureGroupNameTransportSocketPool* transport_conn_pool =
8620 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138621 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348622 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:448623 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8624 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028625 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
8626 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518627 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068628
8629 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:428630 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:188631 if (tests[i].ssl)
8632 EXPECT_EQ(tests[i].expected_group_name,
8633 ssl_conn_pool->last_group_name_received());
8634 else
8635 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:288636 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068637 }
[email protected]2d731a32010-04-29 01:04:068638}
8639
[email protected]23e482282013-06-14 16:08:028640TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:068641 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238642 {
8643 "http_proxy",
8644 "http://www.example.org/http_proxy_normal",
8645 "www.example.org:80",
8646 false,
8647 },
[email protected]2d731a32010-04-29 01:04:068648
bncce36dca22015-04-21 22:11:238649 // SSL Tests
8650 {
8651 "http_proxy",
8652 "https://www.example.org/http_connect_ssl",
8653 "ssl/www.example.org:443",
8654 true,
8655 },
[email protected]af3490e2010-10-16 21:02:298656
bncce36dca22015-04-21 22:11:238657 {
8658 "http_proxy",
8659 "http://host.with.alternate/direct",
8660 "ssl/host.with.alternate:443",
8661 true,
8662 },
[email protected]45499252013-01-23 17:12:568663
bncce36dca22015-04-21 22:11:238664 {
8665 "http_proxy",
8666 "ftp://ftp.google.com/http_proxy_normal",
8667 "ftp/ftp.google.com:21",
8668 false,
8669 },
[email protected]2d731a32010-04-29 01:04:068670 };
8671
bnc55ff9da2015-08-19 18:42:358672 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068673
viettrungluue4a8b882014-10-16 06:17:388674 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038675 session_deps_.proxy_service =
8676 ProxyService::CreateFixed(tests[i].proxy_server);
mmenkee65e7af2015-10-13 17:16:428677 scoped_ptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438678 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068679
mmenkee65e7af2015-10-13 17:16:428680 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:068681
[email protected]e60e47a2010-07-14 03:37:188682 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138683 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348684 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138685 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348686 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028687
[email protected]831e4a32013-11-14 02:14:448688 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8689 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028690 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8691 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518692 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068693
8694 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:428695 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:188696 if (tests[i].ssl)
8697 EXPECT_EQ(tests[i].expected_group_name,
8698 ssl_conn_pool->last_group_name_received());
8699 else
8700 EXPECT_EQ(tests[i].expected_group_name,
8701 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068702 }
[email protected]2d731a32010-04-29 01:04:068703}
8704
[email protected]23e482282013-06-14 16:08:028705TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068706 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238707 {
8708 "socks4://socks_proxy:1080",
8709 "http://www.example.org/socks4_direct",
8710 "socks4/www.example.org:80",
8711 false,
8712 },
8713 {
8714 "socks5://socks_proxy:1080",
8715 "http://www.example.org/socks5_direct",
8716 "socks5/www.example.org:80",
8717 false,
8718 },
[email protected]2d731a32010-04-29 01:04:068719
bncce36dca22015-04-21 22:11:238720 // SSL Tests
8721 {
8722 "socks4://socks_proxy:1080",
8723 "https://www.example.org/socks4_ssl",
8724 "socks4/ssl/www.example.org:443",
8725 true,
8726 },
8727 {
8728 "socks5://socks_proxy:1080",
8729 "https://www.example.org/socks5_ssl",
8730 "socks5/ssl/www.example.org:443",
8731 true,
8732 },
[email protected]af3490e2010-10-16 21:02:298733
bncce36dca22015-04-21 22:11:238734 {
8735 "socks4://socks_proxy:1080",
8736 "http://host.with.alternate/direct",
8737 "socks4/ssl/host.with.alternate:443",
8738 true,
8739 },
[email protected]04e5be32009-06-26 20:00:318740 };
8741
bnc55ff9da2015-08-19 18:42:358742 session_deps_.use_alternative_services = true;
[email protected]2ff8b312010-04-26 22:20:548743
viettrungluue4a8b882014-10-16 06:17:388744 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038745 session_deps_.proxy_service =
8746 ProxyService::CreateFixed(tests[i].proxy_server);
mmenkee65e7af2015-10-13 17:16:428747 scoped_ptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438748 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028749
mmenkee65e7af2015-10-13 17:16:428750 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:318751
[email protected]e60e47a2010-07-14 03:37:188752 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138753 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348754 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138755 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348756 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028757
[email protected]831e4a32013-11-14 02:14:448758 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8759 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028760 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8761 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518762 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318763
[email protected]262eec82013-03-19 21:01:368764 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508765 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318766
[email protected]2d731a32010-04-29 01:04:068767 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:428768 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:188769 if (tests[i].ssl)
8770 EXPECT_EQ(tests[i].expected_group_name,
8771 ssl_conn_pool->last_group_name_received());
8772 else
8773 EXPECT_EQ(tests[i].expected_group_name,
8774 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318775 }
8776}
8777
[email protected]23e482282013-06-14 16:08:028778TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278779 HttpRequestInfo request;
8780 request.method = "GET";
bncce36dca22015-04-21 22:11:238781 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278782
rdsmith82957ad2015-09-16 19:42:038783 session_deps_.proxy_service =
8784 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:328785
[email protected]69719062010-01-05 20:09:218786 // This simulates failure resolving all hostnames; that means we will fail
8787 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078788 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328789
mmenkee65e7af2015-10-13 17:16:428790 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258791 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418792 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258793
[email protected]49639fa2011-12-20 23:22:418794 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258795
[email protected]49639fa2011-12-20 23:22:418796 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258797 EXPECT_EQ(ERR_IO_PENDING, rv);
8798
[email protected]9172a982009-06-06 00:30:258799 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018800 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258801}
8802
[email protected]685af592010-05-11 19:31:248803// Base test to make sure that when the load flags for a request specify to
8804// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028805void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078806 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278807 // Issue a request, asking to bypass the cache(s).
8808 HttpRequestInfo request;
8809 request.method = "GET";
8810 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238811 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278812
[email protected]a2c2fb92009-07-18 07:31:048813 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078814 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328815
mmenkee65e7af2015-10-13 17:16:428816 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:078817 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418818 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288819
bncce36dca22015-04-21 22:11:238820 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288821 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298822 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078823 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238824 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8825 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478826 EXPECT_EQ(ERR_IO_PENDING, rv);
8827 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288828 EXPECT_EQ(OK, rv);
8829
8830 // Verify that it was added to host cache, by doing a subsequent async lookup
8831 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078832 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238833 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8834 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328835 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288836
bncce36dca22015-04-21 22:11:238837 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288838 // we can tell if the next lookup hit the cache, or the "network".
8839 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238840 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288841
8842 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8843 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068844 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398845 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078846 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288847
[email protected]3b9cca42009-06-16 01:08:288848 // Run the request.
[email protected]49639fa2011-12-20 23:22:418849 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288850 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418851 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288852
8853 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238854 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288855 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8856}
8857
[email protected]685af592010-05-11 19:31:248858// There are multiple load flags that should trigger the host cache bypass.
8859// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028860TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248861 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8862}
8863
[email protected]23e482282013-06-14 16:08:028864TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248865 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8866}
8867
[email protected]23e482282013-06-14 16:08:028868TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248869 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8870}
8871
[email protected]0877e3d2009-10-17 22:29:578872// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028873TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578874 HttpRequestInfo request;
8875 request.method = "GET";
8876 request.url = GURL("http://www.foo.com/");
8877 request.load_flags = 0;
8878
8879 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068880 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578881 };
[email protected]31a2bfe2010-02-09 08:03:398882 StaticSocketDataProvider data(NULL, 0,
8883 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078884 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenkee65e7af2015-10-13 17:16:428885 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578886
[email protected]49639fa2011-12-20 23:22:418887 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578888
8889 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418890 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578891
[email protected]49639fa2011-12-20 23:22:418892 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578893 EXPECT_EQ(ERR_IO_PENDING, rv);
8894
8895 rv = callback.WaitForResult();
8896 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:598897
8898 IPEndPoint endpoint;
8899 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
8900 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:578901}
8902
zmo9528c9f42015-08-04 22:12:088903// Check that a connection closed after the start of the headers finishes ok.
8904TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578905 HttpRequestInfo request;
8906 request.method = "GET";
8907 request.url = GURL("http://www.foo.com/");
8908 request.load_flags = 0;
8909
8910 MockRead data_reads[] = {
8911 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068912 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578913 };
8914
[email protected]31a2bfe2010-02-09 08:03:398915 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078916 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenkee65e7af2015-10-13 17:16:428917 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578918
[email protected]49639fa2011-12-20 23:22:418919 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578920
8921 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578923
[email protected]49639fa2011-12-20 23:22:418924 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578925 EXPECT_EQ(ERR_IO_PENDING, rv);
8926
8927 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:088928 EXPECT_EQ(OK, rv);
8929
8930 const HttpResponseInfo* response = trans->GetResponseInfo();
8931 ASSERT_TRUE(response != NULL);
8932
8933 EXPECT_TRUE(response->headers.get() != NULL);
8934 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8935
8936 std::string response_data;
8937 rv = ReadTransaction(trans.get(), &response_data);
8938 EXPECT_EQ(OK, rv);
8939 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:598940
8941 IPEndPoint endpoint;
8942 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
8943 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:578944}
8945
8946// Make sure that a dropped connection while draining the body for auth
8947// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028948TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578949 HttpRequestInfo request;
8950 request.method = "GET";
bncce36dca22015-04-21 22:11:238951 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578952 request.load_flags = 0;
8953
8954 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238955 MockWrite(
8956 "GET / HTTP/1.1\r\n"
8957 "Host: www.example.org\r\n"
8958 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578959 };
8960
8961 MockRead data_reads1[] = {
8962 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8963 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8964 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8965 MockRead("Content-Length: 14\r\n\r\n"),
8966 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068967 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578968 };
8969
[email protected]31a2bfe2010-02-09 08:03:398970 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8971 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078972 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578973
8974 // After calling trans->RestartWithAuth(), this is the request we should
8975 // be issuing -- the final header line contains the credentials.
8976 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238977 MockWrite(
8978 "GET / HTTP/1.1\r\n"
8979 "Host: www.example.org\r\n"
8980 "Connection: keep-alive\r\n"
8981 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578982 };
8983
8984 // Lastly, the server responds with the actual content.
8985 MockRead data_reads2[] = {
8986 MockRead("HTTP/1.1 200 OK\r\n"),
8987 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8988 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068989 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578990 };
8991
[email protected]31a2bfe2010-02-09 08:03:398992 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8993 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078994 session_deps_.socket_factory->AddSocketDataProvider(&data2);
mmenkee65e7af2015-10-13 17:16:428995 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578996
[email protected]49639fa2011-12-20 23:22:418997 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578998
[email protected]262eec82013-03-19 21:01:368999 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509000 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509001
[email protected]49639fa2011-12-20 23:22:419002 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579003 EXPECT_EQ(ERR_IO_PENDING, rv);
9004
9005 rv = callback1.WaitForResult();
9006 EXPECT_EQ(OK, rv);
9007
9008 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509009 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049010 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579011
[email protected]49639fa2011-12-20 23:22:419012 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579013
[email protected]49639fa2011-12-20 23:22:419014 rv = trans->RestartWithAuth(
9015 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:579016 EXPECT_EQ(ERR_IO_PENDING, rv);
9017
9018 rv = callback2.WaitForResult();
9019 EXPECT_EQ(OK, rv);
9020
9021 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509022 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:579023 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9024 EXPECT_EQ(100, response->headers->GetContentLength());
9025}
9026
9027// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:029028TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039029 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579030
9031 HttpRequestInfo request;
9032 request.method = "GET";
bncce36dca22015-04-21 22:11:239033 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579034 request.load_flags = 0;
9035
9036 MockRead proxy_reads[] = {
9037 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069038 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579039 };
9040
[email protected]31a2bfe2010-02-09 08:03:399041 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069042 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579043
[email protected]bb88e1d32013-05-03 23:11:079044 session_deps_.socket_factory->AddSocketDataProvider(&data);
9045 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579046
[email protected]49639fa2011-12-20 23:22:419047 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579048
[email protected]bb88e1d32013-05-03 23:11:079049 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579050
mmenkee65e7af2015-10-13 17:16:429051 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579052 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419053 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579054
[email protected]49639fa2011-12-20 23:22:419055 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579056 EXPECT_EQ(ERR_IO_PENDING, rv);
9057
9058 rv = callback.WaitForResult();
9059 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
9060}
9061
[email protected]23e482282013-06-14 16:08:029062TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469063 HttpRequestInfo request;
9064 request.method = "GET";
bncce36dca22015-04-21 22:11:239065 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469066 request.load_flags = 0;
9067
mmenkee65e7af2015-10-13 17:16:429068 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:279069 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419070 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:279071
[email protected]e22e1362009-11-23 21:31:129072 MockRead data_reads[] = {
9073 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069074 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129075 };
[email protected]9492e4a2010-02-24 00:58:469076
9077 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079078 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469079
[email protected]49639fa2011-12-20 23:22:419080 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469081
[email protected]49639fa2011-12-20 23:22:419082 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:469083 EXPECT_EQ(ERR_IO_PENDING, rv);
9084
9085 EXPECT_EQ(OK, callback.WaitForResult());
9086
9087 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509088 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:469089
[email protected]90499482013-06-01 00:39:509090 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:469091 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9092
9093 std::string response_data;
9094 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:239095 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:129096}
9097
[email protected]23e482282013-06-14 16:08:029098TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159099 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529100 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:339101 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219102 UploadFileElementReader::ScopedOverridingContentLengthForTests
9103 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339104
[email protected]b2d26cfd2012-12-11 10:36:069105 ScopedVector<UploadElementReader> element_readers;
9106 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:459107 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
9108 temp_file_path, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:079109 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:279110
9111 HttpRequestInfo request;
9112 request.method = "POST";
bncce36dca22015-04-21 22:11:239113 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279114 request.upload_data_stream = &upload_data_stream;
9115 request.load_flags = 0;
9116
mmenkee65e7af2015-10-13 17:16:429117 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:279118 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419119 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:339120
9121 MockRead data_reads[] = {
9122 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9123 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069124 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339125 };
[email protected]31a2bfe2010-02-09 08:03:399126 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079127 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339128
[email protected]49639fa2011-12-20 23:22:419129 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339130
[email protected]49639fa2011-12-20 23:22:419131 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:339132 EXPECT_EQ(ERR_IO_PENDING, rv);
9133
9134 rv = callback.WaitForResult();
9135 EXPECT_EQ(OK, rv);
9136
9137 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509138 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:339139
[email protected]90499482013-06-01 00:39:509140 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:339141 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9142
9143 std::string response_data;
9144 rv = ReadTransaction(trans.get(), &response_data);
9145 EXPECT_EQ(OK, rv);
9146 EXPECT_EQ("hello world", response_data);
9147
[email protected]dd3aa792013-07-16 19:10:239148 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339149}
9150
[email protected]23e482282013-06-14 16:08:029151TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159152 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529153 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369154 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:309155 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:369156 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119157 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369158
[email protected]b2d26cfd2012-12-11 10:36:069159 ScopedVector<UploadElementReader> element_readers;
9160 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:459161 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
9162 temp_file, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:079163 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:279164
9165 HttpRequestInfo request;
9166 request.method = "POST";
bncce36dca22015-04-21 22:11:239167 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279168 request.upload_data_stream = &upload_data_stream;
9169 request.load_flags = 0;
9170
[email protected]999dd8c2013-11-12 06:45:549171 // If we try to upload an unreadable file, the transaction should fail.
mmenkee65e7af2015-10-13 17:16:429172 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:279173 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419174 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:369175
[email protected]999dd8c2013-11-12 06:45:549176 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079177 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369178
[email protected]49639fa2011-12-20 23:22:419179 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369180
[email protected]49639fa2011-12-20 23:22:419181 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:369182 EXPECT_EQ(ERR_IO_PENDING, rv);
9183
9184 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:549185 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:369186
[email protected]dd3aa792013-07-16 19:10:239187 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369188}
9189
[email protected]02cad5d2013-10-02 08:14:039190TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
9191 class FakeUploadElementReader : public UploadElementReader {
9192 public:
9193 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209194 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039195
9196 const CompletionCallback& callback() const { return callback_; }
9197
9198 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209199 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039200 callback_ = callback;
9201 return ERR_IO_PENDING;
9202 }
dchengb03027d2014-10-21 12:00:209203 uint64 GetContentLength() const override { return 0; }
9204 uint64 BytesRemaining() const override { return 0; }
9205 int Read(IOBuffer* buf,
9206 int buf_length,
9207 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039208 return ERR_FAILED;
9209 }
9210
9211 private:
9212 CompletionCallback callback_;
9213 };
9214
9215 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
9216 ScopedVector<UploadElementReader> element_readers;
9217 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:079218 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:039219
9220 HttpRequestInfo request;
9221 request.method = "POST";
bncce36dca22015-04-21 22:11:239222 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039223 request.upload_data_stream = &upload_data_stream;
9224 request.load_flags = 0;
9225
mmenkee65e7af2015-10-13 17:16:429226 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:039227 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419228 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039229
9230 StaticSocketDataProvider data;
9231 session_deps_.socket_factory->AddSocketDataProvider(&data);
9232
9233 TestCompletionCallback callback;
9234 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9235 EXPECT_EQ(ERR_IO_PENDING, rv);
9236 base::MessageLoop::current()->RunUntilIdle();
9237
9238 // Transaction is pending on request body initialization.
9239 ASSERT_FALSE(fake_reader->callback().is_null());
9240
9241 // Return Init()'s result after the transaction gets destroyed.
9242 trans.reset();
9243 fake_reader->callback().Run(OK); // Should not crash.
9244}
9245
[email protected]aeefc9e82010-02-19 16:18:279246// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:029247TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279248 HttpRequestInfo request;
9249 request.method = "GET";
bncce36dca22015-04-21 22:11:239250 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279251 request.load_flags = 0;
9252
9253 // First transaction will request a resource and receive a Basic challenge
9254 // with realm="first_realm".
9255 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239256 MockWrite(
9257 "GET / HTTP/1.1\r\n"
9258 "Host: www.example.org\r\n"
9259 "Connection: keep-alive\r\n"
9260 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279261 };
9262 MockRead data_reads1[] = {
9263 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9264 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9265 "\r\n"),
9266 };
9267
9268 // After calling trans->RestartWithAuth(), provide an Authentication header
9269 // for first_realm. The server will reject and provide a challenge with
9270 // second_realm.
9271 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239272 MockWrite(
9273 "GET / HTTP/1.1\r\n"
9274 "Host: www.example.org\r\n"
9275 "Connection: keep-alive\r\n"
9276 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9277 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279278 };
9279 MockRead data_reads2[] = {
9280 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9281 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9282 "\r\n"),
9283 };
9284
9285 // This again fails, and goes back to first_realm. Make sure that the
9286 // entry is removed from cache.
9287 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239288 MockWrite(
9289 "GET / HTTP/1.1\r\n"
9290 "Host: www.example.org\r\n"
9291 "Connection: keep-alive\r\n"
9292 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9293 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279294 };
9295 MockRead data_reads3[] = {
9296 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9297 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9298 "\r\n"),
9299 };
9300
9301 // Try one last time (with the correct password) and get the resource.
9302 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239303 MockWrite(
9304 "GET / HTTP/1.1\r\n"
9305 "Host: www.example.org\r\n"
9306 "Connection: keep-alive\r\n"
9307 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9308 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279309 };
9310 MockRead data_reads4[] = {
9311 MockRead("HTTP/1.1 200 OK\r\n"
9312 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509313 "Content-Length: 5\r\n"
9314 "\r\n"
9315 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279316 };
9317
9318 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9319 data_writes1, arraysize(data_writes1));
9320 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9321 data_writes2, arraysize(data_writes2));
9322 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9323 data_writes3, arraysize(data_writes3));
9324 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9325 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079326 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9327 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9328 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9329 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279330
[email protected]49639fa2011-12-20 23:22:419331 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279332
mmenkee65e7af2015-10-13 17:16:429333 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:509334 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419335 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509336
[email protected]aeefc9e82010-02-19 16:18:279337 // Issue the first request with Authorize headers. There should be a
9338 // password prompt for first_realm waiting to be filled in after the
9339 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419340 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:279341 EXPECT_EQ(ERR_IO_PENDING, rv);
9342 rv = callback1.WaitForResult();
9343 EXPECT_EQ(OK, rv);
9344 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509345 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049346 const AuthChallengeInfo* challenge = response->auth_challenge.get();
9347 ASSERT_FALSE(challenge == NULL);
9348 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239349 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049350 EXPECT_EQ("first_realm", challenge->realm);
9351 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279352
9353 // Issue the second request with an incorrect password. There should be a
9354 // password prompt for second_realm waiting to be filled in after the
9355 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419356 TestCompletionCallback callback2;
9357 rv = trans->RestartWithAuth(
9358 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:279359 EXPECT_EQ(ERR_IO_PENDING, rv);
9360 rv = callback2.WaitForResult();
9361 EXPECT_EQ(OK, rv);
9362 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509363 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049364 challenge = response->auth_challenge.get();
9365 ASSERT_FALSE(challenge == NULL);
9366 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239367 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049368 EXPECT_EQ("second_realm", challenge->realm);
9369 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279370
9371 // Issue the third request with another incorrect password. There should be
9372 // a password prompt for first_realm waiting to be filled in. If the password
9373 // prompt is not present, it indicates that the HttpAuthCacheEntry for
9374 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:419375 TestCompletionCallback callback3;
9376 rv = trans->RestartWithAuth(
9377 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:279378 EXPECT_EQ(ERR_IO_PENDING, rv);
9379 rv = callback3.WaitForResult();
9380 EXPECT_EQ(OK, rv);
9381 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509382 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049383 challenge = response->auth_challenge.get();
9384 ASSERT_FALSE(challenge == NULL);
9385 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239386 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049387 EXPECT_EQ("first_realm", challenge->realm);
9388 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279389
9390 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:419391 TestCompletionCallback callback4;
9392 rv = trans->RestartWithAuth(
9393 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:279394 EXPECT_EQ(ERR_IO_PENDING, rv);
9395 rv = callback4.WaitForResult();
9396 EXPECT_EQ(OK, rv);
9397 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509398 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:279399 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9400}
9401
bncc958faa2015-07-31 18:14:529402TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
9403 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359404 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529405
9406 std::string alternative_service_http_header =
9407 GetAlternativeServiceHttpHeader();
9408
9409 MockRead data_reads[] = {
9410 MockRead("HTTP/1.1 200 OK\r\n"),
9411 MockRead(alternative_service_http_header.c_str()),
9412 MockRead("\r\n"),
9413 MockRead("hello world"),
9414 MockRead(SYNCHRONOUS, OK),
9415 };
9416
9417 HttpRequestInfo request;
9418 request.method = "GET";
9419 request.url = GURL("http://www.example.org/");
9420 request.load_flags = 0;
9421
9422 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9423
9424 session_deps_.socket_factory->AddSocketDataProvider(&data);
9425
9426 TestCompletionCallback callback;
9427
mmenkee65e7af2015-10-13 17:16:429428 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529429 scoped_ptr<HttpTransaction> trans(
9430 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9431
9432 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9433 EXPECT_EQ(ERR_IO_PENDING, rv);
9434
9435 HostPortPair http_host_port_pair("www.example.org", 80);
9436 HttpServerProperties& http_server_properties =
9437 *session->http_server_properties();
9438 AlternativeServiceVector alternative_service_vector =
9439 http_server_properties.GetAlternativeServices(http_host_port_pair);
9440 EXPECT_TRUE(alternative_service_vector.empty());
9441
9442 EXPECT_EQ(OK, callback.WaitForResult());
9443
9444 const HttpResponseInfo* response = trans->GetResponseInfo();
9445 ASSERT_TRUE(response != NULL);
9446 ASSERT_TRUE(response->headers.get() != NULL);
9447 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9448 EXPECT_FALSE(response->was_fetched_via_spdy);
9449 EXPECT_FALSE(response->was_npn_negotiated);
9450
9451 std::string response_data;
9452 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9453 EXPECT_EQ("hello world", response_data);
9454
9455 alternative_service_vector =
9456 http_server_properties.GetAlternativeServices(http_host_port_pair);
9457 ASSERT_EQ(1u, alternative_service_vector.size());
9458 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9459 alternative_service_vector[0].protocol);
9460 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9461 EXPECT_EQ(443, alternative_service_vector[0].port);
9462}
9463
bnc4f575852015-10-14 18:35:089464TEST_P(HttpNetworkTransactionTest, ClearAlternativeServices) {
9465 session_deps_.next_protos = SpdyNextProtos();
9466 session_deps_.use_alternative_services = true;
9467
9468 // Set an alternative service for origin.
9469 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9470 HttpServerProperties& http_server_properties =
9471 *session->http_server_properties();
9472 HostPortPair http_host_port_pair("www.example.org", 80);
9473 AlternativeService alternative_service(QUIC, "", 80);
9474 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9475 http_server_properties.SetAlternativeService(
9476 http_host_port_pair, alternative_service, 1.0, expiration);
9477 AlternativeServiceVector alternative_service_vector =
9478 http_server_properties.GetAlternativeServices(http_host_port_pair);
9479 EXPECT_EQ(1u, alternative_service_vector.size());
9480
9481 // Send a clear header.
9482 MockRead data_reads[] = {
9483 MockRead("HTTP/1.1 200 OK\r\n"),
9484 MockRead("Alt-Svc: clear\r\n"),
9485 MockRead("\r\n"),
9486 MockRead("hello world"),
9487 MockRead(SYNCHRONOUS, OK),
9488 };
9489 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
9490 session_deps_.socket_factory->AddSocketDataProvider(&data);
9491
9492 HttpRequestInfo request;
9493 request.method = "GET";
9494 request.url = GURL("http://www.example.org/");
9495 request.load_flags = 0;
9496
9497 TestCompletionCallback callback;
9498
9499 scoped_ptr<HttpTransaction> trans(
9500 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9501
9502 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9503 EXPECT_EQ(OK, callback.GetResult(rv));
9504
9505 const HttpResponseInfo* response = trans->GetResponseInfo();
9506 ASSERT_TRUE(response != nullptr);
9507 ASSERT_TRUE(response->headers.get() != nullptr);
9508 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9509 EXPECT_FALSE(response->was_fetched_via_spdy);
9510 EXPECT_FALSE(response->was_npn_negotiated);
9511
9512 std::string response_data;
9513 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9514 EXPECT_EQ("hello world", response_data);
9515
9516 alternative_service_vector =
9517 http_server_properties.GetAlternativeServices(http_host_port_pair);
9518 EXPECT_TRUE(alternative_service_vector.empty());
9519}
9520
bnc54ec34b72015-08-26 19:34:569521// Alternative Service headers must be ignored when |use_alternative_services|
9522// is false.
9523TEST_P(HttpNetworkTransactionTest, DoNotHonorAlternativeServiceHeader) {
9524 session_deps_.next_protos = SpdyNextProtos();
9525 session_deps_.use_alternative_services = false;
9526
9527 std::string alternative_service_http_header =
9528 GetAlternativeServiceHttpHeader();
9529
9530 MockRead data_reads[] = {
9531 MockRead("HTTP/1.1 200 OK\r\n"),
9532 MockRead(alternative_service_http_header.c_str()),
9533 MockRead("\r\n"),
9534 MockRead("hello world"),
9535 MockRead(SYNCHRONOUS, OK),
9536 };
9537
9538 HttpRequestInfo request;
9539 request.method = "GET";
9540 request.url = GURL("http://www.example.org/");
9541 request.load_flags = 0;
9542
9543 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
9544
9545 session_deps_.socket_factory->AddSocketDataProvider(&data);
9546
9547 TestCompletionCallback callback;
9548
mmenkee65e7af2015-10-13 17:16:429549 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc54ec34b72015-08-26 19:34:569550 scoped_ptr<HttpTransaction> trans(
9551 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9552
9553 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9554 EXPECT_EQ(ERR_IO_PENDING, rv);
9555
9556 HostPortPair http_host_port_pair("www.example.org", 80);
9557 HttpServerProperties& http_server_properties =
9558 *session->http_server_properties();
9559 AlternativeServiceVector alternative_service_vector =
9560 http_server_properties.GetAlternativeServices(http_host_port_pair);
9561 EXPECT_TRUE(alternative_service_vector.empty());
9562
9563 EXPECT_EQ(OK, callback.WaitForResult());
9564
9565 const HttpResponseInfo* response = trans->GetResponseInfo();
9566 ASSERT_TRUE(response != nullptr);
9567 ASSERT_TRUE(response->headers.get() != nullptr);
9568 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9569 EXPECT_FALSE(response->was_fetched_via_spdy);
9570 EXPECT_FALSE(response->was_npn_negotiated);
9571
9572 std::string response_data;
9573 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9574 EXPECT_EQ("hello world", response_data);
9575
9576 alternative_service_vector =
9577 http_server_properties.GetAlternativeServices(http_host_port_pair);
9578 EXPECT_TRUE(alternative_service_vector.empty());
9579}
9580
bncc958faa2015-07-31 18:14:529581TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
9582 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359583 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529584
9585 MockRead data_reads[] = {
9586 MockRead("HTTP/1.1 200 OK\r\n"),
9587 MockRead("Alt-Svc: "),
9588 MockRead(GetAlternateProtocolFromParam()),
bnc44858c82015-10-16 11:57:219589 MockRead("=\"www.example.com:443\";p=\"1.0\","),
bncc958faa2015-07-31 18:14:529590 MockRead("quic=\":1234\"\r\n\r\n"),
9591 MockRead("hello world"),
9592 MockRead(SYNCHRONOUS, OK),
9593 };
9594
9595 HttpRequestInfo request;
9596 request.method = "GET";
9597 request.url = GURL("http://www.example.org/");
9598 request.load_flags = 0;
9599
9600 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9601
9602 session_deps_.socket_factory->AddSocketDataProvider(&data);
9603
9604 TestCompletionCallback callback;
9605
mmenkee65e7af2015-10-13 17:16:429606 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529607 scoped_ptr<HttpTransaction> trans(
9608 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9609
9610 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9611 EXPECT_EQ(ERR_IO_PENDING, rv);
9612
9613 HostPortPair http_host_port_pair("www.example.org", 80);
9614 HttpServerProperties& http_server_properties =
9615 *session->http_server_properties();
9616 AlternativeServiceVector alternative_service_vector =
9617 http_server_properties.GetAlternativeServices(http_host_port_pair);
9618 EXPECT_TRUE(alternative_service_vector.empty());
9619
9620 EXPECT_EQ(OK, callback.WaitForResult());
9621
9622 const HttpResponseInfo* response = trans->GetResponseInfo();
9623 ASSERT_TRUE(response != NULL);
9624 ASSERT_TRUE(response->headers.get() != NULL);
9625 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9626 EXPECT_FALSE(response->was_fetched_via_spdy);
9627 EXPECT_FALSE(response->was_npn_negotiated);
9628
9629 std::string response_data;
9630 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9631 EXPECT_EQ("hello world", response_data);
9632
9633 alternative_service_vector =
9634 http_server_properties.GetAlternativeServices(http_host_port_pair);
9635 ASSERT_EQ(2u, alternative_service_vector.size());
9636 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9637 alternative_service_vector[0].protocol);
9638 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9639 EXPECT_EQ(443, alternative_service_vector[0].port);
9640 EXPECT_EQ(QUIC, alternative_service_vector[1].protocol);
9641 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
9642 EXPECT_EQ(1234, alternative_service_vector[1].port);
9643}
9644
bnc54ec34b72015-08-26 19:34:569645// Alternate Protocol headers must be honored even if |use_alternative_services|
9646// is false.
[email protected]23e482282013-06-14 16:08:029647TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:239648 session_deps_.next_protos = SpdyNextProtos();
bnc54ec34b72015-08-26 19:34:569649 session_deps_.use_alternative_services = false;
[email protected]a2cb8122010-03-10 17:22:429650
[email protected]8a0fc822013-06-27 20:52:439651 std::string alternate_protocol_http_header =
9652 GetAlternateProtocolHttpHeader();
9653
[email protected]564b4912010-03-09 16:30:429654 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529655 MockRead("HTTP/1.1 200 OK\r\n"),
9656 MockRead(alternate_protocol_http_header.c_str()),
9657 MockRead("\r\n"),
9658 MockRead("hello world"),
9659 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:429660 };
9661
9662 HttpRequestInfo request;
9663 request.method = "GET";
bncce36dca22015-04-21 22:11:239664 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429665 request.load_flags = 0;
9666
9667 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9668
[email protected]bb88e1d32013-05-03 23:11:079669 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:429670
[email protected]49639fa2011-12-20 23:22:419671 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429672
mmenkee65e7af2015-10-13 17:16:429673 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369674 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509675 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:429676
[email protected]49639fa2011-12-20 23:22:419677 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429678 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:539679
bncce36dca22015-04-21 22:11:239680 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:559681 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:539682 *session->http_server_properties();
bncd9b132e2015-07-08 05:16:109683 AlternativeServiceVector alternative_service_vector =
9684 http_server_properties.GetAlternativeServices(http_host_port_pair);
9685 EXPECT_TRUE(alternative_service_vector.empty());
[email protected]564b4912010-03-09 16:30:429686
9687 EXPECT_EQ(OK, callback.WaitForResult());
9688
9689 const HttpResponseInfo* response = trans->GetResponseInfo();
9690 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509691 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429692 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539693 EXPECT_FALSE(response->was_fetched_via_spdy);
9694 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:429695
9696 std::string response_data;
9697 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9698 EXPECT_EQ("hello world", response_data);
9699
bncd9b132e2015-07-08 05:16:109700 alternative_service_vector =
9701 http_server_properties.GetAlternativeServices(http_host_port_pair);
9702 ASSERT_EQ(1u, alternative_service_vector.size());
9703 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc181b39a2015-03-17 21:36:479704 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
bncd9b132e2015-07-08 05:16:109705 alternative_service_vector[0].protocol);
[email protected]564b4912010-03-09 16:30:429706}
9707
rch89c6e102015-03-18 18:56:529708TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
9709 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359710 session_deps_.use_alternative_services = true;
rch89c6e102015-03-18 18:56:529711
9712 MockRead data_reads[] = {
9713 MockRead("HTTP/1.1 200 OK\r\n"),
9714 MockRead("Alternate-Protocol: \r\n\r\n"),
9715 MockRead("hello world"),
9716 MockRead(SYNCHRONOUS, OK),
9717 };
9718
9719 HttpRequestInfo request;
9720 request.method = "GET";
bncce36dca22015-04-21 22:11:239721 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:529722 request.load_flags = 0;
9723
9724 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9725
9726 session_deps_.socket_factory->AddSocketDataProvider(&data);
9727
9728 TestCompletionCallback callback;
9729
mmenkee65e7af2015-10-13 17:16:429730 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rch89c6e102015-03-18 18:56:529731
bncce36dca22015-04-21 22:11:239732 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:529733 HttpServerProperties& http_server_properties =
9734 *session->http_server_properties();
bnccacc0992015-03-20 20:22:229735 AlternativeService alternative_service(QUIC, "", 80);
bnc7dc7e1b42015-07-28 14:43:129736 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9737 http_server_properties.SetAlternativeService(
9738 http_host_port_pair, alternative_service, 1.0, expiration);
bnccacc0992015-03-20 20:22:229739
bncd9b132e2015-07-08 05:16:109740 AlternativeServiceVector alternative_service_vector =
9741 http_server_properties.GetAlternativeServices(http_host_port_pair);
9742 ASSERT_EQ(1u, alternative_service_vector.size());
9743 EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
rch89c6e102015-03-18 18:56:529744
9745 scoped_ptr<HttpTransaction> trans(
9746 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9747
9748 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9749 EXPECT_EQ(ERR_IO_PENDING, rv);
9750
9751 EXPECT_EQ(OK, callback.WaitForResult());
9752
9753 const HttpResponseInfo* response = trans->GetResponseInfo();
9754 ASSERT_TRUE(response != NULL);
9755 ASSERT_TRUE(response->headers.get() != NULL);
9756 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9757 EXPECT_FALSE(response->was_fetched_via_spdy);
9758 EXPECT_FALSE(response->was_npn_negotiated);
9759
9760 std::string response_data;
9761 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9762 EXPECT_EQ("hello world", response_data);
9763
bncd9b132e2015-07-08 05:16:109764 alternative_service_vector =
9765 http_server_properties.GetAlternativeServices(http_host_port_pair);
9766 EXPECT_TRUE(alternative_service_vector.empty());
rch89c6e102015-03-18 18:56:529767}
9768
bncc958faa2015-07-31 18:14:529769TEST_P(HttpNetworkTransactionTest, AltSvcOverwritesAlternateProtocol) {
9770 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359771 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529772
9773 std::string alternative_service_http_header =
9774 GetAlternativeServiceHttpHeader();
9775 std::string alternate_protocol_http_header = GetAlternateProtocolHttpHeader();
9776
9777 MockRead data_reads[] = {
9778 MockRead("HTTP/1.1 200 OK\r\n"),
9779 MockRead(alternative_service_http_header.c_str()),
9780 MockRead(alternate_protocol_http_header.c_str()),
9781 MockRead("\r\n"),
9782 MockRead("hello world"),
9783 MockRead(SYNCHRONOUS, OK),
9784 };
9785
9786 HttpRequestInfo request;
9787 request.method = "GET";
9788 request.url = GURL("http://www.example.org/");
9789 request.load_flags = 0;
9790
9791 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9792
9793 session_deps_.socket_factory->AddSocketDataProvider(&data);
9794
9795 TestCompletionCallback callback;
9796
mmenkee65e7af2015-10-13 17:16:429797 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529798 scoped_ptr<HttpTransaction> trans(
9799 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9800
9801 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9802 EXPECT_EQ(ERR_IO_PENDING, rv);
9803
9804 HostPortPair http_host_port_pair("www.example.org", 80);
9805 HttpServerProperties& http_server_properties =
9806 *session->http_server_properties();
9807 AlternativeServiceVector alternative_service_vector =
9808 http_server_properties.GetAlternativeServices(http_host_port_pair);
9809 EXPECT_TRUE(alternative_service_vector.empty());
9810
9811 EXPECT_EQ(OK, callback.WaitForResult());
9812
9813 const HttpResponseInfo* response = trans->GetResponseInfo();
9814 ASSERT_TRUE(response != NULL);
9815 ASSERT_TRUE(response->headers.get() != NULL);
9816 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9817 EXPECT_FALSE(response->was_fetched_via_spdy);
9818 EXPECT_FALSE(response->was_npn_negotiated);
9819
9820 std::string response_data;
9821 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9822 EXPECT_EQ("hello world", response_data);
9823
9824 alternative_service_vector =
9825 http_server_properties.GetAlternativeServices(http_host_port_pair);
9826 ASSERT_EQ(1u, alternative_service_vector.size());
9827 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9828 alternative_service_vector[0].protocol);
9829 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9830 EXPECT_EQ(443, alternative_service_vector[0].port);
9831}
9832
bnc54ec34b72015-08-26 19:34:569833// When |use_alternative_services| is false, do not observe alternative service
9834// entries that point to a different host.
9835TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
9836 session_deps_.use_alternative_services = false;
9837
9838 HttpRequestInfo request;
9839 request.method = "GET";
9840 request.url = GURL("http://www.example.org/");
9841 request.load_flags = 0;
9842
9843 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9844 StaticSocketDataProvider first_data;
9845 first_data.set_connect_data(mock_connect);
9846 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
9847
9848 MockRead data_reads[] = {
9849 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
9850 MockRead(ASYNC, OK),
9851 };
9852 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
9853 nullptr, 0);
9854 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
9855
mmenkee65e7af2015-10-13 17:16:429856 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc54ec34b72015-08-26 19:34:569857
9858 base::WeakPtr<HttpServerProperties> http_server_properties =
9859 session->http_server_properties();
9860 AlternativeService alternative_service(
9861 AlternateProtocolFromNextProto(GetParam()), "different.example.org", 80);
9862 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9863 http_server_properties->SetAlternativeService(
9864 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
9865
9866 scoped_ptr<HttpTransaction> trans(
9867 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9868 TestCompletionCallback callback;
9869
9870 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9871 // The connetion to origin was refused, and the alternative service should not
9872 // be used (even though mock data are there), therefore the request should
9873 // fail.
9874 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
9875}
9876
[email protected]23e482282013-06-14 16:08:029877TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239878 MarkBrokenAlternateProtocolAndFallback) {
bnc55ff9da2015-08-19 18:42:359879 session_deps_.use_alternative_services = true;
[email protected]564b4912010-03-09 16:30:429880
9881 HttpRequestInfo request;
9882 request.method = "GET";
bncce36dca22015-04-21 22:11:239883 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429884 request.load_flags = 0;
9885
[email protected]d973e99a2012-02-17 21:02:369886 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:429887 StaticSocketDataProvider first_data;
9888 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079889 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:429890
9891 MockRead data_reads[] = {
9892 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9893 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069894 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:429895 };
9896 StaticSocketDataProvider second_data(
9897 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079898 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:429899
mmenkee65e7af2015-10-13 17:16:429900 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:429901
[email protected]30d4c022013-07-18 22:58:169902 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539903 session->http_server_properties();
bnc8445b3002015-03-13 01:57:099904 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:119905 // Port must be < 1024, or the header will be ignored (since initial port was
9906 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:109907 const AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239908 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bncd9b132e2015-07-08 05:16:109909 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:129910 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9911 http_server_properties->SetAlternativeService(
9912 host_port_pair, alternative_service, 1.0, expiration);
[email protected]564b4912010-03-09 16:30:429913
[email protected]262eec82013-03-19 21:01:369914 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509915 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419916 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429917
[email protected]49639fa2011-12-20 23:22:419918 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429919 EXPECT_EQ(ERR_IO_PENDING, rv);
9920 EXPECT_EQ(OK, callback.WaitForResult());
9921
9922 const HttpResponseInfo* response = trans->GetResponseInfo();
9923 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509924 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429925 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9926
9927 std::string response_data;
9928 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9929 EXPECT_EQ("hello world", response_data);
9930
bncd9b132e2015-07-08 05:16:109931 const AlternativeServiceVector alternative_service_vector =
9932 http_server_properties->GetAlternativeServices(host_port_pair);
9933 ASSERT_EQ(1u, alternative_service_vector.size());
9934 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
9935 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
9936 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:429937}
9938
bnc55ff9da2015-08-19 18:42:359939// Ensure that we are not allowed to redirect traffic via an alternate protocol
9940// to an unrestricted (port >= 1024) when the original traffic was on a
9941// restricted port (port < 1024). Ensure that we can redirect in all other
9942// cases.
[email protected]23e482282013-06-14 16:08:029943TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239944 AlternateProtocolPortRestrictedBlocked) {
bnc55ff9da2015-08-19 18:42:359945 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119946
9947 HttpRequestInfo restricted_port_request;
9948 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239949 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119950 restricted_port_request.load_flags = 0;
9951
[email protected]d973e99a2012-02-17 21:02:369952 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119953 StaticSocketDataProvider first_data;
9954 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079955 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119956
9957 MockRead data_reads[] = {
9958 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9959 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069960 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119961 };
9962 StaticSocketDataProvider second_data(
9963 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079964 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119965
mmenkee65e7af2015-10-13 17:16:429966 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119967
[email protected]30d4c022013-07-18 22:58:169968 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539969 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119970 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229971 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239972 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229973 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129974 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229975 http_server_properties->SetAlternativeService(
9976 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129977 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119978
[email protected]262eec82013-03-19 21:01:369979 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509980 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419981 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119982
[email protected]49639fa2011-12-20 23:22:419983 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369984 &restricted_port_request,
9985 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119986 EXPECT_EQ(ERR_IO_PENDING, rv);
9987 // Invalid change to unrestricted port should fail.
9988 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:199989}
[email protected]3912662a32011-10-04 00:51:119990
bnc55ff9da2015-08-19 18:42:359991// Ensure that we are allowed to redirect traffic via an alternate protocol to
9992// an unrestricted (port >= 1024) when the original traffic was on a restricted
9993// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:029994TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:199995 AlternateProtocolPortRestrictedPermitted) {
bnc55ff9da2015-08-19 18:42:359996 session_deps_.use_alternative_services = true;
[email protected]bb88e1d32013-05-03 23:11:079997 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:199998
9999 HttpRequestInfo restricted_port_request;
10000 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310001 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910002 restricted_port_request.load_flags = 0;
10003
10004 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10005 StaticSocketDataProvider first_data;
10006 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710007 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910008
10009 MockRead data_reads[] = {
10010 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10011 MockRead("hello world"),
10012 MockRead(ASYNC, OK),
10013 };
10014 StaticSocketDataProvider second_data(
10015 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710016 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:1910017
mmenkee65e7af2015-10-13 17:16:4210018 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910019
[email protected]30d4c022013-07-18 22:58:1610020 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910021 session->http_server_properties();
10022 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210023 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:2310024 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:2210025 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210026 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210027 http_server_properties->SetAlternativeService(
10028 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:1210029 1.0, expiration);
[email protected]c54c6962013-02-01 04:53:1910030
[email protected]262eec82013-03-19 21:01:3610031 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010032 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:1910033 TestCompletionCallback callback;
10034
10035 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:3610036 &restricted_port_request,
10037 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:1910038 // Change to unrestricted port should succeed.
10039 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110040}
10041
bnc55ff9da2015-08-19 18:42:3510042// Ensure that we are not allowed to redirect traffic via an alternate protocol
10043// to an unrestricted (port >= 1024) when the original traffic was on a
10044// restricted port (port < 1024). Ensure that we can redirect in all other
10045// cases.
[email protected]23e482282013-06-14 16:08:0210046TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310047 AlternateProtocolPortRestrictedAllowed) {
bnc55ff9da2015-08-19 18:42:3510048 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:1110049
10050 HttpRequestInfo restricted_port_request;
10051 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310052 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110053 restricted_port_request.load_flags = 0;
10054
[email protected]d973e99a2012-02-17 21:02:3610055 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110056 StaticSocketDataProvider first_data;
10057 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710058 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110059
10060 MockRead data_reads[] = {
10061 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10062 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610063 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110064 };
10065 StaticSocketDataProvider second_data(
10066 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710067 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110068
mmenkee65e7af2015-10-13 17:16:4210069 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110070
[email protected]30d4c022013-07-18 22:58:1610071 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310072 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110073 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210074 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:2310075 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:2210076 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210077 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210078 http_server_properties->SetAlternativeService(
10079 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:1210080 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:1110081
[email protected]262eec82013-03-19 21:01:3610082 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010083 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110084 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110085
[email protected]49639fa2011-12-20 23:22:4110086 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610087 &restricted_port_request,
10088 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110089 EXPECT_EQ(ERR_IO_PENDING, rv);
10090 // Valid change to restricted port should pass.
10091 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110092}
10093
bnc55ff9da2015-08-19 18:42:3510094// Ensure that we are not allowed to redirect traffic via an alternate protocol
10095// to an unrestricted (port >= 1024) when the original traffic was on a
10096// restricted port (port < 1024). Ensure that we can redirect in all other
10097// cases.
[email protected]23e482282013-06-14 16:08:0210098TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310099 AlternateProtocolPortUnrestrictedAllowed1) {
bnc55ff9da2015-08-19 18:42:3510100 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:1110101
10102 HttpRequestInfo unrestricted_port_request;
10103 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310104 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110105 unrestricted_port_request.load_flags = 0;
10106
[email protected]d973e99a2012-02-17 21:02:3610107 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110108 StaticSocketDataProvider first_data;
10109 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710110 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110111
10112 MockRead data_reads[] = {
10113 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10114 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610115 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110116 };
10117 StaticSocketDataProvider second_data(
10118 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710119 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110120
mmenkee65e7af2015-10-13 17:16:4210121 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110122
[email protected]30d4c022013-07-18 22:58:1610123 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310124 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110125 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210126 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:2310127 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:2210128 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210129 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210130 http_server_properties->SetAlternativeService(
10131 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:1210132 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:1110133
[email protected]262eec82013-03-19 21:01:3610134 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010135 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110136 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110137
[email protected]49639fa2011-12-20 23:22:4110138 int rv = trans->Start(
10139 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110140 EXPECT_EQ(ERR_IO_PENDING, rv);
10141 // Valid change to restricted port should pass.
10142 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110143}
10144
bnc55ff9da2015-08-19 18:42:3510145// Ensure that we are not allowed to redirect traffic via an alternate protocol
10146// to an unrestricted (port >= 1024) when the original traffic was on a
10147// restricted port (port < 1024). Ensure that we can redirect in all other
10148// cases.
[email protected]23e482282013-06-14 16:08:0210149TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310150 AlternateProtocolPortUnrestrictedAllowed2) {
bnc55ff9da2015-08-19 18:42:3510151 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:1110152
10153 HttpRequestInfo unrestricted_port_request;
10154 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310155 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110156 unrestricted_port_request.load_flags = 0;
10157
[email protected]d973e99a2012-02-17 21:02:3610158 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110159 StaticSocketDataProvider first_data;
10160 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710161 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110162
10163 MockRead data_reads[] = {
10164 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10165 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610166 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110167 };
10168 StaticSocketDataProvider second_data(
10169 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710170 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110171
mmenkee65e7af2015-10-13 17:16:4210172 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110173
[email protected]30d4c022013-07-18 22:58:1610174 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310175 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210176 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:2210177 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:2310178 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:2210179 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210180 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210181 http_server_properties->SetAlternativeService(
10182 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:1210183 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:1110184
[email protected]262eec82013-03-19 21:01:3610185 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010186 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110187 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110188
[email protected]49639fa2011-12-20 23:22:4110189 int rv = trans->Start(
10190 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110191 EXPECT_EQ(ERR_IO_PENDING, rv);
10192 // Valid change to an unrestricted port should pass.
10193 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110194}
10195
bnc55ff9da2015-08-19 18:42:3510196// Ensure that we are not allowed to redirect traffic via an alternate protocol
10197// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10198// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:2310199TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bnc55ff9da2015-08-19 18:42:3510200 session_deps_.use_alternative_services = true;
[email protected]eb6234e2012-01-19 01:50:0210201
10202 HttpRequestInfo request;
10203 request.method = "GET";
bncce36dca22015-04-21 22:11:2310204 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210205 request.load_flags = 0;
10206
10207 // The alternate protocol request will error out before we attempt to connect,
10208 // so only the standard HTTP request will try to connect.
10209 MockRead data_reads[] = {
10210 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10211 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610212 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210213 };
10214 StaticSocketDataProvider data(
10215 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710216 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210217
mmenkee65e7af2015-10-13 17:16:4210218 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210219
[email protected]30d4c022013-07-18 22:58:1610220 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210221 session->http_server_properties();
10222 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:2210223 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:2310224 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:2210225 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210226 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210227 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:1210228 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
[email protected]eb6234e2012-01-19 01:50:0210229
[email protected]262eec82013-03-19 21:01:3610230 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010231 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:0210232 TestCompletionCallback callback;
10233
10234 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10235 EXPECT_EQ(ERR_IO_PENDING, rv);
10236 // The HTTP request should succeed.
10237 EXPECT_EQ(OK, callback.WaitForResult());
10238
[email protected]eb6234e2012-01-19 01:50:0210239 const HttpResponseInfo* response = trans->GetResponseInfo();
10240 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010241 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:0210242 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10243
10244 std::string response_data;
10245 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10246 EXPECT_EQ("hello world", response_data);
10247}
10248
[email protected]23e482282013-06-14 16:08:0210249TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:3510250 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310251 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:5410252
10253 HttpRequestInfo request;
10254 request.method = "GET";
bncce36dca22015-04-21 22:11:2310255 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410256 request.load_flags = 0;
10257
[email protected]8a0fc822013-06-27 20:52:4310258 std::string alternate_protocol_http_header =
10259 GetAlternateProtocolHttpHeader();
10260
[email protected]2ff8b312010-04-26 22:20:5410261 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210262 MockRead("HTTP/1.1 200 OK\r\n"),
10263 MockRead(alternate_protocol_http_header.c_str()),
10264 MockRead("\r\n"),
10265 MockRead("hello world"),
10266 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10267 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410268
10269 StaticSocketDataProvider first_transaction(
10270 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710271 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410272
[email protected]8ddf8322012-02-23 18:08:0610273 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210274 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310275 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10276 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710277 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410278
[email protected]cdf8f7e72013-05-23 10:56:4610279 scoped_ptr<SpdyFrame> req(
10280 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310281 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410282
[email protected]23e482282013-06-14 16:08:0210283 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10284 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410285 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310286 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410287 };
10288
rch8e6c6c42015-05-01 14:05:1310289 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10290 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710291 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410292
[email protected]d973e99a2012-02-17 21:02:3610293 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510294 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10295 NULL, 0, NULL, 0);
10296 hanging_non_alternate_protocol_socket.set_connect_data(
10297 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710298 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510299 &hanging_non_alternate_protocol_socket);
10300
[email protected]49639fa2011-12-20 23:22:4110301 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410302
mmenkee65e7af2015-10-13 17:16:4210303 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610304 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010305 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410306
[email protected]49639fa2011-12-20 23:22:4110307 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410308 EXPECT_EQ(ERR_IO_PENDING, rv);
10309 EXPECT_EQ(OK, callback.WaitForResult());
10310
10311 const HttpResponseInfo* response = trans->GetResponseInfo();
10312 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010313 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410314 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10315
10316 std::string response_data;
10317 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10318 EXPECT_EQ("hello world", response_data);
10319
[email protected]90499482013-06-01 00:39:5010320 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410321
[email protected]49639fa2011-12-20 23:22:4110322 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410323 EXPECT_EQ(ERR_IO_PENDING, rv);
10324 EXPECT_EQ(OK, callback.WaitForResult());
10325
10326 response = trans->GetResponseInfo();
10327 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010328 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410329 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310330 EXPECT_TRUE(response->was_fetched_via_spdy);
10331 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410332
10333 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10334 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410335}
10336
[email protected]23e482282013-06-14 16:08:0210337TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
bnc55ff9da2015-08-19 18:42:3510338 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310339 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:5510340
10341 HttpRequestInfo request;
10342 request.method = "GET";
bncce36dca22015-04-21 22:11:2310343 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510344 request.load_flags = 0;
10345
[email protected]8a0fc822013-06-27 20:52:4310346 std::string alternate_protocol_http_header =
10347 GetAlternateProtocolHttpHeader();
10348
[email protected]2d6728692011-03-12 01:39:5510349 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210350 MockRead("HTTP/1.1 200 OK\r\n"),
10351 MockRead(alternate_protocol_http_header.c_str()),
10352 MockRead("\r\n"),
10353 MockRead("hello world"),
10354 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10355 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510356 };
10357
10358 StaticSocketDataProvider first_transaction(
10359 data_reads, arraysize(data_reads), NULL, 0);
10360 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:0710361 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510362
[email protected]d973e99a2012-02-17 21:02:3610363 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510364 StaticSocketDataProvider hanging_socket(
10365 NULL, 0, NULL, 0);
10366 hanging_socket.set_connect_data(never_finishing_connect);
10367 // Socket 2 and 3 are the hanging Alternate-Protocol and
10368 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:0710369 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
10370 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:5510371
[email protected]8ddf8322012-02-23 18:08:0610372 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210373 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310374 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10375 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710376 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510377
[email protected]cdf8f7e72013-05-23 10:56:4610378 scoped_ptr<SpdyFrame> req1(
10379 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
10380 scoped_ptr<SpdyFrame> req2(
10381 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:5510382 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310383 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:5510384 };
[email protected]23e482282013-06-14 16:08:0210385 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10386 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
10387 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10388 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510389 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310390 CreateMockRead(*resp1, 2),
10391 CreateMockRead(*data1, 3),
10392 CreateMockRead(*resp2, 4),
10393 CreateMockRead(*data2, 5),
10394 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510395 };
10396
rch8e6c6c42015-05-01 14:05:1310397 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10398 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:5510399 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:0710400 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510401
10402 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:0710403 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:5510404
mmenkee65e7af2015-10-13 17:16:4210405 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110406 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010407 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510408
[email protected]49639fa2011-12-20 23:22:4110409 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510410 EXPECT_EQ(ERR_IO_PENDING, rv);
10411 EXPECT_EQ(OK, callback1.WaitForResult());
10412
10413 const HttpResponseInfo* response = trans1.GetResponseInfo();
10414 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010415 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510416 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10417
10418 std::string response_data;
10419 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10420 EXPECT_EQ("hello world", response_data);
10421
[email protected]49639fa2011-12-20 23:22:4110422 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5010423 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110424 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510425 EXPECT_EQ(ERR_IO_PENDING, rv);
10426
[email protected]49639fa2011-12-20 23:22:4110427 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5010428 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110429 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510430 EXPECT_EQ(ERR_IO_PENDING, rv);
10431
10432 EXPECT_EQ(OK, callback2.WaitForResult());
10433 EXPECT_EQ(OK, callback3.WaitForResult());
10434
10435 response = trans2.GetResponseInfo();
10436 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010437 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510438 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10439 EXPECT_TRUE(response->was_fetched_via_spdy);
10440 EXPECT_TRUE(response->was_npn_negotiated);
10441 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10442 EXPECT_EQ("hello!", response_data);
10443
10444 response = trans3.GetResponseInfo();
10445 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010446 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510447 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10448 EXPECT_TRUE(response->was_fetched_via_spdy);
10449 EXPECT_TRUE(response->was_npn_negotiated);
10450 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
10451 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5510452}
10453
[email protected]23e482282013-06-14 16:08:0210454TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:3510455 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310456 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:5510457
10458 HttpRequestInfo request;
10459 request.method = "GET";
bncce36dca22015-04-21 22:11:2310460 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510461 request.load_flags = 0;
10462
[email protected]8a0fc822013-06-27 20:52:4310463 std::string alternate_protocol_http_header =
10464 GetAlternateProtocolHttpHeader();
10465
[email protected]2d6728692011-03-12 01:39:5510466 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210467 MockRead("HTTP/1.1 200 OK\r\n"),
10468 MockRead(alternate_protocol_http_header.c_str()),
10469 MockRead("\r\n"),
10470 MockRead("hello world"),
10471 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10472 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510473 };
10474
10475 StaticSocketDataProvider first_transaction(
10476 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710477 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510478
[email protected]8ddf8322012-02-23 18:08:0610479 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210480 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710481 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510482
[email protected]d973e99a2012-02-17 21:02:3610483 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510484 StaticSocketDataProvider hanging_alternate_protocol_socket(
10485 NULL, 0, NULL, 0);
10486 hanging_alternate_protocol_socket.set_connect_data(
10487 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710488 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510489 &hanging_alternate_protocol_socket);
10490
10491 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:0710492 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510493
[email protected]49639fa2011-12-20 23:22:4110494 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5510495
mmenkee65e7af2015-10-13 17:16:4210496 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610497 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010498 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510499
[email protected]49639fa2011-12-20 23:22:4110500 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510501 EXPECT_EQ(ERR_IO_PENDING, rv);
10502 EXPECT_EQ(OK, callback.WaitForResult());
10503
10504 const HttpResponseInfo* response = trans->GetResponseInfo();
10505 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010506 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510507 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10508
10509 std::string response_data;
10510 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10511 EXPECT_EQ("hello world", response_data);
10512
[email protected]90499482013-06-01 00:39:5010513 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510514
[email protected]49639fa2011-12-20 23:22:4110515 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510516 EXPECT_EQ(ERR_IO_PENDING, rv);
10517 EXPECT_EQ(OK, callback.WaitForResult());
10518
10519 response = trans->GetResponseInfo();
10520 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010521 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510522 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10523 EXPECT_FALSE(response->was_fetched_via_spdy);
10524 EXPECT_FALSE(response->was_npn_negotiated);
10525
10526 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10527 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5510528}
10529
[email protected]631f1322010-04-30 17:59:1110530class CapturingProxyResolver : public ProxyResolver {
10531 public:
sammce90c9212015-05-27 23:43:3510532 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2010533 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1110534
dchengb03027d2014-10-21 12:00:2010535 int GetProxyForURL(const GURL& url,
10536 ProxyInfo* results,
10537 const CompletionCallback& callback,
10538 RequestHandle* request,
10539 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4010540 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
10541 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4210542 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1110543 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4210544 return OK;
[email protected]631f1322010-04-30 17:59:1110545 }
10546
dchengb03027d2014-10-21 12:00:2010547 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:1110548
dchengb03027d2014-10-21 12:00:2010549 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:1710550 NOTREACHED();
10551 return LOAD_STATE_IDLE;
10552 }
10553
[email protected]24476402010-07-20 20:55:1710554 const std::vector<GURL>& resolved() const { return resolved_; }
10555
10556 private:
[email protected]631f1322010-04-30 17:59:1110557 std::vector<GURL> resolved_;
10558
10559 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
10560};
10561
sammce64b2362015-04-29 03:50:2310562class CapturingProxyResolverFactory : public ProxyResolverFactory {
10563 public:
10564 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
10565 : ProxyResolverFactory(false), resolver_(resolver) {}
10566
10567 int CreateProxyResolver(
10568 const scoped_refptr<ProxyResolverScriptData>& pac_script,
10569 scoped_ptr<ProxyResolver>* resolver,
10570 const net::CompletionCallback& callback,
10571 scoped_ptr<Request>* request) override {
10572 resolver->reset(new ForwardingProxyResolver(resolver_));
10573 return OK;
10574 }
10575
10576 private:
10577 ProxyResolver* resolver_;
10578};
10579
[email protected]23e482282013-06-14 16:08:0210580TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310581 UseAlternateProtocolForTunneledNpnSpdy) {
bnc55ff9da2015-08-19 18:42:3510582 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310583 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:1110584
10585 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4210586 proxy_config.set_auto_detect(true);
10587 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1110588
sammc5dd160c2015-04-02 02:43:1310589 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710590 session_deps_.proxy_service.reset(new ProxyService(
csharrisonb7e3a082015-09-22 19:13:0410591 make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)),
sammc5dd160c2015-04-02 02:43:1310592 make_scoped_ptr(
sammce64b2362015-04-29 03:50:2310593 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:3810594 NULL));
vishal.b62985ca92015-04-17 08:45:5110595 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710596 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1110597
10598 HttpRequestInfo request;
10599 request.method = "GET";
bncce36dca22015-04-21 22:11:2310600 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:1110601 request.load_flags = 0;
10602
[email protected]8a0fc822013-06-27 20:52:4310603 std::string alternate_protocol_http_header =
10604 GetAlternateProtocolHttpHeader();
10605
[email protected]631f1322010-04-30 17:59:1110606 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210607 MockRead("HTTP/1.1 200 OK\r\n"),
10608 MockRead(alternate_protocol_http_header.c_str()),
10609 MockRead("\r\n"),
10610 MockRead("hello world"),
10611 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10612 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1110613 };
10614
10615 StaticSocketDataProvider first_transaction(
10616 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710617 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:1110618
[email protected]8ddf8322012-02-23 18:08:0610619 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210620 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310621 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10622 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:1110624
[email protected]cdf8f7e72013-05-23 10:56:4610625 scoped_ptr<SpdyFrame> req(
10626 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:1110627 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310628 MockWrite(ASYNC, 0,
10629 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10630 "Host: www.example.org\r\n"
10631 "Proxy-Connection: keep-alive\r\n\r\n"),
10632 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:1110633 };
10634
[email protected]d911f1b2010-05-05 22:39:4210635 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10636
[email protected]23e482282013-06-14 16:08:0210637 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10638 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1110639 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310640 MockRead(ASYNC, 1, kCONNECTResponse),
10641 CreateMockRead(*resp.get(), 3),
10642 CreateMockRead(*data.get(), 4),
10643 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1110644 };
10645
rch8e6c6c42015-05-01 14:05:1310646 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10647 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710648 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1110649
[email protected]d973e99a2012-02-17 21:02:3610650 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510651 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10652 NULL, 0, NULL, 0);
10653 hanging_non_alternate_protocol_socket.set_connect_data(
10654 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710655 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510656 &hanging_non_alternate_protocol_socket);
10657
[email protected]49639fa2011-12-20 23:22:4110658 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1110659
mmenkee65e7af2015-10-13 17:16:4210660 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610661 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010662 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110663
[email protected]49639fa2011-12-20 23:22:4110664 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110665 EXPECT_EQ(ERR_IO_PENDING, rv);
10666 EXPECT_EQ(OK, callback.WaitForResult());
10667
10668 const HttpResponseInfo* response = trans->GetResponseInfo();
10669 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010670 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110671 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310672 EXPECT_FALSE(response->was_fetched_via_spdy);
10673 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110674
10675 std::string response_data;
10676 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10677 EXPECT_EQ("hello world", response_data);
10678
[email protected]90499482013-06-01 00:39:5010679 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110680
[email protected]49639fa2011-12-20 23:22:4110681 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110682 EXPECT_EQ(ERR_IO_PENDING, rv);
10683 EXPECT_EQ(OK, callback.WaitForResult());
10684
10685 response = trans->GetResponseInfo();
10686 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010687 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110688 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310689 EXPECT_TRUE(response->was_fetched_via_spdy);
10690 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110691
10692 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10693 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1310694 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2310695 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310696 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2310697 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310698 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1110699
[email protected]029c83b62013-01-24 05:28:2010700 LoadTimingInfo load_timing_info;
10701 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10702 TestLoadTimingNotReusedWithPac(load_timing_info,
10703 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1110704}
[email protected]631f1322010-04-30 17:59:1110705
[email protected]23e482282013-06-14 16:08:0210706TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:5410707 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
bnc55ff9da2015-08-19 18:42:3510708 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310709 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:5410710
10711 HttpRequestInfo request;
10712 request.method = "GET";
bncce36dca22015-04-21 22:11:2310713 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410714 request.load_flags = 0;
10715
[email protected]8a0fc822013-06-27 20:52:4310716 std::string alternate_protocol_http_header =
10717 GetAlternateProtocolHttpHeader();
10718
[email protected]2ff8b312010-04-26 22:20:5410719 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210720 MockRead("HTTP/1.1 200 OK\r\n"),
10721 MockRead(alternate_protocol_http_header.c_str()),
10722 MockRead("\r\n"),
10723 MockRead("hello world"),
10724 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5410725 };
10726
10727 StaticSocketDataProvider first_transaction(
10728 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710729 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410730
[email protected]8ddf8322012-02-23 18:08:0610731 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210732 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310733 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10734 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710735 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410736
[email protected]cdf8f7e72013-05-23 10:56:4610737 scoped_ptr<SpdyFrame> req(
10738 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310739 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410740
[email protected]23e482282013-06-14 16:08:0210741 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10742 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410743 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310744 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410745 };
10746
rch8e6c6c42015-05-01 14:05:1310747 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10748 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710749 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410750
[email protected]83039bb2011-12-09 18:43:5510751 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410752
mmenkee65e7af2015-10-13 17:16:4210753 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5410754
[email protected]262eec82013-03-19 21:01:3610755 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010756 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410757
[email protected]49639fa2011-12-20 23:22:4110758 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410759 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110760 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410761
10762 const HttpResponseInfo* response = trans->GetResponseInfo();
10763 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010764 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410765 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10766
10767 std::string response_data;
10768 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10769 EXPECT_EQ("hello world", response_data);
10770
10771 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310772 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010773 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310774 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710775 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4210776 CreateSecureSpdySession(session.get(), key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3810777
[email protected]90499482013-06-01 00:39:5010778 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410779
[email protected]49639fa2011-12-20 23:22:4110780 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410781 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110782 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410783
10784 response = trans->GetResponseInfo();
10785 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010786 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410787 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310788 EXPECT_TRUE(response->was_fetched_via_spdy);
10789 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410790
10791 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10792 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4210793}
10794
[email protected]044de0642010-06-17 10:42:1510795// GenerateAuthToken is a mighty big test.
10796// It tests all permutation of GenerateAuthToken behavior:
10797// - Synchronous and Asynchronous completion.
10798// - OK or error on completion.
10799// - Direct connection, non-authenticating proxy, and authenticating proxy.
10800// - HTTP or HTTPS backend (to include proxy tunneling).
10801// - Non-authenticating and authenticating backend.
10802//
[email protected]fe3b7dc2012-02-03 19:52:0910803// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1510804// problems generating an auth token for an authenticating proxy, we don't
10805// need to test all permutations of the backend server).
10806//
10807// The test proceeds by going over each of the configuration cases, and
10808// potentially running up to three rounds in each of the tests. The TestConfig
10809// specifies both the configuration for the test as well as the expectations
10810// for the results.
[email protected]23e482282013-06-14 16:08:0210811TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5010812 static const char kServer[] = "http://www.example.com";
10813 static const char kSecureServer[] = "https://www.example.com";
10814 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1510815 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
10816
10817 enum AuthTiming {
10818 AUTH_NONE,
10819 AUTH_SYNC,
10820 AUTH_ASYNC,
10821 };
10822
10823 const MockWrite kGet(
10824 "GET / HTTP/1.1\r\n"
10825 "Host: www.example.com\r\n"
10826 "Connection: keep-alive\r\n\r\n");
10827 const MockWrite kGetProxy(
10828 "GET http://www.example.com/ HTTP/1.1\r\n"
10829 "Host: www.example.com\r\n"
10830 "Proxy-Connection: keep-alive\r\n\r\n");
10831 const MockWrite kGetAuth(
10832 "GET / HTTP/1.1\r\n"
10833 "Host: www.example.com\r\n"
10834 "Connection: keep-alive\r\n"
10835 "Authorization: auth_token\r\n\r\n");
10836 const MockWrite kGetProxyAuth(
10837 "GET http://www.example.com/ HTTP/1.1\r\n"
10838 "Host: www.example.com\r\n"
10839 "Proxy-Connection: keep-alive\r\n"
10840 "Proxy-Authorization: auth_token\r\n\r\n");
10841 const MockWrite kGetAuthThroughProxy(
10842 "GET http://www.example.com/ HTTP/1.1\r\n"
10843 "Host: www.example.com\r\n"
10844 "Proxy-Connection: keep-alive\r\n"
10845 "Authorization: auth_token\r\n\r\n");
10846 const MockWrite kGetAuthWithProxyAuth(
10847 "GET http://www.example.com/ HTTP/1.1\r\n"
10848 "Host: www.example.com\r\n"
10849 "Proxy-Connection: keep-alive\r\n"
10850 "Proxy-Authorization: auth_token\r\n"
10851 "Authorization: auth_token\r\n\r\n");
10852 const MockWrite kConnect(
10853 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10854 "Host: www.example.com\r\n"
10855 "Proxy-Connection: keep-alive\r\n\r\n");
10856 const MockWrite kConnectProxyAuth(
10857 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10858 "Host: www.example.com\r\n"
10859 "Proxy-Connection: keep-alive\r\n"
10860 "Proxy-Authorization: auth_token\r\n\r\n");
10861
10862 const MockRead kSuccess(
10863 "HTTP/1.1 200 OK\r\n"
10864 "Content-Type: text/html; charset=iso-8859-1\r\n"
10865 "Content-Length: 3\r\n\r\n"
10866 "Yes");
10867 const MockRead kFailure(
10868 "Should not be called.");
10869 const MockRead kServerChallenge(
10870 "HTTP/1.1 401 Unauthorized\r\n"
10871 "WWW-Authenticate: Mock realm=server\r\n"
10872 "Content-Type: text/html; charset=iso-8859-1\r\n"
10873 "Content-Length: 14\r\n\r\n"
10874 "Unauthorized\r\n");
10875 const MockRead kProxyChallenge(
10876 "HTTP/1.1 407 Unauthorized\r\n"
10877 "Proxy-Authenticate: Mock realm=proxy\r\n"
10878 "Proxy-Connection: close\r\n"
10879 "Content-Type: text/html; charset=iso-8859-1\r\n"
10880 "Content-Length: 14\r\n\r\n"
10881 "Unauthorized\r\n");
10882 const MockRead kProxyConnected(
10883 "HTTP/1.1 200 Connection Established\r\n\r\n");
10884
10885 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
10886 // no constructors, but the C++ compiler on Windows warns about
10887 // unspecified data in compound literals. So, moved to using constructors,
10888 // and TestRound's created with the default constructor should not be used.
10889 struct TestRound {
10890 TestRound()
10891 : expected_rv(ERR_UNEXPECTED),
10892 extra_write(NULL),
10893 extra_read(NULL) {
10894 }
10895 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10896 int expected_rv_arg)
10897 : write(write_arg),
10898 read(read_arg),
10899 expected_rv(expected_rv_arg),
10900 extra_write(NULL),
10901 extra_read(NULL) {
10902 }
10903 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10904 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0110905 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1510906 : write(write_arg),
10907 read(read_arg),
10908 expected_rv(expected_rv_arg),
10909 extra_write(extra_write_arg),
10910 extra_read(extra_read_arg) {
10911 }
10912 MockWrite write;
10913 MockRead read;
10914 int expected_rv;
10915 const MockWrite* extra_write;
10916 const MockRead* extra_read;
10917 };
10918
10919 static const int kNoSSL = 500;
10920
10921 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5110922 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1510923 AuthTiming proxy_auth_timing;
10924 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5110925 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1510926 AuthTiming server_auth_timing;
10927 int server_auth_rv;
10928 int num_auth_rounds;
10929 int first_ssl_round;
10930 TestRound rounds[3];
10931 } test_configs[] = {
10932 // Non-authenticating HTTP server with a direct connection.
10933 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10934 { TestRound(kGet, kSuccess, OK)}},
10935 // Authenticating HTTP server with a direct connection.
10936 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10937 { TestRound(kGet, kServerChallenge, OK),
10938 TestRound(kGetAuth, kSuccess, OK)}},
10939 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10940 { TestRound(kGet, kServerChallenge, OK),
10941 TestRound(kGetAuth, kFailure, kAuthErr)}},
10942 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10943 { TestRound(kGet, kServerChallenge, OK),
10944 TestRound(kGetAuth, kSuccess, OK)}},
10945 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10946 { TestRound(kGet, kServerChallenge, OK),
10947 TestRound(kGetAuth, kFailure, kAuthErr)}},
10948 // Non-authenticating HTTP server through a non-authenticating proxy.
10949 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10950 { TestRound(kGetProxy, kSuccess, OK)}},
10951 // Authenticating HTTP server through a non-authenticating proxy.
10952 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10953 { TestRound(kGetProxy, kServerChallenge, OK),
10954 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10955 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10956 { TestRound(kGetProxy, kServerChallenge, OK),
10957 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10958 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10959 { TestRound(kGetProxy, kServerChallenge, OK),
10960 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10961 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10962 { TestRound(kGetProxy, kServerChallenge, OK),
10963 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10964 // Non-authenticating HTTP server through an authenticating proxy.
10965 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10966 { TestRound(kGetProxy, kProxyChallenge, OK),
10967 TestRound(kGetProxyAuth, kSuccess, OK)}},
10968 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10969 { TestRound(kGetProxy, kProxyChallenge, OK),
10970 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10971 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10972 { TestRound(kGetProxy, kProxyChallenge, OK),
10973 TestRound(kGetProxyAuth, kSuccess, OK)}},
10974 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10975 { TestRound(kGetProxy, kProxyChallenge, OK),
10976 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10977 // Authenticating HTTP server through an authenticating proxy.
10978 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10979 { TestRound(kGetProxy, kProxyChallenge, OK),
10980 TestRound(kGetProxyAuth, kServerChallenge, OK),
10981 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10982 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10983 { TestRound(kGetProxy, kProxyChallenge, OK),
10984 TestRound(kGetProxyAuth, kServerChallenge, OK),
10985 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10986 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10987 { TestRound(kGetProxy, kProxyChallenge, OK),
10988 TestRound(kGetProxyAuth, kServerChallenge, OK),
10989 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10990 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10991 { TestRound(kGetProxy, kProxyChallenge, OK),
10992 TestRound(kGetProxyAuth, kServerChallenge, OK),
10993 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10994 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10995 { TestRound(kGetProxy, kProxyChallenge, OK),
10996 TestRound(kGetProxyAuth, kServerChallenge, OK),
10997 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10998 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10999 { TestRound(kGetProxy, kProxyChallenge, OK),
11000 TestRound(kGetProxyAuth, kServerChallenge, OK),
11001 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11002 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11003 { TestRound(kGetProxy, kProxyChallenge, OK),
11004 TestRound(kGetProxyAuth, kServerChallenge, OK),
11005 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11006 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11007 { TestRound(kGetProxy, kProxyChallenge, OK),
11008 TestRound(kGetProxyAuth, kServerChallenge, OK),
11009 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11010 // Non-authenticating HTTPS server with a direct connection.
11011 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11012 { TestRound(kGet, kSuccess, OK)}},
11013 // Authenticating HTTPS server with a direct connection.
11014 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11015 { TestRound(kGet, kServerChallenge, OK),
11016 TestRound(kGetAuth, kSuccess, OK)}},
11017 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11018 { TestRound(kGet, kServerChallenge, OK),
11019 TestRound(kGetAuth, kFailure, kAuthErr)}},
11020 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11021 { TestRound(kGet, kServerChallenge, OK),
11022 TestRound(kGetAuth, kSuccess, OK)}},
11023 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11024 { TestRound(kGet, kServerChallenge, OK),
11025 TestRound(kGetAuth, kFailure, kAuthErr)}},
11026 // Non-authenticating HTTPS server with a non-authenticating proxy.
11027 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11028 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11029 // Authenticating HTTPS server through a non-authenticating proxy.
11030 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11031 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11032 TestRound(kGetAuth, kSuccess, OK)}},
11033 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11034 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11035 TestRound(kGetAuth, kFailure, kAuthErr)}},
11036 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11037 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11038 TestRound(kGetAuth, kSuccess, OK)}},
11039 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11040 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11041 TestRound(kGetAuth, kFailure, kAuthErr)}},
11042 // Non-Authenticating HTTPS server through an authenticating proxy.
11043 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11044 { TestRound(kConnect, kProxyChallenge, OK),
11045 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11046 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11047 { TestRound(kConnect, kProxyChallenge, OK),
11048 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11049 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11050 { TestRound(kConnect, kProxyChallenge, OK),
11051 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11052 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11053 { TestRound(kConnect, kProxyChallenge, OK),
11054 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11055 // Authenticating HTTPS server through an authenticating proxy.
11056 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11057 { TestRound(kConnect, kProxyChallenge, OK),
11058 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11059 &kGet, &kServerChallenge),
11060 TestRound(kGetAuth, kSuccess, OK)}},
11061 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11062 { TestRound(kConnect, kProxyChallenge, OK),
11063 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11064 &kGet, &kServerChallenge),
11065 TestRound(kGetAuth, kFailure, kAuthErr)}},
11066 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11067 { TestRound(kConnect, kProxyChallenge, OK),
11068 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11069 &kGet, &kServerChallenge),
11070 TestRound(kGetAuth, kSuccess, OK)}},
11071 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11072 { TestRound(kConnect, kProxyChallenge, OK),
11073 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11074 &kGet, &kServerChallenge),
11075 TestRound(kGetAuth, kFailure, kAuthErr)}},
11076 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11077 { TestRound(kConnect, kProxyChallenge, OK),
11078 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11079 &kGet, &kServerChallenge),
11080 TestRound(kGetAuth, kSuccess, OK)}},
11081 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11082 { TestRound(kConnect, kProxyChallenge, OK),
11083 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11084 &kGet, &kServerChallenge),
11085 TestRound(kGetAuth, kFailure, kAuthErr)}},
11086 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11087 { TestRound(kConnect, kProxyChallenge, OK),
11088 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11089 &kGet, &kServerChallenge),
11090 TestRound(kGetAuth, kSuccess, OK)}},
11091 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11092 { TestRound(kConnect, kProxyChallenge, OK),
11093 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11094 &kGet, &kServerChallenge),
11095 TestRound(kGetAuth, kFailure, kAuthErr)}},
11096 };
11097
viettrungluue4a8b882014-10-16 06:17:3811098 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0811099 HttpAuthHandlerMock::Factory* auth_factory(
11100 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711101 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1511102 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2611103
11104 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1511105 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0811106 for (int n = 0; n < 2; n++) {
11107 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11108 std::string auth_challenge = "Mock realm=proxy";
11109 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2411110 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11111 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0811112 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
11113 origin, BoundNetLog());
11114 auth_handler->SetGenerateExpectation(
11115 test_config.proxy_auth_timing == AUTH_ASYNC,
11116 test_config.proxy_auth_rv);
11117 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11118 }
[email protected]044de0642010-06-17 10:42:1511119 }
11120 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0011121 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1511122 std::string auth_challenge = "Mock realm=server";
11123 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2411124 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11125 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1511126 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
11127 origin, BoundNetLog());
11128 auth_handler->SetGenerateExpectation(
11129 test_config.server_auth_timing == AUTH_ASYNC,
11130 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0811131 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1511132 }
11133 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0311134 session_deps_.proxy_service =
11135 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1511136 } else {
rdsmith82957ad2015-09-16 19:42:0311137 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1511138 }
11139
11140 HttpRequestInfo request;
11141 request.method = "GET";
11142 request.url = GURL(test_config.server_url);
11143 request.load_flags = 0;
11144
mmenkee65e7af2015-10-13 17:16:4211145 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4111146 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1511147
rchcb68dc62015-05-21 04:45:3611148 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
11149
11150 std::vector<std::vector<MockRead>> mock_reads(1);
11151 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1511152 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11153 const TestRound& read_write_round = test_config.rounds[round];
11154
11155 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3611156 mock_reads.back().push_back(read_write_round.read);
11157 mock_writes.back().push_back(read_write_round.write);
11158
11159 // kProxyChallenge uses Proxy-Connection: close which means that the
11160 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5411161 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3611162 mock_reads.push_back(std::vector<MockRead>());
11163 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1511164 }
11165
rchcb68dc62015-05-21 04:45:3611166 if (read_write_round.extra_read) {
11167 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1511168 }
rchcb68dc62015-05-21 04:45:3611169 if (read_write_round.extra_write) {
11170 mock_writes.back().push_back(*read_write_round.extra_write);
11171 }
[email protected]044de0642010-06-17 10:42:1511172
11173 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1511174 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0711175 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1511176 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3611177 }
[email protected]044de0642010-06-17 10:42:1511178
rchcb68dc62015-05-21 04:45:3611179 ScopedVector<StaticSocketDataProvider> data_providers;
11180 for (size_t i = 0; i < mock_reads.size(); ++i) {
11181 data_providers.push_back(new StaticSocketDataProvider(
11182 vector_as_array(&mock_reads[i]), mock_reads[i].size(),
11183 vector_as_array(&mock_writes[i]), mock_writes[i].size()));
11184 session_deps_.socket_factory->AddSocketDataProvider(
11185 data_providers.back());
11186 }
11187
11188 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11189 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1511190 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4111191 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1511192 int rv;
11193 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4111194 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511195 } else {
[email protected]49639fa2011-12-20 23:22:4111196 rv = trans.RestartWithAuth(
11197 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1511198 }
11199 if (rv == ERR_IO_PENDING)
11200 rv = callback.WaitForResult();
11201
11202 // Compare results with expected data.
11203 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5011204 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5511205 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1511206 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
11207 continue;
11208 }
11209 if (round + 1 < test_config.num_auth_rounds) {
11210 EXPECT_FALSE(response->auth_challenge.get() == NULL);
11211 } else {
11212 EXPECT_TRUE(response->auth_challenge.get() == NULL);
11213 }
11214 }
[email protected]e5ae96a2010-04-14 20:12:4511215 }
11216}
11217
[email protected]23e482282013-06-14 16:08:0211218TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1411219 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1411220 HttpAuthHandlerMock::Factory* auth_factory(
11221 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711222 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0311223 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0711224 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
11225 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1411226
11227 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11228 auth_handler->set_connection_based(true);
11229 std::string auth_challenge = "Mock realm=server";
11230 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2411231 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11232 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1411233 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
11234 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811235 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1411236
[email protected]c871bce92010-07-15 21:51:1411237 int rv = OK;
11238 const HttpResponseInfo* response = NULL;
11239 HttpRequestInfo request;
11240 request.method = "GET";
11241 request.url = origin;
11242 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2711243
mmenkee65e7af2015-10-13 17:16:4211244 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1011245
11246 // Use a TCP Socket Pool with only one connection per group. This is used
11247 // to validate that the TCP socket is not released to the pool between
11248 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4211249 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2811250 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1011251 50, // Max sockets for pool
11252 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0711253 session_deps_.host_resolver.get(),
11254 session_deps_.socket_factory.get(),
11255 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4411256 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
11257 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0211258 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5111259 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1011260
[email protected]262eec82013-03-19 21:01:3611261 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011262 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111263 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1411264
11265 const MockWrite kGet(
11266 "GET / HTTP/1.1\r\n"
11267 "Host: www.example.com\r\n"
11268 "Connection: keep-alive\r\n\r\n");
11269 const MockWrite kGetAuth(
11270 "GET / HTTP/1.1\r\n"
11271 "Host: www.example.com\r\n"
11272 "Connection: keep-alive\r\n"
11273 "Authorization: auth_token\r\n\r\n");
11274
11275 const MockRead kServerChallenge(
11276 "HTTP/1.1 401 Unauthorized\r\n"
11277 "WWW-Authenticate: Mock realm=server\r\n"
11278 "Content-Type: text/html; charset=iso-8859-1\r\n"
11279 "Content-Length: 14\r\n\r\n"
11280 "Unauthorized\r\n");
11281 const MockRead kSuccess(
11282 "HTTP/1.1 200 OK\r\n"
11283 "Content-Type: text/html; charset=iso-8859-1\r\n"
11284 "Content-Length: 3\r\n\r\n"
11285 "Yes");
11286
11287 MockWrite writes[] = {
11288 // First round
11289 kGet,
11290 // Second round
11291 kGetAuth,
11292 // Third round
11293 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3011294 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1011295 kGetAuth,
11296 // Competing request
11297 kGet,
[email protected]c871bce92010-07-15 21:51:1411298 };
11299 MockRead reads[] = {
11300 // First round
11301 kServerChallenge,
11302 // Second round
11303 kServerChallenge,
11304 // Third round
[email protected]eca50e122010-09-11 14:03:3011305 kServerChallenge,
11306 // Fourth round
[email protected]c871bce92010-07-15 21:51:1411307 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1011308 // Competing response
11309 kSuccess,
[email protected]c871bce92010-07-15 21:51:1411310 };
11311 StaticSocketDataProvider data_provider(reads, arraysize(reads),
11312 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0711313 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1411314
thestig9d3bb0c2015-01-24 00:49:5111315 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1011316
11317 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1411318 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111319 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1411320 if (rv == ERR_IO_PENDING)
11321 rv = callback.WaitForResult();
11322 EXPECT_EQ(OK, rv);
11323 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011324 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1411325 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811326 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411327
[email protected]7ef4cbbb2011-02-06 11:19:1011328 // In between rounds, another request comes in for the same domain.
11329 // It should not be able to grab the TCP socket that trans has already
11330 // claimed.
11331 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5011332 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111333 TestCompletionCallback callback_compete;
11334 rv = trans_compete->Start(
11335 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1011336 EXPECT_EQ(ERR_IO_PENDING, rv);
11337 // callback_compete.WaitForResult at this point would stall forever,
11338 // since the HttpNetworkTransaction does not release the request back to
11339 // the pool until after authentication completes.
11340
11341 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1411342 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111343 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411344 if (rv == ERR_IO_PENDING)
11345 rv = callback.WaitForResult();
11346 EXPECT_EQ(OK, rv);
11347 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011348 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1411349 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811350 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411351
[email protected]7ef4cbbb2011-02-06 11:19:1011352 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1411353 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111354 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411355 if (rv == ERR_IO_PENDING)
11356 rv = callback.WaitForResult();
11357 EXPECT_EQ(OK, rv);
11358 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011359 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1411360 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811361 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3011362
[email protected]7ef4cbbb2011-02-06 11:19:1011363 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3011364 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111365 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3011366 if (rv == ERR_IO_PENDING)
11367 rv = callback.WaitForResult();
11368 EXPECT_EQ(OK, rv);
11369 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011370 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3011371 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811372 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011373
11374 // Read the body since the fourth round was successful. This will also
11375 // release the socket back to the pool.
11376 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5011377 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011378 if (rv == ERR_IO_PENDING)
11379 rv = callback.WaitForResult();
11380 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011381 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011382 EXPECT_EQ(0, rv);
11383 // There are still 0 idle sockets, since the trans_compete transaction
11384 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2811385 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011386
11387 // The competing request can now finish. Wait for the headers and then
11388 // read the body.
11389 rv = callback_compete.WaitForResult();
11390 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5011391 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011392 if (rv == ERR_IO_PENDING)
11393 rv = callback.WaitForResult();
11394 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011395 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011396 EXPECT_EQ(0, rv);
11397
11398 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2811399 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411400}
11401
[email protected]65041fa2010-05-21 06:56:5311402// This tests the case that a request is issued via http instead of spdy after
11403// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0211404TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bnc55ff9da2015-08-19 18:42:3511405 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311406 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1611407 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2311408 session_deps_.next_protos = next_protos;
11409
[email protected]65041fa2010-05-21 06:56:5311410 HttpRequestInfo request;
11411 request.method = "GET";
bncce36dca22015-04-21 22:11:2311412 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5311413 request.load_flags = 0;
11414
11415 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2311416 MockWrite(
11417 "GET / HTTP/1.1\r\n"
11418 "Host: www.example.org\r\n"
11419 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5311420 };
11421
[email protected]8a0fc822013-06-27 20:52:4311422 std::string alternate_protocol_http_header =
11423 GetAlternateProtocolHttpHeader();
11424
[email protected]65041fa2010-05-21 06:56:5311425 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211426 MockRead("HTTP/1.1 200 OK\r\n"),
11427 MockRead(alternate_protocol_http_header.c_str()),
11428 MockRead("\r\n"),
11429 MockRead("hello world"),
11430 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5311431 };
11432
[email protected]8ddf8322012-02-23 18:08:0611433 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4811434 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5311435
[email protected]bb88e1d32013-05-03 23:11:0711436 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5311437
11438 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11439 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711440 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5311441
[email protected]49639fa2011-12-20 23:22:4111442 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5311443
mmenkee65e7af2015-10-13 17:16:4211444 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611445 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011446 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5311447
[email protected]49639fa2011-12-20 23:22:4111448 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5311449
11450 EXPECT_EQ(ERR_IO_PENDING, rv);
11451 EXPECT_EQ(OK, callback.WaitForResult());
11452
11453 const HttpResponseInfo* response = trans->GetResponseInfo();
11454 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011455 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5311456 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11457
11458 std::string response_data;
11459 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11460 EXPECT_EQ("hello world", response_data);
11461
11462 EXPECT_FALSE(response->was_fetched_via_spdy);
11463 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5311464}
[email protected]26ef6582010-06-24 02:30:4711465
bnc55ff9da2015-08-19 18:42:3511466// Simulate the SSL handshake completing with an NPN negotiation followed by an
11467// immediate server closing of the socket.
11468// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0211469TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bnc55ff9da2015-08-19 18:42:3511470 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311471 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4711472
11473 HttpRequestInfo request;
11474 request.method = "GET";
bncce36dca22015-04-21 22:11:2311475 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4711476 request.load_flags = 0;
11477
[email protected]8ddf8322012-02-23 18:08:0611478 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211479 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711480 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4711481
[email protected]cdf8f7e72013-05-23 10:56:4611482 scoped_ptr<SpdyFrame> req(
11483 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1311484 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4711485
11486 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611487 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4711488 };
11489
rch8e6c6c42015-05-01 14:05:1311490 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11491 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711492 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4711493
[email protected]49639fa2011-12-20 23:22:4111494 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4711495
mmenkee65e7af2015-10-13 17:16:4211496 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611497 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011498 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4711499
[email protected]49639fa2011-12-20 23:22:4111500 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4711501 EXPECT_EQ(ERR_IO_PENDING, rv);
11502 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4711503}
[email protected]65d34382010-07-01 18:12:2611504
[email protected]795cbf82013-07-22 09:37:2711505// A subclass of HttpAuthHandlerMock that records the request URL when
11506// it gets it. This is needed since the auth handler may get destroyed
11507// before we get a chance to query it.
11508class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
11509 public:
11510 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
11511
dchengb03027d2014-10-21 12:00:2011512 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2711513
11514 protected:
dchengb03027d2014-10-21 12:00:2011515 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
11516 const HttpRequestInfo* request,
11517 const CompletionCallback& callback,
11518 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2711519 *url_ = request->url;
11520 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
11521 credentials, request, callback, auth_token);
11522 }
11523
11524 private:
11525 GURL* url_;
11526};
11527
bnc55ff9da2015-08-19 18:42:3511528// This test ensures that the URL passed into the proxy is upgraded to https
11529// when doing an Alternate Protocol upgrade.
[email protected]23e482282013-06-14 16:08:0211530TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
bnc55ff9da2015-08-19 18:42:3511531 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311532 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3011533
rdsmith82957ad2015-09-16 19:42:0311534 session_deps_.proxy_service =
11535 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111536 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711537 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2711538 GURL request_url;
11539 {
11540 HttpAuthHandlerMock::Factory* auth_factory =
11541 new HttpAuthHandlerMock::Factory();
11542 UrlRecordingHttpAuthHandlerMock* auth_handler =
11543 new UrlRecordingHttpAuthHandlerMock(&request_url);
11544 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11545 auth_factory->set_do_init_from_challenge(true);
11546 session_deps_.http_auth_handler_factory.reset(auth_factory);
11547 }
[email protected]f45c1ee2010-08-03 00:54:3011548
11549 HttpRequestInfo request;
11550 request.method = "GET";
bncce36dca22015-04-21 22:11:2311551 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3011552 request.load_flags = 0;
11553
11554 // First round goes unauthenticated through the proxy.
11555 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2311556 MockWrite(
11557 "GET http://www.example.org/ HTTP/1.1\r\n"
11558 "Host: www.example.org\r\n"
11559 "Proxy-Connection: keep-alive\r\n"
11560 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011561 };
11562 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0611563 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3811564 MockRead("HTTP/1.1 200 OK\r\n"),
11565 MockRead("Alternate-Protocol: 443:"),
11566 MockRead(GetAlternateProtocolFromParam()),
11567 MockRead("\r\n"),
11568 MockRead("Proxy-Connection: close\r\n"),
11569 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011570 };
11571 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
11572 data_writes_1, arraysize(data_writes_1));
11573
bncce36dca22015-04-21 22:11:2311574 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3011575 // Alternate-Protocol announcement in the first round. It fails due
11576 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2311577 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5911578 // Proxy-Authorization headers. There is then a SPDY request round.
11579 //
[email protected]fe3b7dc2012-02-03 19:52:0911580 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
11581 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
11582 // does a Disconnect and Connect on the same socket, rather than trying
11583 // to obtain a new one.
11584 //
[email protected]394816e92010-08-03 07:38:5911585 // NOTE: Originally, the proxy response to the second CONNECT request
11586 // simply returned another 407 so the unit test could skip the SSL connection
11587 // establishment and SPDY framing issues. Alas, the
11588 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3011589 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5911590
[email protected]cdf8f7e72013-05-23 10:56:4611591 scoped_ptr<SpdyFrame> req(
11592 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0211593 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11594 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3011595
[email protected]394816e92010-08-03 07:38:5911596 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2311597 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311598 MockWrite(ASYNC, 0,
11599 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11600 "Host: www.example.org\r\n"
11601 "Proxy-Connection: keep-alive\r\n"
11602 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911603
bncce36dca22015-04-21 22:11:2311604 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311605 MockWrite(ASYNC, 2,
11606 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11607 "Host: www.example.org\r\n"
11608 "Proxy-Connection: keep-alive\r\n"
11609 "Proxy-Authorization: auth_token\r\n"
11610 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011611
bncce36dca22015-04-21 22:11:2311612 // SPDY request
rch8e6c6c42015-05-01 14:05:1311613 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3011614 };
[email protected]394816e92010-08-03 07:38:5911615 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1311616 // First connection attempt fails
mmenkee71e15332015-10-07 16:39:5411617 MockRead(ASYNC, 1,
11618 "HTTP/1.1 407 Unauthorized\r\n"
11619 "Proxy-Authenticate: Mock\r\n"
11620 "Content-Length: 0\r\n"
11621 "Proxy-Connection: keep-alive\r\n"
11622 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911623
rch8e6c6c42015-05-01 14:05:1311624 // Second connection attempt passes
mmenkee71e15332015-10-07 16:39:5411625 MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:5911626
rch8e6c6c42015-05-01 14:05:1311627 // SPDY response
mmenkee71e15332015-10-07 16:39:5411628 CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1311629 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5911630 };
rch8e6c6c42015-05-01 14:05:1311631 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
11632 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3011633
[email protected]8ddf8322012-02-23 18:08:0611634 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211635 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2311636 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
11637 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3011638
[email protected]d973e99a2012-02-17 21:02:3611639 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511640 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11641 NULL, 0, NULL, 0);
11642 hanging_non_alternate_protocol_socket.set_connect_data(
11643 never_finishing_connect);
11644
[email protected]bb88e1d32013-05-03 23:11:0711645 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
11646 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
11647 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11648 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511649 &hanging_non_alternate_protocol_socket);
mmenkee65e7af2015-10-13 17:16:4211650 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3011651
11652 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4111653 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3611654 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5011655 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111656 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011657 EXPECT_EQ(ERR_IO_PENDING, rv);
11658 EXPECT_EQ(OK, callback_1.WaitForResult());
11659
11660 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4111661 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3611662 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5011663 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111664 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011665 EXPECT_EQ(ERR_IO_PENDING, rv);
11666 EXPECT_EQ(OK, callback_2.WaitForResult());
11667 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011668 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3011669 ASSERT_FALSE(response->auth_challenge.get() == NULL);
11670
11671 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4111672 TestCompletionCallback callback_3;
11673 rv = trans_2->RestartWithAuth(
11674 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3011675 EXPECT_EQ(ERR_IO_PENDING, rv);
11676 EXPECT_EQ(OK, callback_3.WaitForResult());
11677
11678 // After all that work, these two lines (or actually, just the scheme) are
11679 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3011680 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2311681 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3011682
[email protected]029c83b62013-01-24 05:28:2011683 LoadTimingInfo load_timing_info;
11684 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
11685 TestLoadTimingNotReusedWithPac(load_timing_info,
11686 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3811687}
11688
11689// Test that if we cancel the transaction as the connection is completing, that
11690// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0211691TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3811692 // Setup everything about the connection to complete synchronously, so that
11693 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
11694 // for is the callback from the HttpStreamRequest.
11695 // Then cancel the transaction.
11696 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3611697 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3811698 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611699 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
11700 MockRead(SYNCHRONOUS, "hello world"),
11701 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3811702 };
11703
[email protected]8e6441ca2010-08-19 05:56:3811704 HttpRequestInfo request;
11705 request.method = "GET";
bncce36dca22015-04-21 22:11:2311706 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3811707 request.load_flags = 0;
11708
[email protected]bb88e1d32013-05-03 23:11:0711709 session_deps_.host_resolver->set_synchronous_mode(true);
mmenkee65e7af2015-10-13 17:16:4211710 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2711711 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111712 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2711713
[email protected]8e6441ca2010-08-19 05:56:3811714 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11715 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711716 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3811717
[email protected]49639fa2011-12-20 23:22:4111718 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3811719
vishal.b62985ca92015-04-17 08:45:5111720 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4111721 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3811722 EXPECT_EQ(ERR_IO_PENDING, rv);
11723 trans.reset(); // Cancel the transaction here.
11724
[email protected]2da659e2013-05-23 20:51:3411725 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3011726}
11727
[email protected]ecab6e052014-05-16 14:58:1211728// Test that if a transaction is cancelled after receiving the headers, the
11729// stream is drained properly and added back to the socket pool. The main
11730// purpose of this test is to make sure that an HttpStreamParser can be read
11731// from after the HttpNetworkTransaction and the objects it owns have been
11732// deleted.
11733// See http://crbug.com/368418
11734TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
11735 MockRead data_reads[] = {
11736 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
11737 MockRead(ASYNC, "Content-Length: 2\r\n"),
11738 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
11739 MockRead(ASYNC, "1"),
11740 // 2 async reads are necessary to trigger a ReadResponseBody call after the
11741 // HttpNetworkTransaction has been deleted.
11742 MockRead(ASYNC, "2"),
11743 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
11744 };
11745 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11746 session_deps_.socket_factory->AddSocketDataProvider(&data);
11747
mmenkee65e7af2015-10-13 17:16:4211748 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1211749
11750 {
11751 HttpRequestInfo request;
11752 request.method = "GET";
bncce36dca22015-04-21 22:11:2311753 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1211754 request.load_flags = 0;
11755
dcheng48459ac22014-08-26 00:46:4111756 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1211757 TestCompletionCallback callback;
11758
11759 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
11760 EXPECT_EQ(ERR_IO_PENDING, rv);
11761 callback.WaitForResult();
11762
11763 const HttpResponseInfo* response = trans.GetResponseInfo();
11764 ASSERT_TRUE(response != NULL);
11765 EXPECT_TRUE(response->headers.get() != NULL);
11766 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11767
11768 // The transaction and HttpRequestInfo are deleted.
11769 }
11770
11771 // Let the HttpResponseBodyDrainer drain the socket.
11772 base::MessageLoop::current()->RunUntilIdle();
11773
11774 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4111775 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1211776}
11777
[email protected]76a505b2010-08-25 06:23:0011778// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211779TEST_P(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0311780 session_deps_.proxy_service =
11781 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111782 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711783 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:4211784 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011785
[email protected]76a505b2010-08-25 06:23:0011786 HttpRequestInfo request;
11787 request.method = "GET";
bncce36dca22015-04-21 22:11:2311788 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011789
11790 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311791 MockWrite(
11792 "GET http://www.example.org/ HTTP/1.1\r\n"
11793 "Host: www.example.org\r\n"
11794 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011795 };
11796
11797 MockRead data_reads1[] = {
11798 MockRead("HTTP/1.1 200 OK\r\n"),
11799 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11800 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611801 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011802 };
11803
11804 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11805 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711806 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0011807
[email protected]49639fa2011-12-20 23:22:4111808 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011809
[email protected]262eec82013-03-19 21:01:3611810 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011811 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2711812 BeforeProxyHeadersSentHandler proxy_headers_handler;
11813 trans->SetBeforeProxyHeadersSentCallback(
11814 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
11815 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5011816
[email protected]49639fa2011-12-20 23:22:4111817 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011818 EXPECT_EQ(ERR_IO_PENDING, rv);
11819
11820 rv = callback1.WaitForResult();
11821 EXPECT_EQ(OK, rv);
11822
11823 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011824 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011825
11826 EXPECT_TRUE(response->headers->IsKeepAlive());
11827 EXPECT_EQ(200, response->headers->response_code());
11828 EXPECT_EQ(100, response->headers->GetContentLength());
11829 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511830 EXPECT_TRUE(
11831 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2711832 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
11833 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0011834 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2011835
11836 LoadTimingInfo load_timing_info;
11837 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11838 TestLoadTimingNotReusedWithPac(load_timing_info,
11839 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0011840}
11841
11842// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211843TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0311844 session_deps_.proxy_service =
11845 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111846 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711847 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:4211848 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011849
[email protected]76a505b2010-08-25 06:23:0011850 HttpRequestInfo request;
11851 request.method = "GET";
bncce36dca22015-04-21 22:11:2311852 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011853
11854 // Since we have proxy, should try to establish tunnel.
11855 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311856 MockWrite(
11857 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11858 "Host: www.example.org\r\n"
11859 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011860
bncce36dca22015-04-21 22:11:2311861 MockWrite(
11862 "GET / HTTP/1.1\r\n"
11863 "Host: www.example.org\r\n"
11864 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011865 };
11866
11867 MockRead data_reads1[] = {
11868 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
11869
11870 MockRead("HTTP/1.1 200 OK\r\n"),
11871 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11872 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611873 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011874 };
11875
11876 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11877 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711878 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611879 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711880 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011881
[email protected]49639fa2011-12-20 23:22:4111882 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011883
[email protected]262eec82013-03-19 21:01:3611884 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011885 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011886
[email protected]49639fa2011-12-20 23:22:4111887 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011888 EXPECT_EQ(ERR_IO_PENDING, rv);
11889
11890 rv = callback1.WaitForResult();
11891 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4611892 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011893 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011894 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011895 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011896 NetLog::PHASE_NONE);
11897 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011898 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011899 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11900 NetLog::PHASE_NONE);
11901
11902 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011903 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011904
11905 EXPECT_TRUE(response->headers->IsKeepAlive());
11906 EXPECT_EQ(200, response->headers->response_code());
11907 EXPECT_EQ(100, response->headers->GetContentLength());
11908 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
11909 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511910 EXPECT_TRUE(
11911 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2011912
11913 LoadTimingInfo load_timing_info;
11914 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11915 TestLoadTimingNotReusedWithPac(load_timing_info,
11916 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0011917}
11918
11919// Test a basic HTTPS GET request through a proxy, but the server hangs up
11920// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0211921TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0311922 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111923 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711924 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:4211925 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011926
[email protected]76a505b2010-08-25 06:23:0011927 HttpRequestInfo request;
11928 request.method = "GET";
bncce36dca22015-04-21 22:11:2311929 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011930
11931 // Since we have proxy, should try to establish tunnel.
11932 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311933 MockWrite(
11934 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11935 "Host: www.example.org\r\n"
11936 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011937
bncce36dca22015-04-21 22:11:2311938 MockWrite(
11939 "GET / HTTP/1.1\r\n"
11940 "Host: www.example.org\r\n"
11941 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011942 };
11943
11944 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0611945 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0011946 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611947 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0011948 };
11949
11950 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11951 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711952 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611953 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711954 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011955
[email protected]49639fa2011-12-20 23:22:4111956 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011957
[email protected]262eec82013-03-19 21:01:3611958 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011959 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011960
[email protected]49639fa2011-12-20 23:22:4111961 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011962 EXPECT_EQ(ERR_IO_PENDING, rv);
11963
11964 rv = callback1.WaitForResult();
11965 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4611966 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011967 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011968 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011969 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011970 NetLog::PHASE_NONE);
11971 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011972 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011973 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11974 NetLog::PHASE_NONE);
11975}
11976
[email protected]749eefa82010-09-13 22:14:0311977// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0211978TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4611979 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2311980 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1311981 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0311982
[email protected]23e482282013-06-14 16:08:0211983 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11984 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0311985 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311986 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0311987 };
11988
rch8e6c6c42015-05-01 14:05:1311989 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11990 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711991 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0311992
[email protected]8ddf8322012-02-23 18:08:0611993 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211994 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711995 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0311996
mmenkee65e7af2015-10-13 17:16:4211997 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0311998
11999 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2312000 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012001 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5312002 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2712003 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4212004 CreateInsecureSpdySession(session.get(), key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312005
12006 HttpRequestInfo request;
12007 request.method = "GET";
bncce36dca22015-04-21 22:11:2312008 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0312009 request.load_flags = 0;
12010
12011 // This is the important line that marks this as a preconnect.
12012 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
12013
[email protected]262eec82013-03-19 21:01:3612014 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012015 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0312016
[email protected]41d64e82013-07-03 22:44:2612017 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4112018 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312019 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112020 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0312021}
12022
[email protected]73b8dd222010-11-11 19:55:2412023// Given a net error, cause that error to be returned from the first Write()
12024// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0212025void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0712026 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2912027 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712028 request_info.url = GURL("https://www.example.com/");
12029 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912030 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712031
[email protected]8ddf8322012-02-23 18:08:0612032 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2912033 MockWrite data_writes[] = {
12034 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2412035 };
ttuttle859dc7a2015-04-23 19:42:2912036 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712037 session_deps_.socket_factory->AddSocketDataProvider(&data);
12038 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2412039
mmenkee65e7af2015-10-13 17:16:4212040 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3612041 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012042 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2412043
[email protected]49639fa2011-12-20 23:22:4112044 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912045 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12046 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2412047 rv = callback.WaitForResult();
12048 ASSERT_EQ(error, rv);
12049}
12050
[email protected]23e482282013-06-14 16:08:0212051TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2412052 // Just check a grab bag of cert errors.
12053 static const int kErrors[] = {
12054 ERR_CERT_COMMON_NAME_INVALID,
12055 ERR_CERT_AUTHORITY_INVALID,
12056 ERR_CERT_DATE_INVALID,
12057 };
12058 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0612059 CheckErrorIsPassedBack(kErrors[i], ASYNC);
12060 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2412061 }
12062}
12063
[email protected]bd0b6772011-01-11 19:59:3012064// Ensure that a client certificate is removed from the SSL client auth
12065// cache when:
12066// 1) No proxy is involved.
12067// 2) TLS False Start is disabled.
12068// 3) The initial TLS handshake requests a client certificate.
12069// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212070TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312071 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912072 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712073 request_info.url = GURL("https://www.example.com/");
12074 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912075 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712076
[email protected]bd0b6772011-01-11 19:59:3012077 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112078 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012079
12080 // [ssl_]data1 contains the data for the first SSL handshake. When a
12081 // CertificateRequest is received for the first time, the handshake will
12082 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2912083 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012084 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712085 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912086 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712087 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012088
12089 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
12090 // False Start is not being used, the result of the SSL handshake will be
12091 // returned as part of the SSLClientSocket::Connect() call. This test
12092 // matches the result of a server sending a handshake_failure alert,
12093 // rather than a Finished message, because it requires a client
12094 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2912095 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012096 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712097 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912098 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712099 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012100
12101 // [ssl_]data3 contains the data for the third SSL handshake. When a
12102 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212103 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
12104 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3012105 // of the HttpNetworkTransaction. Because this test failure is due to
12106 // requiring a client certificate, this fallback handshake should also
12107 // fail.
ttuttle859dc7a2015-04-23 19:42:2912108 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012109 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712110 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912111 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712112 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012113
[email protected]80c75f682012-05-26 16:22:1712114 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
12115 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212116 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
12117 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1712118 // of the HttpNetworkTransaction. Because this test failure is due to
12119 // requiring a client certificate, this fallback handshake should also
12120 // fail.
ttuttle859dc7a2015-04-23 19:42:2912121 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1712122 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712123 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912124 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712125 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712126
mmenkee65e7af2015-10-13 17:16:4212127 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3612128 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012129 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012130
[email protected]bd0b6772011-01-11 19:59:3012131 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4112132 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912133 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12134 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012135
12136 // Complete the SSL handshake, which should abort due to requiring a
12137 // client certificate.
12138 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912139 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012140
12141 // Indicate that no certificate should be supplied. From the perspective
12142 // of SSLClientCertCache, NULL is just as meaningful as a real
12143 // certificate, so this is the same as supply a
12144 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4112145 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912146 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012147
12148 // Ensure the certificate was added to the client auth cache before
12149 // allowing the connection to continue restarting.
12150 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4112151 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
12152 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3012153 ASSERT_EQ(NULL, client_cert.get());
12154
12155 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712156 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12157 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012158 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912159 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012160
12161 // Ensure that the client certificate is removed from the cache on a
12162 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112163 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
12164 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3012165}
12166
12167// Ensure that a client certificate is removed from the SSL client auth
12168// cache when:
12169// 1) No proxy is involved.
12170// 2) TLS False Start is enabled.
12171// 3) The initial TLS handshake requests a client certificate.
12172// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212173TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312174 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912175 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712176 request_info.url = GURL("https://www.example.com/");
12177 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912178 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712179
[email protected]bd0b6772011-01-11 19:59:3012180 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112181 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012182
12183 // When TLS False Start is used, SSLClientSocket::Connect() calls will
12184 // return successfully after reading up to the peer's Certificate message.
12185 // This is to allow the caller to call SSLClientSocket::Write(), which can
12186 // enqueue application data to be sent in the same packet as the
12187 // ChangeCipherSpec and Finished messages.
12188 // The actual handshake will be finished when SSLClientSocket::Read() is
12189 // called, which expects to process the peer's ChangeCipherSpec and
12190 // Finished messages. If there was an error negotiating with the peer,
12191 // such as due to the peer requiring a client certificate when none was
12192 // supplied, the alert sent by the peer won't be processed until Read() is
12193 // called.
12194
12195 // Like the non-False Start case, when a client certificate is requested by
12196 // the peer, the handshake is aborted during the Connect() call.
12197 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2912198 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012199 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712200 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912201 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712202 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012203
12204 // When a client certificate is supplied, Connect() will not be aborted
12205 // when the peer requests the certificate. Instead, the handshake will
12206 // artificially succeed, allowing the caller to write the HTTP request to
12207 // the socket. The handshake messages are not processed until Read() is
12208 // called, which then detects that the handshake was aborted, due to the
12209 // peer sending a handshake_failure because it requires a client
12210 // certificate.
ttuttle859dc7a2015-04-23 19:42:2912211 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012212 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712213 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912214 MockRead data2_reads[] = {
12215 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3012216 };
ttuttle859dc7a2015-04-23 19:42:2912217 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712218 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012219
12220 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1712221 // the data for the SSL handshake once the TLSv1.1 connection falls back to
12222 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912223 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012224 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712225 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912226 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712227 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012228
[email protected]80c75f682012-05-26 16:22:1712229 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
12230 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912231 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1712232 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712233 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912234 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712235 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712236
[email protected]7799de12013-05-30 05:52:5112237 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2912238 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5112239 ssl_data5.cert_request_info = cert_request.get();
12240 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2912241 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5112242 session_deps_.socket_factory->AddSocketDataProvider(&data5);
12243
mmenkee65e7af2015-10-13 17:16:4212244 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3612245 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012246 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012247
[email protected]bd0b6772011-01-11 19:59:3012248 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4112249 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912250 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12251 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012252
12253 // Complete the SSL handshake, which should abort due to requiring a
12254 // client certificate.
12255 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912256 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012257
12258 // Indicate that no certificate should be supplied. From the perspective
12259 // of SSLClientCertCache, NULL is just as meaningful as a real
12260 // certificate, so this is the same as supply a
12261 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4112262 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912263 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012264
12265 // Ensure the certificate was added to the client auth cache before
12266 // allowing the connection to continue restarting.
12267 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4112268 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
12269 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3012270 ASSERT_EQ(NULL, client_cert.get());
12271
[email protected]bd0b6772011-01-11 19:59:3012272 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712273 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12274 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012275 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912276 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012277
12278 // Ensure that the client certificate is removed from the cache on a
12279 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112280 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
12281 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3012282}
12283
[email protected]8c405132011-01-11 22:03:1812284// Ensure that a client certificate is removed from the SSL client auth
12285// cache when:
12286// 1) An HTTPS proxy is involved.
12287// 3) The HTTPS proxy requests a client certificate.
12288// 4) The client supplies an invalid/unacceptable certificate for the
12289// proxy.
12290// The test is repeated twice, first for connecting to an HTTPS endpoint,
12291// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0212292TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0312293 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5112294 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712295 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1812296
12297 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112298 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1812299
12300 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
12301 // [ssl_]data[1-3]. Rather than represending the endpoint
12302 // (www.example.com:443), they represent failures with the HTTPS proxy
12303 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2912304 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1812305 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712306 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912307 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712308 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1812309
ttuttle859dc7a2015-04-23 19:42:2912310 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812311 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712312 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912313 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712314 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1812315
[email protected]80c75f682012-05-26 16:22:1712316 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
12317#if 0
ttuttle859dc7a2015-04-23 19:42:2912318 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812319 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712320 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912321 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712322 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1712323#endif
[email protected]8c405132011-01-11 22:03:1812324
ttuttle859dc7a2015-04-23 19:42:2912325 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1812326 requests[0].url = GURL("https://www.example.com/");
12327 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912328 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812329
12330 requests[1].url = GURL("http://www.example.com/");
12331 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912332 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812333
12334 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0712335 session_deps_.socket_factory->ResetNextMockIndexes();
mmenkee65e7af2015-10-13 17:16:4212336 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1812337 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012338 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1812339
12340 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4112341 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912342 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
12343 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1812344
12345 // Complete the SSL handshake, which should abort due to requiring a
12346 // client certificate.
12347 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912348 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1812349
12350 // Indicate that no certificate should be supplied. From the perspective
12351 // of SSLClientCertCache, NULL is just as meaningful as a real
12352 // certificate, so this is the same as supply a
12353 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4112354 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912355 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1812356
12357 // Ensure the certificate was added to the client auth cache before
12358 // allowing the connection to continue restarting.
12359 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4112360 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
12361 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1812362 ASSERT_EQ(NULL, client_cert.get());
12363 // Ensure the certificate was NOT cached for the endpoint. This only
12364 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4112365 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
12366 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1812367
12368 // Restart the handshake. This will consume ssl_data2, which fails, and
12369 // then consume ssl_data3, which should also fail. The result code is
12370 // checked against what ssl_data3 should return.
12371 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912372 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1812373
12374 // Now that the new handshake has failed, ensure that the client
12375 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4112376 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
12377 HostPortPair("proxy", 70), &client_cert));
12378 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
12379 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1812380 }
12381}
12382
mmenke5c642132015-06-02 16:05:1312383TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bnc55ff9da2015-08-19 18:42:3512384 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2312385 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4612386
12387 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712388 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenkee65e7af2015-10-13 17:16:4212389 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612390 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12391 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612392
[email protected]8ddf8322012-02-23 18:08:0612393 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212394 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712395 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612396
[email protected]cdf8f7e72013-05-23 10:56:4612397 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2312398 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4612399 scoped_ptr<SpdyFrame> host2_req(
12400 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612401 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312402 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612403 };
[email protected]23e482282013-06-14 16:08:0212404 scoped_ptr<SpdyFrame> host1_resp(
12405 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12406 scoped_ptr<SpdyFrame> host1_resp_body(
12407 spdy_util_.ConstructSpdyBodyFrame(1, true));
12408 scoped_ptr<SpdyFrame> host2_resp(
12409 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12410 scoped_ptr<SpdyFrame> host2_resp_body(
12411 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612412 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312413 CreateMockRead(*host1_resp, 1),
12414 CreateMockRead(*host1_resp_body, 2),
12415 CreateMockRead(*host2_resp, 4),
12416 CreateMockRead(*host2_resp_body, 5),
12417 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612418 };
12419
[email protected]d2b5f092012-06-08 23:55:0212420 IPAddressNumber ip;
12421 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12422 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12423 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312424 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12425 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712426 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612427
[email protected]aa22b242011-11-16 18:58:2912428 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612429 HttpRequestInfo request1;
12430 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312431 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612432 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012433 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612434
[email protected]49639fa2011-12-20 23:22:4112435 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612436 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112437 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612438
12439 const HttpResponseInfo* response = trans1.GetResponseInfo();
12440 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012441 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612442 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12443
12444 std::string response_data;
12445 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12446 EXPECT_EQ("hello!", response_data);
12447
12448 // Preload www.gmail.com into HostCache.
12449 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1012450 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4612451 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012452 rv = session_deps_.host_resolver->Resolve(resolve_info,
12453 DEFAULT_PRIORITY,
12454 &ignored,
12455 callback.callback(),
12456 NULL,
12457 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712458 EXPECT_EQ(ERR_IO_PENDING, rv);
12459 rv = callback.WaitForResult();
12460 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612461
12462 HttpRequestInfo request2;
12463 request2.method = "GET";
12464 request2.url = GURL("https://www.gmail.com/");
12465 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012466 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612467
[email protected]49639fa2011-12-20 23:22:4112468 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612469 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112470 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612471
12472 response = trans2.GetResponseInfo();
12473 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012474 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612475 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12476 EXPECT_TRUE(response->was_fetched_via_spdy);
12477 EXPECT_TRUE(response->was_npn_negotiated);
12478 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12479 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612480}
12481
[email protected]23e482282013-06-14 16:08:0212482TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bnc55ff9da2015-08-19 18:42:3512483 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2312484 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0212485
12486 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712487 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenkee65e7af2015-10-13 17:16:4212488 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0212489 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12490 pool_peer.DisableDomainAuthenticationVerification();
12491
12492 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212493 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712494 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0212495
[email protected]cdf8f7e72013-05-23 10:56:4612496 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2312497 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4612498 scoped_ptr<SpdyFrame> host2_req(
12499 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0212500 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312501 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0212502 };
[email protected]23e482282013-06-14 16:08:0212503 scoped_ptr<SpdyFrame> host1_resp(
12504 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12505 scoped_ptr<SpdyFrame> host1_resp_body(
12506 spdy_util_.ConstructSpdyBodyFrame(1, true));
12507 scoped_ptr<SpdyFrame> host2_resp(
12508 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12509 scoped_ptr<SpdyFrame> host2_resp_body(
12510 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0212511 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312512 CreateMockRead(*host1_resp, 1),
12513 CreateMockRead(*host1_resp_body, 2),
12514 CreateMockRead(*host2_resp, 4),
12515 CreateMockRead(*host2_resp_body, 5),
12516 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0212517 };
12518
12519 IPAddressNumber ip;
12520 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12521 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12522 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312523 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12524 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712525 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0212526
12527 TestCompletionCallback callback;
12528 HttpRequestInfo request1;
12529 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312530 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0212531 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012532 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212533
12534 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
12535 EXPECT_EQ(ERR_IO_PENDING, rv);
12536 EXPECT_EQ(OK, callback.WaitForResult());
12537
12538 const HttpResponseInfo* response = trans1.GetResponseInfo();
12539 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012540 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0212541 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12542
12543 std::string response_data;
12544 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12545 EXPECT_EQ("hello!", response_data);
12546
12547 HttpRequestInfo request2;
12548 request2.method = "GET";
12549 request2.url = GURL("https://www.gmail.com/");
12550 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012551 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212552
12553 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
12554 EXPECT_EQ(ERR_IO_PENDING, rv);
12555 EXPECT_EQ(OK, callback.WaitForResult());
12556
12557 response = trans2.GetResponseInfo();
12558 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012559 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0212560 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12561 EXPECT_TRUE(response->was_fetched_via_spdy);
12562 EXPECT_TRUE(response->was_npn_negotiated);
12563 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12564 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0212565}
12566
ttuttle859dc7a2015-04-23 19:42:2912567class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4612568 public:
12569 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
12570 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2012571 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4612572
12573 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
12574
12575 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2012576 int Resolve(const RequestInfo& info,
12577 RequestPriority priority,
12578 AddressList* addresses,
12579 const CompletionCallback& callback,
12580 RequestHandle* out_req,
12581 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012582 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1012583 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4012584 }
12585
dchengb03027d2014-10-21 12:00:2012586 int ResolveFromCache(const RequestInfo& info,
12587 AddressList* addresses,
12588 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012589 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
12590 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0912591 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4612592 return rv;
12593 }
12594
dchengb03027d2014-10-21 12:00:2012595 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4612596 host_resolver_.CancelRequest(req);
12597 }
12598
[email protected]46da33be2011-07-19 21:58:0412599 MockCachingHostResolver* GetMockHostResolver() {
12600 return &host_resolver_;
12601 }
12602
[email protected]e3ceb682011-06-28 23:55:4612603 private:
12604 MockCachingHostResolver host_resolver_;
12605 const HostPortPair host_port_;
12606};
12607
mmenke5c642132015-06-02 16:05:1312608TEST_P(HttpNetworkTransactionTest,
12609 UseIPConnectionPoolingWithHostCacheExpiration) {
bnc55ff9da2015-08-19 18:42:3512610 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2312611 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4612612
12613 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4612614 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3412615 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0712616 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4612617 params.host_resolver = &host_resolver;
mmenkee65e7af2015-10-13 17:16:4212618 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612619 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12620 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612621
[email protected]8ddf8322012-02-23 18:08:0612622 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212623 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712624 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612625
[email protected]cdf8f7e72013-05-23 10:56:4612626 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2312627 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4612628 scoped_ptr<SpdyFrame> host2_req(
12629 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612630 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312631 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612632 };
[email protected]23e482282013-06-14 16:08:0212633 scoped_ptr<SpdyFrame> host1_resp(
12634 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12635 scoped_ptr<SpdyFrame> host1_resp_body(
12636 spdy_util_.ConstructSpdyBodyFrame(1, true));
12637 scoped_ptr<SpdyFrame> host2_resp(
12638 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12639 scoped_ptr<SpdyFrame> host2_resp_body(
12640 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612641 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312642 CreateMockRead(*host1_resp, 1),
12643 CreateMockRead(*host1_resp_body, 2),
12644 CreateMockRead(*host2_resp, 4),
12645 CreateMockRead(*host2_resp_body, 5),
12646 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612647 };
12648
[email protected]d2b5f092012-06-08 23:55:0212649 IPAddressNumber ip;
12650 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12651 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12652 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312653 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12654 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712655 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612656
[email protected]aa22b242011-11-16 18:58:2912657 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612658 HttpRequestInfo request1;
12659 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312660 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612661 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012662 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612663
[email protected]49639fa2011-12-20 23:22:4112664 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612665 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112666 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612667
12668 const HttpResponseInfo* response = trans1.GetResponseInfo();
12669 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012670 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612671 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12672
12673 std::string response_data;
12674 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12675 EXPECT_EQ("hello!", response_data);
12676
12677 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1012678 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4612679 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012680 rv = host_resolver.Resolve(resolve_info,
12681 DEFAULT_PRIORITY,
12682 &ignored,
12683 callback.callback(),
12684 NULL,
12685 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712686 EXPECT_EQ(ERR_IO_PENDING, rv);
12687 rv = callback.WaitForResult();
12688 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612689
12690 HttpRequestInfo request2;
12691 request2.method = "GET";
12692 request2.url = GURL("https://www.gmail.com/");
12693 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012694 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612695
[email protected]49639fa2011-12-20 23:22:4112696 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612697 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112698 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612699
12700 response = trans2.GetResponseInfo();
12701 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012702 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612703 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12704 EXPECT_TRUE(response->was_fetched_via_spdy);
12705 EXPECT_TRUE(response->was_npn_negotiated);
12706 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12707 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612708}
12709
[email protected]23e482282013-06-14 16:08:0212710TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2312711 const std::string https_url = "https://www.example.org:8080/";
12712 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412713
12714 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4612715 scoped_ptr<SpdyFrame> req1(
12716 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0412717
12718 MockWrite writes1[] = {
12719 CreateMockWrite(*req1, 0),
12720 };
12721
[email protected]23e482282013-06-14 16:08:0212722 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12723 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0412724 MockRead reads1[] = {
12725 CreateMockRead(*resp1, 1),
12726 CreateMockRead(*body1, 2),
12727 MockRead(ASYNC, ERR_IO_PENDING, 3)
12728 };
12729
rch8e6c6c42015-05-01 14:05:1312730 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
12731 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412732 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712733 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412734
12735 // HTTP GET for the HTTP URL
12736 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1312737 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3412738 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2312739 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3412740 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0412741 };
12742
12743 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1312744 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12745 MockRead(ASYNC, 2, "hello"),
12746 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0412747 };
12748
rch8e6c6c42015-05-01 14:05:1312749 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12750 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0412751
[email protected]8450d722012-07-02 19:14:0412752 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212753 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712754 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12755 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12756 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0412757
mmenkee65e7af2015-10-13 17:16:4212758 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412759
12760 // Start the first transaction to set up the SpdySession
12761 HttpRequestInfo request1;
12762 request1.method = "GET";
12763 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412764 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012765 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412766 TestCompletionCallback callback1;
12767 EXPECT_EQ(ERR_IO_PENDING,
12768 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412769 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412770
12771 EXPECT_EQ(OK, callback1.WaitForResult());
12772 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12773
12774 // Now, start the HTTP request
12775 HttpRequestInfo request2;
12776 request2.method = "GET";
12777 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412778 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012779 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412780 TestCompletionCallback callback2;
12781 EXPECT_EQ(ERR_IO_PENDING,
12782 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412783 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412784
12785 EXPECT_EQ(OK, callback2.WaitForResult());
12786 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12787}
12788
bnc1b0e36852015-04-28 15:32:5912789class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
12790 public:
12791 void Run(bool pooling, bool valid) {
12792 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
12793 443);
12794 HostPortPair alternative("www.example.org", 443);
12795
12796 base::FilePath certs_dir = GetTestCertsDirectory();
12797 scoped_refptr<X509Certificate> cert(
12798 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
12799 ASSERT_TRUE(cert.get());
12800 bool common_name_fallback_used;
12801 EXPECT_EQ(valid,
12802 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
12803 EXPECT_TRUE(
12804 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
12805 SSLSocketDataProvider ssl(ASYNC, OK);
12806 ssl.SetNextProto(GetParam());
12807 ssl.cert = cert;
12808 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12809
12810 // If pooling, then start a request to alternative first to create a
12811 // SpdySession.
12812 std::string url0 = "https://www.example.org:443";
12813 // Second request to origin, which has an alternative service, and could
12814 // open a connection to the alternative host or pool to the existing one.
12815 std::string url1("https://");
12816 url1.append(origin.host());
12817 url1.append(":443");
12818
12819 scoped_ptr<SpdyFrame> req0;
12820 scoped_ptr<SpdyFrame> req1;
12821 scoped_ptr<SpdyFrame> resp0;
12822 scoped_ptr<SpdyFrame> body0;
12823 scoped_ptr<SpdyFrame> resp1;
12824 scoped_ptr<SpdyFrame> body1;
12825 std::vector<MockWrite> writes;
12826 std::vector<MockRead> reads;
12827
12828 if (pooling) {
12829 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
12830 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
12831
12832 writes.push_back(CreateMockWrite(*req0, 0));
12833 writes.push_back(CreateMockWrite(*req1, 3));
12834
12835 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12836 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12837 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12838 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
12839
12840 reads.push_back(CreateMockRead(*resp0, 1));
12841 reads.push_back(CreateMockRead(*body0, 2));
12842 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
12843 reads.push_back(CreateMockRead(*resp1, 5));
12844 reads.push_back(CreateMockRead(*body1, 6));
12845 reads.push_back(MockRead(ASYNC, OK, 7));
12846 } else {
12847 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
12848
12849 writes.push_back(CreateMockWrite(*req1, 0));
12850
12851 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12852 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12853
12854 reads.push_back(CreateMockRead(*resp1, 1));
12855 reads.push_back(CreateMockRead(*body1, 2));
12856 reads.push_back(MockRead(ASYNC, OK, 3));
12857 }
12858
rch32320842015-05-16 15:57:0912859 SequencedSocketData data(vector_as_array(&reads), reads.size(),
12860 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5912861 session_deps_.socket_factory->AddSocketDataProvider(&data);
12862
12863 // Connection to the origin fails.
12864 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12865 StaticSocketDataProvider data_refused;
12866 data_refused.set_connect_data(mock_connect);
12867 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12868
bnc55ff9da2015-08-19 18:42:3512869 session_deps_.use_alternative_services = true;
mmenkee65e7af2015-10-13 17:16:4212870 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc1b0e36852015-04-28 15:32:5912871 base::WeakPtr<HttpServerProperties> http_server_properties =
12872 session->http_server_properties();
12873 AlternativeService alternative_service(
12874 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212875 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc1b0e36852015-04-28 15:32:5912876 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212877 1.0, expiration);
bnc1b0e36852015-04-28 15:32:5912878
12879 // First request to alternative.
12880 if (pooling) {
12881 scoped_ptr<HttpTransaction> trans0(
12882 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12883 HttpRequestInfo request0;
12884 request0.method = "GET";
12885 request0.url = GURL(url0);
12886 request0.load_flags = 0;
12887 TestCompletionCallback callback0;
12888
12889 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
12890 EXPECT_EQ(ERR_IO_PENDING, rv);
12891 rv = callback0.WaitForResult();
12892 EXPECT_EQ(OK, rv);
12893 }
12894
12895 // Second request to origin.
12896 scoped_ptr<HttpTransaction> trans1(
12897 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12898 HttpRequestInfo request1;
12899 request1.method = "GET";
12900 request1.url = GURL(url1);
12901 request1.load_flags = 0;
12902 TestCompletionCallback callback1;
12903
12904 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12905 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0912906 base::MessageLoop::current()->RunUntilIdle();
12907 if (data.IsReadPaused()) {
12908 data.CompleteRead();
12909 }
bnc1b0e36852015-04-28 15:32:5912910 rv = callback1.WaitForResult();
12911 if (valid) {
12912 EXPECT_EQ(OK, rv);
12913 } else {
12914 if (pooling) {
12915 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12916 } else {
12917 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
12918 }
12919 }
12920 }
12921};
12922
12923INSTANTIATE_TEST_CASE_P(NextProto,
12924 AltSvcCertificateVerificationTest,
12925 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:4312926 kProtoHTTP2));
bnc1b0e36852015-04-28 15:32:5912927
12928// The alternative service host must exhibit a certificate that is valid for the
12929// origin host. Test that this is enforced when pooling to an existing
12930// connection.
12931TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
12932 Run(true, true);
12933}
12934
12935TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
12936 Run(true, false);
12937}
12938
12939// The alternative service host must exhibit a certificate that is valid for the
12940// origin host. Test that this is enforced when opening a new connection.
12941TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
12942 Run(false, true);
12943}
12944
12945TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
12946 Run(false, false);
12947}
12948
bnc5452e2a2015-05-08 16:27:4212949// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
12950// with the alternative server. That connection should not be used.
12951TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
12952 HostPortPair origin("origin.example.org", 443);
12953 HostPortPair alternative("alternative.example.org", 443);
12954
12955 // Negotiate HTTP/1.1 with alternative.example.org.
12956 SSLSocketDataProvider ssl(ASYNC, OK);
12957 ssl.SetNextProto(kProtoHTTP11);
12958 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12959
12960 // No data should be read from the alternative, because HTTP/1.1 is
12961 // negotiated.
12962 StaticSocketDataProvider data;
12963 session_deps_.socket_factory->AddSocketDataProvider(&data);
12964
12965 // This test documents that an alternate Job should not be used if HTTP/1.1 is
12966 // negotiated. In order to test this, a failed connection to the origin is
12967 // mocked. This way the request relies on the alternate Job.
12968 StaticSocketDataProvider data_refused;
12969 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12970 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12971
12972 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512973 session_deps_.use_alternative_services = true;
mmenkee65e7af2015-10-13 17:16:4212974 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4212975 base::WeakPtr<HttpServerProperties> http_server_properties =
12976 session->http_server_properties();
12977 AlternativeService alternative_service(
12978 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212979 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212980 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212981 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212982
12983 scoped_ptr<HttpTransaction> trans(
12984 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12985 HttpRequestInfo request;
12986 request.method = "GET";
12987 request.url = GURL("https://origin.example.org:443");
12988 request.load_flags = 0;
12989 TestCompletionCallback callback;
12990
12991 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
12992 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
12993 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12994 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
12995}
12996
bnc40448a532015-05-11 19:13:1412997// A request to a server with an alternative service fires two Jobs: one to the
12998// origin, and an alternate one to the alternative server. If the former
12999// succeeds, the request should succeed, even if the latter fails because
13000// HTTP/1.1 is negotiated which is insufficient for alternative service.
13001TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
13002 HostPortPair origin("origin.example.org", 443);
13003 HostPortPair alternative("alternative.example.org", 443);
13004
13005 // Negotiate HTTP/1.1 with alternative.
13006 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
13007 alternative_ssl.SetNextProto(kProtoHTTP11);
13008 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13009
13010 // No data should be read from the alternative, because HTTP/1.1 is
13011 // negotiated.
13012 StaticSocketDataProvider data;
13013 session_deps_.socket_factory->AddSocketDataProvider(&data);
13014
13015 // Negotiate HTTP/1.1 with origin.
13016 SSLSocketDataProvider origin_ssl(ASYNC, OK);
13017 origin_ssl.SetNextProto(kProtoHTTP11);
13018 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13019
13020 MockWrite http_writes[] = {
13021 MockWrite(
13022 "GET / HTTP/1.1\r\n"
13023 "Host: origin.example.org\r\n"
13024 "Connection: keep-alive\r\n\r\n"),
13025 MockWrite(
13026 "GET /second HTTP/1.1\r\n"
13027 "Host: origin.example.org\r\n"
13028 "Connection: keep-alive\r\n\r\n"),
13029 };
13030
13031 MockRead http_reads[] = {
13032 MockRead("HTTP/1.1 200 OK\r\n"),
13033 MockRead("Content-Type: text/html\r\n"),
13034 MockRead("Content-Length: 6\r\n\r\n"),
13035 MockRead("foobar"),
13036 MockRead("HTTP/1.1 200 OK\r\n"),
13037 MockRead("Content-Type: text/html\r\n"),
13038 MockRead("Content-Length: 7\r\n\r\n"),
13039 MockRead("another"),
13040 };
13041 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13042 http_writes, arraysize(http_writes));
13043 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13044
13045 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3513046 session_deps_.use_alternative_services = true;
mmenkee65e7af2015-10-13 17:16:4213047 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc40448a532015-05-11 19:13:1413048 base::WeakPtr<HttpServerProperties> http_server_properties =
13049 session->http_server_properties();
13050 AlternativeService alternative_service(
13051 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213052 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc40448a532015-05-11 19:13:1413053 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1213054 1.0, expiration);
bnc40448a532015-05-11 19:13:1413055
13056 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13057 HttpRequestInfo request1;
13058 request1.method = "GET";
13059 request1.url = GURL("https://origin.example.org:443");
13060 request1.load_flags = 0;
13061 TestCompletionCallback callback1;
13062
13063 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
13064 rv = callback1.GetResult(rv);
13065 EXPECT_EQ(OK, rv);
13066
13067 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
13068 ASSERT_TRUE(response1 != nullptr);
13069 ASSERT_TRUE(response1->headers.get() != nullptr);
13070 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13071
13072 std::string response_data1;
13073 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
13074 EXPECT_EQ("foobar", response_data1);
13075
13076 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13077 // for alternative service.
13078 EXPECT_TRUE(
13079 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13080
13081 // Since |alternative_service| is broken, a second transaction to origin
13082 // should not start an alternate Job. It should pool to existing connection
13083 // to origin.
13084 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13085 HttpRequestInfo request2;
13086 request2.method = "GET";
13087 request2.url = GURL("https://origin.example.org:443/second");
13088 request2.load_flags = 0;
13089 TestCompletionCallback callback2;
13090
13091 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
13092 rv = callback2.GetResult(rv);
13093 EXPECT_EQ(OK, rv);
13094
13095 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
13096 ASSERT_TRUE(response2 != nullptr);
13097 ASSERT_TRUE(response2->headers.get() != nullptr);
13098 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13099
13100 std::string response_data2;
13101 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
13102 EXPECT_EQ("another", response_data2);
13103}
13104
bnc5452e2a2015-05-08 16:27:4213105// Alternative service requires HTTP/2 (or SPDY), but there is already a
13106// HTTP/1.1 socket open to the alternative server. That socket should not be
13107// used.
13108TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
13109 HostPortPair origin("origin.example.org", 443);
13110 HostPortPair alternative("alternative.example.org", 443);
13111 std::string origin_url = "https://origin.example.org:443";
13112 std::string alternative_url = "https://alternative.example.org:443";
13113
13114 // Negotiate HTTP/1.1 with alternative.example.org.
13115 SSLSocketDataProvider ssl(ASYNC, OK);
13116 ssl.SetNextProto(kProtoHTTP11);
13117 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13118
13119 // HTTP/1.1 data for |request1| and |request2|.
13120 MockWrite http_writes[] = {
13121 MockWrite(
13122 "GET / HTTP/1.1\r\n"
13123 "Host: alternative.example.org\r\n"
13124 "Connection: keep-alive\r\n\r\n"),
13125 MockWrite(
13126 "GET / HTTP/1.1\r\n"
13127 "Host: alternative.example.org\r\n"
13128 "Connection: keep-alive\r\n\r\n"),
13129 };
13130
13131 MockRead http_reads[] = {
13132 MockRead(
13133 "HTTP/1.1 200 OK\r\n"
13134 "Content-Type: text/html; charset=iso-8859-1\r\n"
13135 "Content-Length: 40\r\n\r\n"
13136 "first HTTP/1.1 response from alternative"),
13137 MockRead(
13138 "HTTP/1.1 200 OK\r\n"
13139 "Content-Type: text/html; charset=iso-8859-1\r\n"
13140 "Content-Length: 41\r\n\r\n"
13141 "second HTTP/1.1 response from alternative"),
13142 };
13143 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13144 http_writes, arraysize(http_writes));
13145 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13146
13147 // This test documents that an alternate Job should not pool to an already
13148 // existing HTTP/1.1 connection. In order to test this, a failed connection
13149 // to the origin is mocked. This way |request2| relies on the alternate Job.
13150 StaticSocketDataProvider data_refused;
13151 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13152 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13153
13154 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3513155 session_deps_.use_alternative_services = true;
mmenkee65e7af2015-10-13 17:16:4213156 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213157 base::WeakPtr<HttpServerProperties> http_server_properties =
13158 session->http_server_properties();
13159 AlternativeService alternative_service(
13160 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213161 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4213162 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1213163 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4213164
13165 // First transaction to alternative to open an HTTP/1.1 socket.
13166 scoped_ptr<HttpTransaction> trans1(
13167 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13168 HttpRequestInfo request1;
13169 request1.method = "GET";
13170 request1.url = GURL(alternative_url);
13171 request1.load_flags = 0;
13172 TestCompletionCallback callback1;
13173
13174 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13175 EXPECT_EQ(OK, callback1.GetResult(rv));
13176 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13177 ASSERT_TRUE(response1);
13178 ASSERT_TRUE(response1->headers.get());
13179 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13180 EXPECT_TRUE(response1->was_npn_negotiated);
13181 EXPECT_FALSE(response1->was_fetched_via_spdy);
13182 std::string response_data1;
13183 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
13184 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
13185
13186 // Request for origin.example.org, which has an alternative service. This
13187 // will start two Jobs: the alternative looks for connections to pool to,
13188 // finds one which is HTTP/1.1, and should ignore it, and should not try to
13189 // open other connections to alternative server. The Job to origin fails, so
13190 // this request fails.
13191 scoped_ptr<HttpTransaction> trans2(
13192 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13193 HttpRequestInfo request2;
13194 request2.method = "GET";
13195 request2.url = GURL(origin_url);
13196 request2.load_flags = 0;
13197 TestCompletionCallback callback2;
13198
13199 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
13200 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
13201
13202 // Another transaction to alternative. This is to test that the HTTP/1.1
13203 // socket is still open and in the pool.
13204 scoped_ptr<HttpTransaction> trans3(
13205 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13206 HttpRequestInfo request3;
13207 request3.method = "GET";
13208 request3.url = GURL(alternative_url);
13209 request3.load_flags = 0;
13210 TestCompletionCallback callback3;
13211
13212 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
13213 EXPECT_EQ(OK, callback3.GetResult(rv));
13214 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
13215 ASSERT_TRUE(response3);
13216 ASSERT_TRUE(response3->headers.get());
13217 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
13218 EXPECT_TRUE(response3->was_npn_negotiated);
13219 EXPECT_FALSE(response3->was_fetched_via_spdy);
13220 std::string response_data3;
13221 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
13222 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
13223}
13224
[email protected]23e482282013-06-14 16:08:0213225TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2313226 const std::string https_url = "https://www.example.org:8080/";
13227 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413228
13229 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2313230 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3413231 scoped_ptr<SpdyFrame> connect(
13232 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4613233 scoped_ptr<SpdyFrame> req1(
13234 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0213235 scoped_ptr<SpdyFrame> wrapped_req1(
13236 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3913237
13238 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2913239 SpdyHeaderBlock req2_block;
bnc7ecc1122015-09-28 13:22:4913240 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]745aa9c2014-06-27 02:21:2913241 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2313242 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2913243 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4913244 req2_block[spdy_util_.GetPathKey()] = "/";
[email protected]601e03f12014-04-06 16:26:3913245 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2913246 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0413247
13248 MockWrite writes1[] = {
13249 CreateMockWrite(*connect, 0),
13250 CreateMockWrite(*wrapped_req1, 2),
13251 CreateMockWrite(*req2, 5),
13252 };
13253
[email protected]23e482282013-06-14 16:08:0213254 scoped_ptr<SpdyFrame> conn_resp(
13255 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13256 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13257 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
13258 scoped_ptr<SpdyFrame> wrapped_resp1(
13259 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
13260 scoped_ptr<SpdyFrame> wrapped_body1(
13261 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
13262 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
13263 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0413264 MockRead reads1[] = {
13265 CreateMockRead(*conn_resp, 1),
13266 CreateMockRead(*wrapped_resp1, 3),
13267 CreateMockRead(*wrapped_body1, 4),
13268 CreateMockRead(*resp2, 6),
13269 CreateMockRead(*body2, 7),
13270 MockRead(ASYNC, ERR_IO_PENDING, 8)
13271 };
13272
[email protected]dd54bd82012-07-19 23:44:5713273 DeterministicSocketData data1(reads1, arraysize(reads1),
13274 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413275 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713276 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413277
rdsmith82957ad2015-09-16 19:42:0313278 session_deps_.proxy_service =
13279 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5113280 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713281 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0413282 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0213283 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0713284 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0413285 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0213286 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0713287 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
13288 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0413289
mmenkee65e7af2015-10-13 17:16:4213290 scoped_ptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0713291 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413292
13293 // Start the first transaction to set up the SpdySession
13294 HttpRequestInfo request1;
13295 request1.method = "GET";
13296 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413297 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013298 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413299 TestCompletionCallback callback1;
13300 EXPECT_EQ(ERR_IO_PENDING,
13301 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413302 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5713303 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0413304
13305 EXPECT_EQ(OK, callback1.WaitForResult());
13306 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13307
[email protected]f6c63db52013-02-02 00:35:2213308 LoadTimingInfo load_timing_info1;
13309 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
13310 TestLoadTimingNotReusedWithPac(load_timing_info1,
13311 CONNECT_TIMING_HAS_SSL_TIMES);
13312
[email protected]8450d722012-07-02 19:14:0413313 // Now, start the HTTP request
13314 HttpRequestInfo request2;
13315 request2.method = "GET";
13316 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413317 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013318 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413319 TestCompletionCallback callback2;
13320 EXPECT_EQ(ERR_IO_PENDING,
13321 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413322 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5713323 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0413324
13325 EXPECT_EQ(OK, callback2.WaitForResult());
13326 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2213327
13328 LoadTimingInfo load_timing_info2;
13329 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
13330 // The established SPDY sessions is considered reused by the HTTP request.
13331 TestLoadTimingReusedWithPac(load_timing_info2);
13332 // HTTP requests over a SPDY session should have a different connection
13333 // socket_log_id than requests over a tunnel.
13334 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0413335}
13336
[email protected]2d88e7d2012-07-19 17:55:1713337// Test that in the case where we have a SPDY session to a SPDY proxy
13338// that we do not pool other origins that resolve to the same IP when
13339// the certificate does not match the new origin.
13340// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0213341TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2313342 const std::string url1 = "http://www.example.org/";
13343 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1713344 const std::string ip_addr = "1.2.3.4";
13345
13346 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0213347 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2313348 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2913349 scoped_ptr<SpdyFrame> req1(
13350 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1713351
13352 MockWrite writes1[] = {
13353 CreateMockWrite(*req1, 0),
13354 };
13355
[email protected]23e482282013-06-14 16:08:0213356 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13357 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1713358 MockRead reads1[] = {
bncb9e20fc62015-08-17 17:19:3713359 CreateMockRead(*resp1, 1),
13360 CreateMockRead(*body1, 2),
13361 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1713362 };
13363
13364 scoped_ptr<DeterministicSocketData> data1(
13365 new DeterministicSocketData(reads1, arraysize(reads1),
13366 writes1, arraysize(writes1)));
13367 IPAddressNumber ip;
13368 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
13369 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13370 MockConnect connect_data1(ASYNC, OK, peer_addr);
13371 data1->set_connect_data(connect_data1);
13372
13373 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4613374 scoped_ptr<SpdyFrame> req2(
13375 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1713376
13377 MockWrite writes2[] = {
13378 CreateMockWrite(*req2, 0),
13379 };
13380
[email protected]23e482282013-06-14 16:08:0213381 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13382 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1713383 MockRead reads2[] = {
bncb9e20fc62015-08-17 17:19:3713384 CreateMockRead(*resp2, 1),
13385 CreateMockRead(*body2, 2),
13386 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1713387 };
13388
13389 scoped_ptr<DeterministicSocketData> data2(
13390 new DeterministicSocketData(reads2, arraysize(reads2),
13391 writes2, arraysize(writes2)));
13392 MockConnect connect_data2(ASYNC, OK);
13393 data2->set_connect_data(connect_data2);
13394
13395 // Set up a proxy config that sends HTTP requests to a proxy, and
13396 // all others direct.
13397 ProxyConfig proxy_config;
13398 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0713399 session_deps_.proxy_service.reset(new ProxyService(
csharrisonb7e3a082015-09-22 19:13:0413400 make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)), nullptr,
13401 NULL));
[email protected]2d88e7d2012-07-19 17:55:1713402
bncce36dca22015-04-21 22:11:2313403 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
13404 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1713405 // Load a valid cert. Note, that this does not need to
13406 // be valid for proxy because the MockSSLClientSocket does
13407 // not actually verify it. But SpdySession will use this
13408 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2313409 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
13410 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0713411 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
13412 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
13413 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1713414
13415 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0213416 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0713417 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
13418 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
13419 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1713420
[email protected]bb88e1d32013-05-03 23:11:0713421 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2313422 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0713423 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1713424
mmenkee65e7af2015-10-13 17:16:4213425 scoped_ptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0713426 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1713427
13428 // Start the first transaction to set up the SpdySession
13429 HttpRequestInfo request1;
13430 request1.method = "GET";
13431 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1713432 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013433 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713434 TestCompletionCallback callback1;
13435 ASSERT_EQ(ERR_IO_PENDING,
13436 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
13437 data1->RunFor(3);
13438
13439 ASSERT_TRUE(callback1.have_result());
13440 EXPECT_EQ(OK, callback1.WaitForResult());
13441 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13442
13443 // Now, start the HTTP request
13444 HttpRequestInfo request2;
13445 request2.method = "GET";
13446 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1713447 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013448 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713449 TestCompletionCallback callback2;
13450 EXPECT_EQ(ERR_IO_PENDING,
13451 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413452 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1713453 data2->RunFor(3);
13454
13455 ASSERT_TRUE(callback2.have_result());
13456 EXPECT_EQ(OK, callback2.WaitForResult());
13457 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13458}
13459
[email protected]85f97342013-04-17 06:12:2413460// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
13461// error) in SPDY session, removes the socket from pool and closes the SPDY
13462// session. Verify that new url's from the same HttpNetworkSession (and a new
13463// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0213464TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2313465 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2413466
13467 MockRead reads1[] = {
13468 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
13469 };
13470
mmenke11eb5152015-06-09 14:50:5013471 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2413472
[email protected]cdf8f7e72013-05-23 10:56:4613473 scoped_ptr<SpdyFrame> req2(
13474 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2413475 MockWrite writes2[] = {
13476 CreateMockWrite(*req2, 0),
13477 };
13478
[email protected]23e482282013-06-14 16:08:0213479 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13480 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2413481 MockRead reads2[] = {
13482 CreateMockRead(*resp2, 1),
13483 CreateMockRead(*body2, 2),
13484 MockRead(ASYNC, OK, 3) // EOF
13485 };
13486
mmenke11eb5152015-06-09 14:50:5013487 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13488 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2413489
[email protected]85f97342013-04-17 06:12:2413490 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0213491 ssl1.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5013492 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13493 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2413494
13495 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0213496 ssl2.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5013497 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13498 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2413499
mmenkee65e7af2015-10-13 17:16:4213500 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5013501 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2413502
13503 // Start the first transaction to set up the SpdySession and verify that
13504 // connection was closed.
13505 HttpRequestInfo request1;
13506 request1.method = "GET";
13507 request1.url = GURL(https_url);
13508 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013509 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413510 TestCompletionCallback callback1;
13511 EXPECT_EQ(ERR_IO_PENDING,
13512 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2413513 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
13514
13515 // Now, start the second request and make sure it succeeds.
13516 HttpRequestInfo request2;
13517 request2.method = "GET";
13518 request2.url = GURL(https_url);
13519 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013520 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413521 TestCompletionCallback callback2;
13522 EXPECT_EQ(ERR_IO_PENDING,
13523 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2413524
mmenke11eb5152015-06-09 14:50:5013525 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2413526 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13527}
13528
[email protected]23e482282013-06-14 16:08:0213529TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2313530 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0313531 ClientSocketPoolManager::set_max_sockets_per_group(
13532 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13533 ClientSocketPoolManager::set_max_sockets_per_pool(
13534 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13535
13536 // Use two different hosts with different IPs so they don't get pooled.
13537 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
13538 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
mmenkee65e7af2015-10-13 17:16:4213539 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0313540
13541 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0213542 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0313543 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0213544 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0313545 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13546 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13547
[email protected]cdf8f7e72013-05-23 10:56:4613548 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0313549 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
13550 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1313551 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0313552 };
[email protected]23e482282013-06-14 16:08:0213553 scoped_ptr<SpdyFrame> host1_resp(
13554 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13555 scoped_ptr<SpdyFrame> host1_resp_body(
13556 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313557 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1313558 CreateMockRead(*host1_resp, 1),
13559 CreateMockRead(*host1_resp_body, 2),
13560 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313561 };
13562
rch8e6c6c42015-05-01 14:05:1313563 scoped_ptr<SequencedSocketData> spdy1_data(
13564 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
13565 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0313566 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
13567
[email protected]cdf8f7e72013-05-23 10:56:4613568 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0313569 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
13570 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1313571 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0313572 };
[email protected]23e482282013-06-14 16:08:0213573 scoped_ptr<SpdyFrame> host2_resp(
13574 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13575 scoped_ptr<SpdyFrame> host2_resp_body(
13576 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313577 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1313578 CreateMockRead(*host2_resp, 1),
13579 CreateMockRead(*host2_resp_body, 2),
13580 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313581 };
13582
rch8e6c6c42015-05-01 14:05:1313583 scoped_ptr<SequencedSocketData> spdy2_data(
13584 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
13585 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0313586 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
13587
13588 MockWrite http_write[] = {
13589 MockWrite("GET / HTTP/1.1\r\n"
13590 "Host: www.a.com\r\n"
13591 "Connection: keep-alive\r\n\r\n"),
13592 };
13593
13594 MockRead http_read[] = {
13595 MockRead("HTTP/1.1 200 OK\r\n"),
13596 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13597 MockRead("Content-Length: 6\r\n\r\n"),
13598 MockRead("hello!"),
13599 };
13600 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
13601 http_write, arraysize(http_write));
13602 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13603
13604 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4013605 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5313606 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313607 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613608 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313609
13610 TestCompletionCallback callback;
13611 HttpRequestInfo request1;
13612 request1.method = "GET";
13613 request1.url = GURL("https://www.a.com/");
13614 request1.load_flags = 0;
13615 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5013616 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313617
13618 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
13619 EXPECT_EQ(ERR_IO_PENDING, rv);
13620 EXPECT_EQ(OK, callback.WaitForResult());
13621
13622 const HttpResponseInfo* response = trans->GetResponseInfo();
13623 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013624 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313625 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13626 EXPECT_TRUE(response->was_fetched_via_spdy);
13627 EXPECT_TRUE(response->was_npn_negotiated);
13628
13629 std::string response_data;
13630 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13631 EXPECT_EQ("hello!", response_data);
13632 trans.reset();
13633 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613634 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313635
13636 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4013637 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5313638 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313639 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613640 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313641 HttpRequestInfo request2;
13642 request2.method = "GET";
13643 request2.url = GURL("https://www.b.com/");
13644 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013645 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313646
13647 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
13648 EXPECT_EQ(ERR_IO_PENDING, rv);
13649 EXPECT_EQ(OK, callback.WaitForResult());
13650
13651 response = trans->GetResponseInfo();
13652 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013653 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313654 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13655 EXPECT_TRUE(response->was_fetched_via_spdy);
13656 EXPECT_TRUE(response->was_npn_negotiated);
13657 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13658 EXPECT_EQ("hello!", response_data);
13659 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613660 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313661 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613662 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313663
13664 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4013665 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5313666 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313667 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613668 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0313669 HttpRequestInfo request3;
13670 request3.method = "GET";
13671 request3.url = GURL("http://www.a.com/");
13672 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013673 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313674
13675 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
13676 EXPECT_EQ(ERR_IO_PENDING, rv);
13677 EXPECT_EQ(OK, callback.WaitForResult());
13678
13679 response = trans->GetResponseInfo();
13680 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013681 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313682 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13683 EXPECT_FALSE(response->was_fetched_via_spdy);
13684 EXPECT_FALSE(response->was_npn_negotiated);
13685 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13686 EXPECT_EQ("hello!", response_data);
13687 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613688 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313689 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613690 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313691}
13692
[email protected]79e1fd62013-06-20 06:50:0413693TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
13694 HttpRequestInfo request;
13695 request.method = "GET";
bncce36dca22015-04-21 22:11:2313696 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413697 request.load_flags = 0;
13698
mmenkee65e7af2015-10-13 17:16:4213699 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413700 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113701 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413702
ttuttled9dbc652015-09-29 20:00:5913703 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413704 StaticSocketDataProvider data;
13705 data.set_connect_data(mock_connect);
13706 session_deps_.socket_factory->AddSocketDataProvider(&data);
13707
13708 TestCompletionCallback callback;
13709
13710 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13711 EXPECT_EQ(ERR_IO_PENDING, rv);
13712
13713 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5913714 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0413715
[email protected]79e1fd62013-06-20 06:50:0413716 // We don't care whether this succeeds or fails, but it shouldn't crash.
13717 HttpRequestHeaders request_headers;
13718 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713719
13720 ConnectionAttempts attempts;
13721 trans->GetConnectionAttempts(&attempts);
13722 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5913723 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
13724
13725 IPEndPoint endpoint;
13726 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
13727 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413728}
13729
13730TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
13731 HttpRequestInfo request;
13732 request.method = "GET";
bncce36dca22015-04-21 22:11:2313733 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413734 request.load_flags = 0;
13735
mmenkee65e7af2015-10-13 17:16:4213736 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413737 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113738 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413739
ttuttled9dbc652015-09-29 20:00:5913740 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413741 StaticSocketDataProvider data;
13742 data.set_connect_data(mock_connect);
13743 session_deps_.socket_factory->AddSocketDataProvider(&data);
13744
13745 TestCompletionCallback callback;
13746
13747 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13748 EXPECT_EQ(ERR_IO_PENDING, rv);
13749
13750 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5913751 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0413752
[email protected]79e1fd62013-06-20 06:50:0413753 // We don't care whether this succeeds or fails, but it shouldn't crash.
13754 HttpRequestHeaders request_headers;
13755 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713756
13757 ConnectionAttempts attempts;
13758 trans->GetConnectionAttempts(&attempts);
13759 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5913760 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
13761
13762 IPEndPoint endpoint;
13763 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
13764 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413765}
13766
13767TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
13768 HttpRequestInfo request;
13769 request.method = "GET";
bncce36dca22015-04-21 22:11:2313770 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413771 request.load_flags = 0;
13772
mmenkee65e7af2015-10-13 17:16:4213773 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413774 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113775 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413776
13777 MockWrite data_writes[] = {
13778 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13779 };
13780 MockRead data_reads[] = {
13781 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13782 };
13783
13784 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13785 data_writes, arraysize(data_writes));
13786 session_deps_.socket_factory->AddSocketDataProvider(&data);
13787
13788 TestCompletionCallback callback;
13789
13790 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13791 EXPECT_EQ(ERR_IO_PENDING, rv);
13792
13793 rv = callback.WaitForResult();
13794 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13795
[email protected]79e1fd62013-06-20 06:50:0413796 HttpRequestHeaders request_headers;
13797 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13798 EXPECT_TRUE(request_headers.HasHeader("Host"));
13799}
13800
13801TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
13802 HttpRequestInfo request;
13803 request.method = "GET";
bncce36dca22015-04-21 22:11:2313804 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413805 request.load_flags = 0;
13806
mmenkee65e7af2015-10-13 17:16:4213807 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413808 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113809 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413810
13811 MockWrite data_writes[] = {
13812 MockWrite(ASYNC, ERR_CONNECTION_RESET),
13813 };
13814 MockRead data_reads[] = {
13815 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13816 };
13817
13818 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13819 data_writes, arraysize(data_writes));
13820 session_deps_.socket_factory->AddSocketDataProvider(&data);
13821
13822 TestCompletionCallback callback;
13823
13824 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13825 EXPECT_EQ(ERR_IO_PENDING, rv);
13826
13827 rv = callback.WaitForResult();
13828 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13829
[email protected]79e1fd62013-06-20 06:50:0413830 HttpRequestHeaders request_headers;
13831 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13832 EXPECT_TRUE(request_headers.HasHeader("Host"));
13833}
13834
13835TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
13836 HttpRequestInfo request;
13837 request.method = "GET";
bncce36dca22015-04-21 22:11:2313838 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413839 request.load_flags = 0;
13840
mmenkee65e7af2015-10-13 17:16:4213841 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413842 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113843 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413844
13845 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313846 MockWrite(
13847 "GET / HTTP/1.1\r\n"
13848 "Host: www.example.org\r\n"
13849 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413850 };
13851 MockRead data_reads[] = {
13852 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
13853 };
13854
13855 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13856 data_writes, arraysize(data_writes));
13857 session_deps_.socket_factory->AddSocketDataProvider(&data);
13858
13859 TestCompletionCallback callback;
13860
13861 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13862 EXPECT_EQ(ERR_IO_PENDING, rv);
13863
13864 rv = callback.WaitForResult();
13865 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13866
[email protected]79e1fd62013-06-20 06:50:0413867 HttpRequestHeaders request_headers;
13868 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13869 EXPECT_TRUE(request_headers.HasHeader("Host"));
13870}
13871
13872TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
13873 HttpRequestInfo request;
13874 request.method = "GET";
bncce36dca22015-04-21 22:11:2313875 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413876 request.load_flags = 0;
13877
mmenkee65e7af2015-10-13 17:16:4213878 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413879 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113880 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413881
13882 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313883 MockWrite(
13884 "GET / HTTP/1.1\r\n"
13885 "Host: www.example.org\r\n"
13886 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413887 };
13888 MockRead data_reads[] = {
13889 MockRead(ASYNC, ERR_CONNECTION_RESET),
13890 };
13891
13892 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13893 data_writes, arraysize(data_writes));
13894 session_deps_.socket_factory->AddSocketDataProvider(&data);
13895
13896 TestCompletionCallback callback;
13897
13898 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13899 EXPECT_EQ(ERR_IO_PENDING, rv);
13900
13901 rv = callback.WaitForResult();
13902 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13903
[email protected]79e1fd62013-06-20 06:50:0413904 HttpRequestHeaders request_headers;
13905 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13906 EXPECT_TRUE(request_headers.HasHeader("Host"));
13907}
13908
13909TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
13910 HttpRequestInfo request;
13911 request.method = "GET";
bncce36dca22015-04-21 22:11:2313912 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413913 request.load_flags = 0;
13914 request.extra_headers.SetHeader("X-Foo", "bar");
13915
mmenkee65e7af2015-10-13 17:16:4213916 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413917 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113918 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413919
13920 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313921 MockWrite(
13922 "GET / HTTP/1.1\r\n"
13923 "Host: www.example.org\r\n"
13924 "Connection: keep-alive\r\n"
13925 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413926 };
13927 MockRead data_reads[] = {
13928 MockRead("HTTP/1.1 200 OK\r\n"
13929 "Content-Length: 5\r\n\r\n"
13930 "hello"),
13931 MockRead(ASYNC, ERR_UNEXPECTED),
13932 };
13933
13934 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13935 data_writes, arraysize(data_writes));
13936 session_deps_.socket_factory->AddSocketDataProvider(&data);
13937
13938 TestCompletionCallback callback;
13939
13940 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13941 EXPECT_EQ(ERR_IO_PENDING, rv);
13942
13943 rv = callback.WaitForResult();
13944 EXPECT_EQ(OK, rv);
13945
13946 HttpRequestHeaders request_headers;
13947 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13948 std::string foo;
13949 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
13950 EXPECT_EQ("bar", foo);
13951}
13952
[email protected]bf828982013-08-14 18:01:4713953namespace {
13954
yhiranoa7e05bb2014-11-06 05:40:3913955// Fake HttpStream that simply records calls to SetPriority().
13956class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0313957 public base::SupportsWeakPtr<FakeStream> {
13958 public:
13959 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2013960 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0313961
13962 RequestPriority priority() const { return priority_; }
13963
dchengb03027d2014-10-21 12:00:2013964 int InitializeStream(const HttpRequestInfo* request_info,
13965 RequestPriority priority,
13966 const BoundNetLog& net_log,
13967 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313968 return ERR_IO_PENDING;
13969 }
13970
dchengb03027d2014-10-21 12:00:2013971 int SendRequest(const HttpRequestHeaders& request_headers,
13972 HttpResponseInfo* response,
13973 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313974 ADD_FAILURE();
13975 return ERR_UNEXPECTED;
13976 }
13977
dchengb03027d2014-10-21 12:00:2013978 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313979 ADD_FAILURE();
13980 return ERR_UNEXPECTED;
13981 }
13982
dchengb03027d2014-10-21 12:00:2013983 int ReadResponseBody(IOBuffer* buf,
13984 int buf_len,
13985 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313986 ADD_FAILURE();
13987 return ERR_UNEXPECTED;
13988 }
13989
dchengb03027d2014-10-21 12:00:2013990 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0313991
dchengb03027d2014-10-21 12:00:2013992 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0313993 ADD_FAILURE();
13994 return false;
13995 }
13996
dchengb03027d2014-10-21 12:00:2013997 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0313998 ADD_FAILURE();
13999 return false;
14000 }
14001
dchengb03027d2014-10-21 12:00:2014002 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314003
mmenkebd84c392015-09-02 14:12:3414004 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314005
sclittle4de1bab92015-09-22 21:28:2414006 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914007 ADD_FAILURE();
14008 return 0;
14009 }
14010
sclittlebe1ccf62015-09-02 19:40:3614011 int64_t GetTotalSentBytes() const override {
14012 ADD_FAILURE();
14013 return 0;
14014 }
14015
dchengb03027d2014-10-21 12:00:2014016 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314017 ADD_FAILURE();
14018 return false;
14019 }
14020
dchengb03027d2014-10-21 12:00:2014021 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14022
14023 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314024 ADD_FAILURE();
14025 }
14026
ttuttled9dbc652015-09-29 20:00:5914027 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14028
dchengb03027d2014-10-21 12:00:2014029 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314030
dchengb03027d2014-10-21 12:00:2014031 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314032
yhiranoa7e05bb2014-11-06 05:40:3914033 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
14034
14035 HttpStream* RenewStreamForAuth() override { return NULL; }
14036
[email protected]e86839fd2013-08-14 18:29:0314037 private:
14038 RequestPriority priority_;
14039
14040 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14041};
14042
14043// Fake HttpStreamRequest that simply records calls to SetPriority()
14044// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714045class FakeStreamRequest : public HttpStreamRequest,
14046 public base::SupportsWeakPtr<FakeStreamRequest> {
14047 public:
[email protected]e86839fd2013-08-14 18:29:0314048 FakeStreamRequest(RequestPriority priority,
14049 HttpStreamRequest::Delegate* delegate)
14050 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414051 delegate_(delegate),
14052 websocket_stream_create_helper_(NULL) {}
14053
14054 FakeStreamRequest(RequestPriority priority,
14055 HttpStreamRequest::Delegate* delegate,
14056 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14057 : priority_(priority),
14058 delegate_(delegate),
14059 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314060
dchengb03027d2014-10-21 12:00:2014061 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714062
14063 RequestPriority priority() const { return priority_; }
14064
[email protected]831e4a32013-11-14 02:14:4414065 const WebSocketHandshakeStreamBase::CreateHelper*
14066 websocket_stream_create_helper() const {
14067 return websocket_stream_create_helper_;
14068 }
14069
[email protected]e86839fd2013-08-14 18:29:0314070 // Create a new FakeStream and pass it to the request's
14071 // delegate. Returns a weak pointer to the FakeStream.
14072 base::WeakPtr<FakeStream> FinishStreamRequest() {
14073 FakeStream* fake_stream = new FakeStream(priority_);
14074 // Do this before calling OnStreamReady() as OnStreamReady() may
14075 // immediately delete |fake_stream|.
14076 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14077 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14078 return weak_stream;
14079 }
14080
dchengb03027d2014-10-21 12:00:2014081 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714082 ADD_FAILURE();
14083 return ERR_UNEXPECTED;
14084 }
14085
dchengb03027d2014-10-21 12:00:2014086 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714087 ADD_FAILURE();
14088 return LoadState();
14089 }
14090
dchengb03027d2014-10-21 12:00:2014091 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714092
dchengb03027d2014-10-21 12:00:2014093 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714094
dchengb03027d2014-10-21 12:00:2014095 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714096
dchengb03027d2014-10-21 12:00:2014097 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714098
ttuttle1f2d7e92015-04-28 16:17:4714099 const ConnectionAttempts& connection_attempts() const override {
14100 static ConnectionAttempts no_attempts;
14101 return no_attempts;
14102 }
14103
[email protected]bf828982013-08-14 18:01:4714104 private:
14105 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314106 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414107 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714108
14109 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14110};
14111
14112// Fake HttpStreamFactory that vends FakeStreamRequests.
14113class FakeStreamFactory : public HttpStreamFactory {
14114 public:
14115 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014116 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714117
14118 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14119 // RequestStream() (which may be NULL if it was destroyed already).
14120 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14121 return last_stream_request_;
14122 }
14123
dchengb03027d2014-10-21 12:00:2014124 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14125 RequestPriority priority,
14126 const SSLConfig& server_ssl_config,
14127 const SSLConfig& proxy_ssl_config,
14128 HttpStreamRequest::Delegate* delegate,
14129 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314130 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714131 last_stream_request_ = fake_request->AsWeakPtr();
14132 return fake_request;
14133 }
14134
dchengb03027d2014-10-21 12:00:2014135 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714136 const HttpRequestInfo& info,
14137 RequestPriority priority,
14138 const SSLConfig& server_ssl_config,
14139 const SSLConfig& proxy_ssl_config,
14140 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614141 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1314142 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414143 FakeStreamRequest* fake_request =
14144 new FakeStreamRequest(priority, delegate, create_helper);
14145 last_stream_request_ = fake_request->AsWeakPtr();
14146 return fake_request;
[email protected]bf828982013-08-14 18:01:4714147 }
14148
dchengb03027d2014-10-21 12:00:2014149 void PreconnectStreams(int num_streams,
14150 const HttpRequestInfo& info,
dchengb03027d2014-10-21 12:00:2014151 const SSLConfig& server_ssl_config,
14152 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4714153 ADD_FAILURE();
14154 }
14155
dchengb03027d2014-10-21 12:00:2014156 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714157 ADD_FAILURE();
14158 return NULL;
14159 }
14160
14161 private:
14162 base::WeakPtr<FakeStreamRequest> last_stream_request_;
14163
14164 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
14165};
14166
Adam Rice425cf122015-01-19 06:18:2414167// TODO(ricea): Maybe unify this with the one in
14168// url_request_http_job_unittest.cc ?
14169class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
14170 public:
14171 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
14172 bool using_proxy)
14173 : state_(connection.release(), using_proxy) {}
14174
14175 // Fake implementation of HttpStreamBase methods.
14176 // This ends up being quite "real" because this object has to really send data
14177 // on the mock socket. It might be easier to use the real implementation, but
14178 // the fact that the WebSocket code is not compiled on iOS makes that
14179 // difficult.
14180 int InitializeStream(const HttpRequestInfo* request_info,
14181 RequestPriority priority,
14182 const BoundNetLog& net_log,
14183 const CompletionCallback& callback) override {
14184 state_.Initialize(request_info, priority, net_log, callback);
14185 return OK;
14186 }
14187
14188 int SendRequest(const HttpRequestHeaders& request_headers,
14189 HttpResponseInfo* response,
14190 const CompletionCallback& callback) override {
14191 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
14192 response, callback);
14193 }
14194
14195 int ReadResponseHeaders(const CompletionCallback& callback) override {
14196 return parser()->ReadResponseHeaders(callback);
14197 }
14198
14199 int ReadResponseBody(IOBuffer* buf,
14200 int buf_len,
14201 const CompletionCallback& callback) override {
14202 NOTREACHED();
14203 return ERR_IO_PENDING;
14204 }
14205
14206 void Close(bool not_reusable) override {
14207 if (parser())
14208 parser()->Close(true);
14209 }
14210
14211 bool IsResponseBodyComplete() const override {
14212 NOTREACHED();
14213 return false;
14214 }
14215
Adam Rice425cf122015-01-19 06:18:2414216 bool IsConnectionReused() const override {
14217 NOTREACHED();
14218 return false;
14219 }
14220 void SetConnectionReused() override { NOTREACHED(); }
14221
mmenkebd84c392015-09-02 14:12:3414222 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2414223
sclittle4de1bab92015-09-22 21:28:2414224 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2414225 NOTREACHED();
14226 return 0;
14227 }
14228
sclittlebe1ccf62015-09-02 19:40:3614229 int64_t GetTotalSentBytes() const override {
14230 NOTREACHED();
14231 return 0;
14232 }
14233
Adam Rice425cf122015-01-19 06:18:2414234 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
14235 NOTREACHED();
14236 return false;
14237 }
14238
Adam Ricecb76ac62015-02-20 05:33:2514239 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2414240
14241 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
14242 NOTREACHED();
14243 }
14244
ttuttled9dbc652015-09-29 20:00:5914245 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14246
Adam Rice425cf122015-01-19 06:18:2414247 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
14248
14249 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
14250
14251 UploadProgress GetUploadProgress() const override {
14252 NOTREACHED();
14253 return UploadProgress();
14254 }
14255
14256 HttpStream* RenewStreamForAuth() override {
14257 NOTREACHED();
14258 return nullptr;
14259 }
14260
14261 // Fake implementation of WebSocketHandshakeStreamBase method(s)
14262 scoped_ptr<WebSocketStream> Upgrade() override {
14263 NOTREACHED();
14264 return scoped_ptr<WebSocketStream>();
14265 }
14266
14267 private:
14268 HttpStreamParser* parser() const { return state_.parser(); }
14269 HttpBasicState state_;
14270
14271 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
14272};
14273
[email protected]831e4a32013-11-14 02:14:4414274// TODO(yhirano): Split this class out into a net/websockets file, if it is
14275// worth doing.
14276class FakeWebSocketStreamCreateHelper :
14277 public WebSocketHandshakeStreamBase::CreateHelper {
14278 public:
dchengb03027d2014-10-21 12:00:2014279 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2114280 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1314281 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2414282 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
14283 using_proxy);
[email protected]831e4a32013-11-14 02:14:4414284 }
14285
dchengb03027d2014-10-21 12:00:2014286 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4414287 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1314288 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4414289 NOTREACHED();
14290 return NULL;
14291 };
14292
dchengb03027d2014-10-21 12:00:2014293 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4414294
14295 virtual scoped_ptr<WebSocketStream> Upgrade() {
14296 NOTREACHED();
14297 return scoped_ptr<WebSocketStream>();
14298 }
14299};
14300
[email protected]bf828982013-08-14 18:01:4714301} // namespace
14302
14303// Make sure that HttpNetworkTransaction passes on its priority to its
14304// stream request on start.
14305TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
mmenkee65e7af2015-10-13 17:16:4214306 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14307 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714308 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4414309 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714310
dcheng48459ac22014-08-26 00:46:4114311 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714312
14313 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
14314
14315 HttpRequestInfo request;
14316 TestCompletionCallback callback;
14317 EXPECT_EQ(ERR_IO_PENDING,
14318 trans.Start(&request, callback.callback(), BoundNetLog()));
14319
14320 base::WeakPtr<FakeStreamRequest> fake_request =
14321 fake_factory->last_stream_request();
14322 ASSERT_TRUE(fake_request != NULL);
14323 EXPECT_EQ(LOW, fake_request->priority());
14324}
14325
14326// Make sure that HttpNetworkTransaction passes on its priority
14327// updates to its stream request.
14328TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
mmenkee65e7af2015-10-13 17:16:4214329 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14330 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714331 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4414332 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714333
dcheng48459ac22014-08-26 00:46:4114334 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714335
14336 HttpRequestInfo request;
14337 TestCompletionCallback callback;
14338 EXPECT_EQ(ERR_IO_PENDING,
14339 trans.Start(&request, callback.callback(), BoundNetLog()));
14340
14341 base::WeakPtr<FakeStreamRequest> fake_request =
14342 fake_factory->last_stream_request();
14343 ASSERT_TRUE(fake_request != NULL);
14344 EXPECT_EQ(LOW, fake_request->priority());
14345
14346 trans.SetPriority(LOWEST);
14347 ASSERT_TRUE(fake_request != NULL);
14348 EXPECT_EQ(LOWEST, fake_request->priority());
14349}
14350
[email protected]e86839fd2013-08-14 18:29:0314351// Make sure that HttpNetworkTransaction passes on its priority
14352// updates to its stream.
14353TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
mmenkee65e7af2015-10-13 17:16:4214354 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14355 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0314356 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4414357 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0314358
dcheng48459ac22014-08-26 00:46:4114359 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0314360
14361 HttpRequestInfo request;
14362 TestCompletionCallback callback;
14363 EXPECT_EQ(ERR_IO_PENDING,
14364 trans.Start(&request, callback.callback(), BoundNetLog()));
14365
14366 base::WeakPtr<FakeStreamRequest> fake_request =
14367 fake_factory->last_stream_request();
14368 ASSERT_TRUE(fake_request != NULL);
14369 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
14370 ASSERT_TRUE(fake_stream != NULL);
14371 EXPECT_EQ(LOW, fake_stream->priority());
14372
14373 trans.SetPriority(LOWEST);
14374 EXPECT_EQ(LOWEST, fake_stream->priority());
14375}
14376
[email protected]831e4a32013-11-14 02:14:4414377TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
14378 // The same logic needs to be tested for both ws: and wss: schemes, but this
14379 // test is already parameterised on NextProto, so it uses a loop to verify
14380 // that the different schemes work.
bncce36dca22015-04-21 22:11:2314381 std::string test_cases[] = {"ws://www.example.org/",
14382 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4414383 for (size_t i = 0; i < arraysize(test_cases); ++i) {
mmenkee65e7af2015-10-13 17:16:4214384 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14385 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4414386 FakeStreamFactory* fake_factory = new FakeStreamFactory();
14387 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2314388 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4414389 scoped_ptr<HttpStreamFactory>(fake_factory));
14390
dcheng48459ac22014-08-26 00:46:4114391 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4414392 trans.SetWebSocketHandshakeStreamCreateHelper(
14393 &websocket_stream_create_helper);
14394
14395 HttpRequestInfo request;
14396 TestCompletionCallback callback;
14397 request.method = "GET";
14398 request.url = GURL(test_cases[i]);
14399
14400 EXPECT_EQ(ERR_IO_PENDING,
14401 trans.Start(&request, callback.callback(), BoundNetLog()));
14402
14403 base::WeakPtr<FakeStreamRequest> fake_request =
14404 fake_factory->last_stream_request();
14405 ASSERT_TRUE(fake_request != NULL);
14406 EXPECT_EQ(&websocket_stream_create_helper,
14407 fake_request->websocket_stream_create_helper());
14408 }
14409}
14410
[email protected]043b68c82013-08-22 23:41:5214411// Tests that when a used socket is returned to the SSL socket pool, it's closed
14412// if the transport socket pool is stalled on the global socket limit.
14413TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
14414 ClientSocketPoolManager::set_max_sockets_per_group(
14415 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14416 ClientSocketPoolManager::set_max_sockets_per_pool(
14417 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14418
14419 // Set up SSL request.
14420
14421 HttpRequestInfo ssl_request;
14422 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2314423 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214424
14425 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2314426 MockWrite(
14427 "GET / HTTP/1.1\r\n"
14428 "Host: www.example.org\r\n"
14429 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214430 };
14431 MockRead ssl_reads[] = {
14432 MockRead("HTTP/1.1 200 OK\r\n"),
14433 MockRead("Content-Length: 11\r\n\r\n"),
14434 MockRead("hello world"),
14435 MockRead(SYNCHRONOUS, OK),
14436 };
14437 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
14438 ssl_writes, arraysize(ssl_writes));
14439 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14440
14441 SSLSocketDataProvider ssl(ASYNC, OK);
14442 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14443
14444 // Set up HTTP request.
14445
14446 HttpRequestInfo http_request;
14447 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314448 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214449
14450 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314451 MockWrite(
14452 "GET / HTTP/1.1\r\n"
14453 "Host: www.example.org\r\n"
14454 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214455 };
14456 MockRead http_reads[] = {
14457 MockRead("HTTP/1.1 200 OK\r\n"),
14458 MockRead("Content-Length: 7\r\n\r\n"),
14459 MockRead("falafel"),
14460 MockRead(SYNCHRONOUS, OK),
14461 };
14462 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14463 http_writes, arraysize(http_writes));
14464 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14465
mmenkee65e7af2015-10-13 17:16:4214466 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5214467
14468 // Start the SSL request.
14469 TestCompletionCallback ssl_callback;
14470 scoped_ptr<HttpTransaction> ssl_trans(
14471 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14472 ASSERT_EQ(ERR_IO_PENDING,
14473 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
14474 BoundNetLog()));
14475
14476 // Start the HTTP request. Pool should stall.
14477 TestCompletionCallback http_callback;
14478 scoped_ptr<HttpTransaction> http_trans(
14479 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14480 ASSERT_EQ(ERR_IO_PENDING,
14481 http_trans->Start(&http_request, http_callback.callback(),
14482 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4114483 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214484
14485 // Wait for response from SSL request.
14486 ASSERT_EQ(OK, ssl_callback.WaitForResult());
14487 std::string response_data;
14488 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
14489 EXPECT_EQ("hello world", response_data);
14490
14491 // The SSL socket should automatically be closed, so the HTTP request can
14492 // start.
dcheng48459ac22014-08-26 00:46:4114493 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
14494 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214495
14496 // The HTTP request can now complete.
14497 ASSERT_EQ(OK, http_callback.WaitForResult());
14498 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
14499 EXPECT_EQ("falafel", response_data);
14500
dcheng48459ac22014-08-26 00:46:4114501 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214502}
14503
14504// Tests that when a SSL connection is established but there's no corresponding
14505// request that needs it, the new socket is closed if the transport socket pool
14506// is stalled on the global socket limit.
14507TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
14508 ClientSocketPoolManager::set_max_sockets_per_group(
14509 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14510 ClientSocketPoolManager::set_max_sockets_per_pool(
14511 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14512
14513 // Set up an ssl request.
14514
14515 HttpRequestInfo ssl_request;
14516 ssl_request.method = "GET";
14517 ssl_request.url = GURL("https://www.foopy.com/");
14518
14519 // No data will be sent on the SSL socket.
14520 StaticSocketDataProvider ssl_data;
14521 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14522
14523 SSLSocketDataProvider ssl(ASYNC, OK);
14524 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14525
14526 // Set up HTTP request.
14527
14528 HttpRequestInfo http_request;
14529 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314530 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214531
14532 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314533 MockWrite(
14534 "GET / HTTP/1.1\r\n"
14535 "Host: www.example.org\r\n"
14536 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214537 };
14538 MockRead http_reads[] = {
14539 MockRead("HTTP/1.1 200 OK\r\n"),
14540 MockRead("Content-Length: 7\r\n\r\n"),
14541 MockRead("falafel"),
14542 MockRead(SYNCHRONOUS, OK),
14543 };
14544 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14545 http_writes, arraysize(http_writes));
14546 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14547
mmenkee65e7af2015-10-13 17:16:4214548 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5214549
14550 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
14551 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2914552 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
14553 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5214554 session->ssl_config_service()->GetSSLConfig(&ssl_config);
mmenked1205bd3972015-07-15 22:26:3514555 http_stream_factory->PreconnectStreams(1, ssl_request, ssl_config,
14556 ssl_config);
dcheng48459ac22014-08-26 00:46:4114557 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214558
14559 // Start the HTTP request. Pool should stall.
14560 TestCompletionCallback http_callback;
14561 scoped_ptr<HttpTransaction> http_trans(
14562 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14563 ASSERT_EQ(ERR_IO_PENDING,
14564 http_trans->Start(&http_request, http_callback.callback(),
14565 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4114566 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214567
14568 // The SSL connection will automatically be closed once the connection is
14569 // established, to let the HTTP request start.
14570 ASSERT_EQ(OK, http_callback.WaitForResult());
14571 std::string response_data;
14572 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
14573 EXPECT_EQ("falafel", response_data);
14574
dcheng48459ac22014-08-26 00:46:4114575 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214576}
14577
[email protected]02d74a02014-04-23 18:10:5414578TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
14579 ScopedVector<UploadElementReader> element_readers;
14580 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714581 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414582
14583 HttpRequestInfo request;
14584 request.method = "POST";
14585 request.url = GURL("http://www.foo.com/");
14586 request.upload_data_stream = &upload_data_stream;
14587 request.load_flags = 0;
14588
mmenkee65e7af2015-10-13 17:16:4214589 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414590 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114591 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414592 // Send headers successfully, but get an error while sending the body.
14593 MockWrite data_writes[] = {
14594 MockWrite("POST / HTTP/1.1\r\n"
14595 "Host: www.foo.com\r\n"
14596 "Connection: keep-alive\r\n"
14597 "Content-Length: 3\r\n\r\n"),
14598 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14599 };
14600
14601 MockRead data_reads[] = {
14602 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14603 MockRead("hello world"),
14604 MockRead(SYNCHRONOUS, OK),
14605 };
14606 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14607 arraysize(data_writes));
14608 session_deps_.socket_factory->AddSocketDataProvider(&data);
14609
14610 TestCompletionCallback callback;
14611
14612 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14613 EXPECT_EQ(ERR_IO_PENDING, rv);
14614
14615 rv = callback.WaitForResult();
14616 EXPECT_EQ(OK, rv);
14617
14618 const HttpResponseInfo* response = trans->GetResponseInfo();
14619 ASSERT_TRUE(response != NULL);
14620
14621 EXPECT_TRUE(response->headers.get() != NULL);
14622 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14623
14624 std::string response_data;
14625 rv = ReadTransaction(trans.get(), &response_data);
14626 EXPECT_EQ(OK, rv);
14627 EXPECT_EQ("hello world", response_data);
14628}
14629
14630// This test makes sure the retry logic doesn't trigger when reading an error
14631// response from a server that rejected a POST with a CONNECTION_RESET.
14632TEST_P(HttpNetworkTransactionTest,
14633 PostReadsErrorResponseAfterResetOnReusedSocket) {
mmenkee65e7af2015-10-13 17:16:4214634 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414635 MockWrite data_writes[] = {
14636 MockWrite("GET / HTTP/1.1\r\n"
14637 "Host: www.foo.com\r\n"
14638 "Connection: keep-alive\r\n\r\n"),
14639 MockWrite("POST / HTTP/1.1\r\n"
14640 "Host: www.foo.com\r\n"
14641 "Connection: keep-alive\r\n"
14642 "Content-Length: 3\r\n\r\n"),
14643 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14644 };
14645
14646 MockRead data_reads[] = {
14647 MockRead("HTTP/1.1 200 Peachy\r\n"
14648 "Content-Length: 14\r\n\r\n"),
14649 MockRead("first response"),
14650 MockRead("HTTP/1.1 400 Not OK\r\n"
14651 "Content-Length: 15\r\n\r\n"),
14652 MockRead("second response"),
14653 MockRead(SYNCHRONOUS, OK),
14654 };
14655 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14656 arraysize(data_writes));
14657 session_deps_.socket_factory->AddSocketDataProvider(&data);
14658
14659 TestCompletionCallback callback;
14660 HttpRequestInfo request1;
14661 request1.method = "GET";
14662 request1.url = GURL("http://www.foo.com/");
14663 request1.load_flags = 0;
14664
14665 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4114666 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414667 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
14668 EXPECT_EQ(ERR_IO_PENDING, rv);
14669
14670 rv = callback.WaitForResult();
14671 EXPECT_EQ(OK, rv);
14672
14673 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
14674 ASSERT_TRUE(response1 != NULL);
14675
14676 EXPECT_TRUE(response1->headers.get() != NULL);
14677 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
14678
14679 std::string response_data1;
14680 rv = ReadTransaction(trans1.get(), &response_data1);
14681 EXPECT_EQ(OK, rv);
14682 EXPECT_EQ("first response", response_data1);
14683 // Delete the transaction to release the socket back into the socket pool.
14684 trans1.reset();
14685
14686 ScopedVector<UploadElementReader> element_readers;
14687 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714688 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414689
14690 HttpRequestInfo request2;
14691 request2.method = "POST";
14692 request2.url = GURL("http://www.foo.com/");
14693 request2.upload_data_stream = &upload_data_stream;
14694 request2.load_flags = 0;
14695
14696 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4114697 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414698 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
14699 EXPECT_EQ(ERR_IO_PENDING, rv);
14700
14701 rv = callback.WaitForResult();
14702 EXPECT_EQ(OK, rv);
14703
14704 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
14705 ASSERT_TRUE(response2 != NULL);
14706
14707 EXPECT_TRUE(response2->headers.get() != NULL);
14708 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
14709
14710 std::string response_data2;
14711 rv = ReadTransaction(trans2.get(), &response_data2);
14712 EXPECT_EQ(OK, rv);
14713 EXPECT_EQ("second response", response_data2);
14714}
14715
14716TEST_P(HttpNetworkTransactionTest,
14717 PostReadsErrorResponseAfterResetPartialBodySent) {
14718 ScopedVector<UploadElementReader> element_readers;
14719 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714720 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414721
14722 HttpRequestInfo request;
14723 request.method = "POST";
14724 request.url = GURL("http://www.foo.com/");
14725 request.upload_data_stream = &upload_data_stream;
14726 request.load_flags = 0;
14727
mmenkee65e7af2015-10-13 17:16:4214728 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414729 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114730 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414731 // Send headers successfully, but get an error while sending the body.
14732 MockWrite data_writes[] = {
14733 MockWrite("POST / HTTP/1.1\r\n"
14734 "Host: www.foo.com\r\n"
14735 "Connection: keep-alive\r\n"
14736 "Content-Length: 3\r\n\r\n"
14737 "fo"),
14738 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14739 };
14740
14741 MockRead data_reads[] = {
14742 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14743 MockRead("hello world"),
14744 MockRead(SYNCHRONOUS, OK),
14745 };
14746 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14747 arraysize(data_writes));
14748 session_deps_.socket_factory->AddSocketDataProvider(&data);
14749
14750 TestCompletionCallback callback;
14751
14752 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14753 EXPECT_EQ(ERR_IO_PENDING, rv);
14754
14755 rv = callback.WaitForResult();
14756 EXPECT_EQ(OK, rv);
14757
14758 const HttpResponseInfo* response = trans->GetResponseInfo();
14759 ASSERT_TRUE(response != NULL);
14760
14761 EXPECT_TRUE(response->headers.get() != NULL);
14762 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14763
14764 std::string response_data;
14765 rv = ReadTransaction(trans.get(), &response_data);
14766 EXPECT_EQ(OK, rv);
14767 EXPECT_EQ("hello world", response_data);
14768}
14769
14770// This tests the more common case than the previous test, where headers and
14771// body are not merged into a single request.
14772TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
14773 ScopedVector<UploadElementReader> element_readers;
14774 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714775 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5414776
14777 HttpRequestInfo request;
14778 request.method = "POST";
14779 request.url = GURL("http://www.foo.com/");
14780 request.upload_data_stream = &upload_data_stream;
14781 request.load_flags = 0;
14782
mmenkee65e7af2015-10-13 17:16:4214783 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414784 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114785 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414786 // Send headers successfully, but get an error while sending the body.
14787 MockWrite data_writes[] = {
14788 MockWrite("POST / HTTP/1.1\r\n"
14789 "Host: www.foo.com\r\n"
14790 "Connection: keep-alive\r\n"
14791 "Transfer-Encoding: chunked\r\n\r\n"),
14792 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14793 };
14794
14795 MockRead data_reads[] = {
14796 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14797 MockRead("hello world"),
14798 MockRead(SYNCHRONOUS, OK),
14799 };
14800 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14801 arraysize(data_writes));
14802 session_deps_.socket_factory->AddSocketDataProvider(&data);
14803
14804 TestCompletionCallback callback;
14805
14806 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14807 EXPECT_EQ(ERR_IO_PENDING, rv);
14808 // Make sure the headers are sent before adding a chunk. This ensures that
14809 // they can't be merged with the body in a single send. Not currently
14810 // necessary since a chunked body is never merged with headers, but this makes
14811 // the test more future proof.
14812 base::RunLoop().RunUntilIdle();
14813
mmenkecbc2b712014-10-09 20:29:0714814 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5414815
14816 rv = callback.WaitForResult();
14817 EXPECT_EQ(OK, rv);
14818
14819 const HttpResponseInfo* response = trans->GetResponseInfo();
14820 ASSERT_TRUE(response != NULL);
14821
14822 EXPECT_TRUE(response->headers.get() != NULL);
14823 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14824
14825 std::string response_data;
14826 rv = ReadTransaction(trans.get(), &response_data);
14827 EXPECT_EQ(OK, rv);
14828 EXPECT_EQ("hello world", response_data);
14829}
14830
14831TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
14832 ScopedVector<UploadElementReader> element_readers;
14833 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714834 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414835
14836 HttpRequestInfo request;
14837 request.method = "POST";
14838 request.url = GURL("http://www.foo.com/");
14839 request.upload_data_stream = &upload_data_stream;
14840 request.load_flags = 0;
14841
mmenkee65e7af2015-10-13 17:16:4214842 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414843 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114844 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414845
14846 MockWrite data_writes[] = {
14847 MockWrite("POST / HTTP/1.1\r\n"
14848 "Host: www.foo.com\r\n"
14849 "Connection: keep-alive\r\n"
14850 "Content-Length: 3\r\n\r\n"),
14851 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14852 };
14853
14854 MockRead data_reads[] = {
14855 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14856 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14857 MockRead("hello world"),
14858 MockRead(SYNCHRONOUS, OK),
14859 };
14860 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14861 arraysize(data_writes));
14862 session_deps_.socket_factory->AddSocketDataProvider(&data);
14863
14864 TestCompletionCallback callback;
14865
14866 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14867 EXPECT_EQ(ERR_IO_PENDING, rv);
14868
14869 rv = callback.WaitForResult();
14870 EXPECT_EQ(OK, rv);
14871
14872 const HttpResponseInfo* response = trans->GetResponseInfo();
14873 ASSERT_TRUE(response != NULL);
14874
14875 EXPECT_TRUE(response->headers.get() != NULL);
14876 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14877
14878 std::string response_data;
14879 rv = ReadTransaction(trans.get(), &response_data);
14880 EXPECT_EQ(OK, rv);
14881 EXPECT_EQ("hello world", response_data);
14882}
14883
14884TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
14885 ScopedVector<UploadElementReader> element_readers;
14886 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714887 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414888
14889 HttpRequestInfo request;
14890 request.method = "POST";
14891 request.url = GURL("http://www.foo.com/");
14892 request.upload_data_stream = &upload_data_stream;
14893 request.load_flags = 0;
14894
mmenkee65e7af2015-10-13 17:16:4214895 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414896 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114897 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414898 // Send headers successfully, but get an error while sending the body.
14899 MockWrite data_writes[] = {
14900 MockWrite("POST / HTTP/1.1\r\n"
14901 "Host: www.foo.com\r\n"
14902 "Connection: keep-alive\r\n"
14903 "Content-Length: 3\r\n\r\n"),
14904 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14905 };
14906
14907 MockRead data_reads[] = {
14908 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
14909 MockRead("hello world"),
14910 MockRead(SYNCHRONOUS, OK),
14911 };
14912 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14913 arraysize(data_writes));
14914 session_deps_.socket_factory->AddSocketDataProvider(&data);
14915
14916 TestCompletionCallback callback;
14917
14918 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14919 EXPECT_EQ(ERR_IO_PENDING, rv);
14920
14921 rv = callback.WaitForResult();
14922 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414923}
14924
14925TEST_P(HttpNetworkTransactionTest,
14926 PostIgnoresNonErrorResponseAfterResetAnd100) {
14927 ScopedVector<UploadElementReader> element_readers;
14928 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714929 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414930
14931 HttpRequestInfo request;
14932 request.method = "POST";
14933 request.url = GURL("http://www.foo.com/");
14934 request.upload_data_stream = &upload_data_stream;
14935 request.load_flags = 0;
14936
mmenkee65e7af2015-10-13 17:16:4214937 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414938 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114939 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414940 // Send headers successfully, but get an error while sending the body.
14941 MockWrite data_writes[] = {
14942 MockWrite("POST / HTTP/1.1\r\n"
14943 "Host: www.foo.com\r\n"
14944 "Connection: keep-alive\r\n"
14945 "Content-Length: 3\r\n\r\n"),
14946 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14947 };
14948
14949 MockRead data_reads[] = {
14950 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14951 MockRead("HTTP/1.0 302 Redirect\r\n"),
14952 MockRead("Location: http://somewhere-else.com/\r\n"),
14953 MockRead("Content-Length: 0\r\n\r\n"),
14954 MockRead(SYNCHRONOUS, OK),
14955 };
14956 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14957 arraysize(data_writes));
14958 session_deps_.socket_factory->AddSocketDataProvider(&data);
14959
14960 TestCompletionCallback callback;
14961
14962 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14963 EXPECT_EQ(ERR_IO_PENDING, rv);
14964
14965 rv = callback.WaitForResult();
14966 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414967}
14968
14969TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
14970 ScopedVector<UploadElementReader> element_readers;
14971 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714972 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414973
14974 HttpRequestInfo request;
14975 request.method = "POST";
14976 request.url = GURL("http://www.foo.com/");
14977 request.upload_data_stream = &upload_data_stream;
14978 request.load_flags = 0;
14979
mmenkee65e7af2015-10-13 17:16:4214980 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414981 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114982 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414983 // Send headers successfully, but get an error while sending the body.
14984 MockWrite data_writes[] = {
14985 MockWrite("POST / HTTP/1.1\r\n"
14986 "Host: www.foo.com\r\n"
14987 "Connection: keep-alive\r\n"
14988 "Content-Length: 3\r\n\r\n"),
14989 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14990 };
14991
14992 MockRead data_reads[] = {
14993 MockRead("HTTP 0.9 rocks!"),
14994 MockRead(SYNCHRONOUS, OK),
14995 };
14996 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14997 arraysize(data_writes));
14998 session_deps_.socket_factory->AddSocketDataProvider(&data);
14999
15000 TestCompletionCallback callback;
15001
15002 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15003 EXPECT_EQ(ERR_IO_PENDING, rv);
15004
15005 rv = callback.WaitForResult();
15006 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415007}
15008
15009TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
15010 ScopedVector<UploadElementReader> element_readers;
15011 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0715012 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5415013
15014 HttpRequestInfo request;
15015 request.method = "POST";
15016 request.url = GURL("http://www.foo.com/");
15017 request.upload_data_stream = &upload_data_stream;
15018 request.load_flags = 0;
15019
mmenkee65e7af2015-10-13 17:16:4215020 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415021 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115022 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415023 // Send headers successfully, but get an error while sending the body.
15024 MockWrite data_writes[] = {
15025 MockWrite("POST / HTTP/1.1\r\n"
15026 "Host: www.foo.com\r\n"
15027 "Connection: keep-alive\r\n"
15028 "Content-Length: 3\r\n\r\n"),
15029 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15030 };
15031
15032 MockRead data_reads[] = {
15033 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15034 MockRead(SYNCHRONOUS, OK),
15035 };
15036 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15037 arraysize(data_writes));
15038 session_deps_.socket_factory->AddSocketDataProvider(&data);
15039
15040 TestCompletionCallback callback;
15041
15042 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15043 EXPECT_EQ(ERR_IO_PENDING, rv);
15044
15045 rv = callback.WaitForResult();
15046 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415047}
15048
Adam Rice425cf122015-01-19 06:18:2415049// Verify that proxy headers are not sent to the destination server when
15050// establishing a tunnel for a secure WebSocket connection.
15051TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
15052 HttpRequestInfo request;
15053 request.method = "GET";
bncce36dca22015-04-21 22:11:2315054 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415055 AddWebSocketHeaders(&request.extra_headers);
15056
15057 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315058 session_deps_.proxy_service =
15059 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415060
mmenkee65e7af2015-10-13 17:16:4215061 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415062
15063 // Since a proxy is configured, try to establish a tunnel.
15064 MockWrite data_writes[] = {
15065 MockWrite(
bncce36dca22015-04-21 22:11:2315066 "CONNECT www.example.org:443 HTTP/1.1\r\n"
15067 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415068 "Proxy-Connection: keep-alive\r\n\r\n"),
15069
15070 // After calling trans->RestartWithAuth(), this is the request we should
15071 // be issuing -- the final header line contains the credentials.
15072 MockWrite(
bncce36dca22015-04-21 22:11:2315073 "CONNECT www.example.org:443 HTTP/1.1\r\n"
15074 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415075 "Proxy-Connection: keep-alive\r\n"
15076 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15077
15078 MockWrite(
15079 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315080 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415081 "Connection: Upgrade\r\n"
15082 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315083 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415084 "Sec-WebSocket-Version: 13\r\n"
15085 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
15086 };
15087
15088 // The proxy responds to the connect with a 407, using a persistent
15089 // connection.
15090 MockRead data_reads[] = {
15091 // No credentials.
15092 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15093 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415094 MockRead("Content-Length: 0\r\n"),
15095 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415096
15097 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15098
15099 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15100 MockRead("Upgrade: websocket\r\n"),
15101 MockRead("Connection: Upgrade\r\n"),
15102 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15103 };
15104
15105 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15106 arraysize(data_writes));
15107 session_deps_.socket_factory->AddSocketDataProvider(&data);
15108 SSLSocketDataProvider ssl(ASYNC, OK);
15109 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15110
15111 scoped_ptr<HttpTransaction> trans(
15112 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15113 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15114 trans->SetWebSocketHandshakeStreamCreateHelper(
15115 &websocket_stream_create_helper);
15116
15117 {
15118 TestCompletionCallback callback;
15119
15120 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15121 EXPECT_EQ(ERR_IO_PENDING, rv);
15122
15123 rv = callback.WaitForResult();
15124 EXPECT_EQ(OK, rv);
15125 }
15126
15127 const HttpResponseInfo* response = trans->GetResponseInfo();
15128 ASSERT_TRUE(response);
15129 ASSERT_TRUE(response->headers.get());
15130 EXPECT_EQ(407, response->headers->response_code());
15131
15132 {
15133 TestCompletionCallback callback;
15134
15135 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15136 callback.callback());
15137 EXPECT_EQ(ERR_IO_PENDING, rv);
15138
15139 rv = callback.WaitForResult();
15140 EXPECT_EQ(OK, rv);
15141 }
15142
15143 response = trans->GetResponseInfo();
15144 ASSERT_TRUE(response);
15145 ASSERT_TRUE(response->headers.get());
15146
15147 EXPECT_EQ(101, response->headers->response_code());
15148
15149 trans.reset();
15150 session->CloseAllConnections();
15151}
15152
15153// Verify that proxy headers are not sent to the destination server when
15154// establishing a tunnel for an insecure WebSocket connection.
15155// This requires the authentication info to be injected into the auth cache
15156// due to crbug.com/395064
15157// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
15158TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
15159 HttpRequestInfo request;
15160 request.method = "GET";
bncce36dca22015-04-21 22:11:2315161 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415162 AddWebSocketHeaders(&request.extra_headers);
15163
15164 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315165 session_deps_.proxy_service =
15166 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415167
mmenkee65e7af2015-10-13 17:16:4215168 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415169
15170 MockWrite data_writes[] = {
15171 // Try to establish a tunnel for the WebSocket connection, with
15172 // credentials. Because WebSockets have a separate set of socket pools,
15173 // they cannot and will not use the same TCP/IP connection as the
15174 // preflight HTTP request.
15175 MockWrite(
bncce36dca22015-04-21 22:11:2315176 "CONNECT www.example.org:80 HTTP/1.1\r\n"
15177 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2415178 "Proxy-Connection: keep-alive\r\n"
15179 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15180
15181 MockWrite(
15182 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315183 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415184 "Connection: Upgrade\r\n"
15185 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315186 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415187 "Sec-WebSocket-Version: 13\r\n"
15188 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
15189 };
15190
15191 MockRead data_reads[] = {
15192 // HTTP CONNECT with credentials.
15193 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15194
15195 // WebSocket connection established inside tunnel.
15196 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15197 MockRead("Upgrade: websocket\r\n"),
15198 MockRead("Connection: Upgrade\r\n"),
15199 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15200 };
15201
15202 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15203 arraysize(data_writes));
15204 session_deps_.socket_factory->AddSocketDataProvider(&data);
15205
15206 session->http_auth_cache()->Add(
15207 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
15208 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
15209
15210 scoped_ptr<HttpTransaction> trans(
15211 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15212 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15213 trans->SetWebSocketHandshakeStreamCreateHelper(
15214 &websocket_stream_create_helper);
15215
15216 TestCompletionCallback callback;
15217
15218 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15219 EXPECT_EQ(ERR_IO_PENDING, rv);
15220
15221 rv = callback.WaitForResult();
15222 EXPECT_EQ(OK, rv);
15223
15224 const HttpResponseInfo* response = trans->GetResponseInfo();
15225 ASSERT_TRUE(response);
15226 ASSERT_TRUE(response->headers.get());
15227
15228 EXPECT_EQ(101, response->headers->response_code());
15229
15230 trans.reset();
15231 session->CloseAllConnections();
15232}
15233
sclittlefb249892015-09-10 21:33:2215234TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
15235 ScopedVector<UploadElementReader> element_readers;
15236 element_readers.push_back(new UploadBytesElementReader("foo", 3));
15237 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
15238
15239 HttpRequestInfo request;
15240 request.method = "POST";
15241 request.url = GURL("http://www.foo.com/");
15242 request.upload_data_stream = &upload_data_stream;
15243
mmenkee65e7af2015-10-13 17:16:4215244 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2215245 scoped_ptr<HttpTransaction> trans(
15246 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15247 MockWrite data_writes[] = {
15248 MockWrite("POST / HTTP/1.1\r\n"
15249 "Host: www.foo.com\r\n"
15250 "Connection: keep-alive\r\n"
15251 "Content-Length: 3\r\n\r\n"),
15252 MockWrite("foo"),
15253 };
15254
15255 MockRead data_reads[] = {
15256 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15257 MockRead(SYNCHRONOUS, OK),
15258 };
15259 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15260 arraysize(data_writes));
15261 session_deps_.socket_factory->AddSocketDataProvider(&data);
15262
15263 TestCompletionCallback callback;
15264
15265 EXPECT_EQ(ERR_IO_PENDING,
15266 trans->Start(&request, callback.callback(), BoundNetLog()));
15267 EXPECT_EQ(OK, callback.WaitForResult());
15268
15269 std::string response_data;
15270 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15271
15272 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15273 trans->GetTotalSentBytes());
15274 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15275 trans->GetTotalReceivedBytes());
15276}
15277
15278TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
15279 ScopedVector<UploadElementReader> element_readers;
15280 element_readers.push_back(new UploadBytesElementReader("foo", 3));
15281 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
15282
15283 HttpRequestInfo request;
15284 request.method = "POST";
15285 request.url = GURL("http://www.foo.com/");
15286 request.upload_data_stream = &upload_data_stream;
15287
mmenkee65e7af2015-10-13 17:16:4215288 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2215289 scoped_ptr<HttpTransaction> trans(
15290 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15291 MockWrite data_writes[] = {
15292 MockWrite("POST / HTTP/1.1\r\n"
15293 "Host: www.foo.com\r\n"
15294 "Connection: keep-alive\r\n"
15295 "Content-Length: 3\r\n\r\n"),
15296 MockWrite("foo"),
15297 };
15298
15299 MockRead data_reads[] = {
15300 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
15301 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15302 MockRead(SYNCHRONOUS, OK),
15303 };
15304 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15305 arraysize(data_writes));
15306 session_deps_.socket_factory->AddSocketDataProvider(&data);
15307
15308 TestCompletionCallback callback;
15309
15310 EXPECT_EQ(ERR_IO_PENDING,
15311 trans->Start(&request, callback.callback(), BoundNetLog()));
15312 EXPECT_EQ(OK, callback.WaitForResult());
15313
15314 std::string response_data;
15315 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15316
15317 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15318 trans->GetTotalSentBytes());
15319 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15320 trans->GetTotalReceivedBytes());
15321}
15322
15323TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
15324 ScopedVector<UploadElementReader> element_readers;
15325 element_readers.push_back(new UploadBytesElementReader("foo", 3));
15326 ChunkedUploadDataStream upload_data_stream(0);
15327
15328 HttpRequestInfo request;
15329 request.method = "POST";
15330 request.url = GURL("http://www.foo.com/");
15331 request.upload_data_stream = &upload_data_stream;
15332
mmenkee65e7af2015-10-13 17:16:4215333 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2215334 scoped_ptr<HttpTransaction> trans(
15335 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15336 // Send headers successfully, but get an error while sending the body.
15337 MockWrite data_writes[] = {
15338 MockWrite("POST / HTTP/1.1\r\n"
15339 "Host: www.foo.com\r\n"
15340 "Connection: keep-alive\r\n"
15341 "Transfer-Encoding: chunked\r\n\r\n"),
15342 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
15343 };
15344
15345 MockRead data_reads[] = {
15346 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15347 MockRead(SYNCHRONOUS, OK),
15348 };
15349 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15350 arraysize(data_writes));
15351 session_deps_.socket_factory->AddSocketDataProvider(&data);
15352
15353 TestCompletionCallback callback;
15354
15355 EXPECT_EQ(ERR_IO_PENDING,
15356 trans->Start(&request, callback.callback(), BoundNetLog()));
15357
15358 base::RunLoop().RunUntilIdle();
15359 upload_data_stream.AppendData("f", 1, false);
15360
15361 base::RunLoop().RunUntilIdle();
15362 upload_data_stream.AppendData("oo", 2, true);
15363
15364 EXPECT_EQ(OK, callback.WaitForResult());
15365
15366 std::string response_data;
15367 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15368
15369 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15370 trans->GetTotalSentBytes());
15371 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15372 trans->GetTotalReceivedBytes());
15373}
15374
[email protected]89ceba9a2009-03-21 03:46:0615375} // namespace net