blob: 56f3bb3d171cb944c83b8ff0fd5882f6f9b2b850 [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);
bnc1f295372015-10-21 23:24:221469 session->GetAlpnProtos(&ssl_config.alpn_protos);
1470 session->GetNpnProtos(&ssl_config.npn_protos);
mmenked1205bd2015-07-15 22:26:351471 session->http_stream_factory()->PreconnectStreams(1, request, ssl_config,
1472 ssl_config);
[email protected]a34f61ee2014-03-18 20:59:491473 // Wait for the preconnect to complete.
1474 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1475 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101476 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491477
1478 // Make the request.
1479 TestCompletionCallback callback;
1480
1481 scoped_ptr<HttpTransaction> trans(
1482 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1483
1484 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1485 EXPECT_EQ(ERR_IO_PENDING, rv);
1486
1487 rv = callback.WaitForResult();
1488 EXPECT_EQ(OK, rv);
1489
1490 LoadTimingInfo load_timing_info;
1491 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101492 TestLoadTimingNotReused(
1493 load_timing_info,
1494 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491495
1496 const HttpResponseInfo* response = trans->GetResponseInfo();
1497 ASSERT_TRUE(response != NULL);
1498
1499 EXPECT_TRUE(response->headers.get() != NULL);
1500 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1501
1502 std::string response_data;
1503 rv = ReadTransaction(trans.get(), &response_data);
1504 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101505 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491506}
1507
[email protected]23e482282013-06-14 16:08:021508TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231509 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061510 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511511 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1512}
1513
[email protected]23e482282013-06-14 16:08:021514TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061515 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511516 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251517}
1518
[email protected]23e482282013-06-14 16:08:021519TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061520 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511521 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251522}
1523
[email protected]d58ceea82014-06-04 10:55:541524// Make sure that on a 408 response (Request Timeout), the request is retried,
1525// if the socket was a reused keep alive socket.
1526TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1527 MockRead read_failure(SYNCHRONOUS,
1528 "HTTP/1.1 408 Request Timeout\r\n"
1529 "Connection: Keep-Alive\r\n"
1530 "Content-Length: 6\r\n\r\n"
1531 "Pickle");
1532 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1533}
1534
[email protected]a34f61ee2014-03-18 20:59:491535TEST_P(HttpNetworkTransactionTest,
1536 PreconnectErrorNotConnectedOnWrite) {
1537 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101538 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491539}
1540
1541TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1542 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101543 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491544}
1545
1546TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1547 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101548 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1549}
1550
1551TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1552 MockRead read_failure(ASYNC, OK); // EOF
1553 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1554}
1555
[email protected]d58ceea82014-06-04 10:55:541556// Make sure that on a 408 response (Request Timeout), the request is retried,
1557// if the socket was a preconnected (UNUSED_IDLE) socket.
1558TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1559 MockRead read_failure(SYNCHRONOUS,
1560 "HTTP/1.1 408 Request Timeout\r\n"
1561 "Connection: Keep-Alive\r\n"
1562 "Content-Length: 6\r\n\r\n"
1563 "Pickle");
1564 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1565 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1566}
1567
[email protected]09356c652014-03-25 15:36:101568TEST_P(HttpNetworkTransactionTest,
1569 SpdyPreconnectErrorNotConnectedOnWrite) {
1570 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1571 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1572}
1573
1574TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1575 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1576 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1577}
1578
1579TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1580 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1581 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1582}
1583
1584TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1585 MockRead read_failure(ASYNC, OK); // EOF
1586 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491587}
1588
[email protected]23e482282013-06-14 16:08:021589TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421590 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251591 request.method = "GET";
bncce36dca22015-04-21 22:11:231592 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251593 request.load_flags = 0;
1594
mmenkee65e7af2015-10-13 17:16:421595 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271596 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411597 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271598
[email protected]3d2a59b2008-09-26 19:44:251599 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061600 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351601 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1602 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061603 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251604 };
[email protected]31a2bfe2010-02-09 08:03:391605 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071606 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251607
[email protected]49639fa2011-12-20 23:22:411608 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251609
[email protected]49639fa2011-12-20 23:22:411610 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421611 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251612
1613 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421614 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:591615
1616 IPEndPoint endpoint;
1617 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
1618 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251619}
1620
1621// What do various browsers do when the server closes a non-keepalive
1622// connection without sending any response header or body?
1623//
1624// IE7: error page
1625// Safari 3.1.2 (Windows): error page
1626// Firefox 3.0.1: blank page
1627// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421628// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1629// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021630TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251631 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061632 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351633 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1634 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061635 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251636 };
[email protected]31a2bfe2010-02-09 08:03:391637 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1638 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421639 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251640}
[email protected]038e9a32008-10-08 22:40:161641
[email protected]1826a402014-01-08 15:40:481642// Test that network access can be deferred and resumed.
1643TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1644 HttpRequestInfo request;
1645 request.method = "GET";
bncce36dca22015-04-21 22:11:231646 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481647 request.load_flags = 0;
1648
mmenkee65e7af2015-10-13 17:16:421649 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1826a402014-01-08 15:40:481650 scoped_ptr<HttpTransaction> trans(
1651 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1652
1653 // Defer on OnBeforeNetworkStart.
1654 BeforeNetworkStartHandler net_start_handler(true); // defer
1655 trans->SetBeforeNetworkStartCallback(
1656 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1657 base::Unretained(&net_start_handler)));
1658
1659 MockRead data_reads[] = {
1660 MockRead("HTTP/1.0 200 OK\r\n"),
1661 MockRead("Content-Length: 5\r\n\r\n"),
1662 MockRead("hello"),
1663 MockRead(SYNCHRONOUS, 0),
1664 };
1665 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1666 session_deps_.socket_factory->AddSocketDataProvider(&data);
1667
1668 TestCompletionCallback callback;
1669
1670 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1671 EXPECT_EQ(ERR_IO_PENDING, rv);
1672 base::MessageLoop::current()->RunUntilIdle();
1673
1674 // Should have deferred for network start.
1675 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1676 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481677
1678 trans->ResumeNetworkStart();
1679 rv = callback.WaitForResult();
1680 EXPECT_EQ(OK, rv);
1681 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1682
1683 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1684 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1685 if (rv == ERR_IO_PENDING)
1686 rv = callback.WaitForResult();
1687 EXPECT_EQ(5, rv);
1688 trans.reset();
1689}
1690
1691// Test that network use can be deferred and canceled.
1692TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1693 HttpRequestInfo request;
1694 request.method = "GET";
bncce36dca22015-04-21 22:11:231695 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481696 request.load_flags = 0;
1697
mmenkee65e7af2015-10-13 17:16:421698 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1826a402014-01-08 15:40:481699 scoped_ptr<HttpTransaction> trans(
1700 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1701
1702 // Defer on OnBeforeNetworkStart.
1703 BeforeNetworkStartHandler net_start_handler(true); // defer
1704 trans->SetBeforeNetworkStartCallback(
1705 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1706 base::Unretained(&net_start_handler)));
1707
1708 TestCompletionCallback callback;
1709
1710 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1711 EXPECT_EQ(ERR_IO_PENDING, rv);
1712 base::MessageLoop::current()->RunUntilIdle();
1713
1714 // Should have deferred for network start.
1715 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1716 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481717}
1718
[email protected]7a5378b2012-11-04 03:25:171719// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1720// tests. There was a bug causing HttpNetworkTransaction to hang in the
1721// destructor in such situations.
1722// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021723TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171724 HttpRequestInfo request;
1725 request.method = "GET";
bncce36dca22015-04-21 22:11:231726 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171727 request.load_flags = 0;
1728
mmenkee65e7af2015-10-13 17:16:421729 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361730 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501731 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171732
1733 MockRead data_reads[] = {
1734 MockRead("HTTP/1.0 200 OK\r\n"),
1735 MockRead("Connection: keep-alive\r\n"),
1736 MockRead("Content-Length: 100\r\n\r\n"),
1737 MockRead("hello"),
1738 MockRead(SYNCHRONOUS, 0),
1739 };
1740 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071741 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171742
1743 TestCompletionCallback callback;
1744
1745 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1746 EXPECT_EQ(ERR_IO_PENDING, rv);
1747
1748 rv = callback.WaitForResult();
1749 EXPECT_EQ(OK, rv);
1750
1751 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501752 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171753 if (rv == ERR_IO_PENDING)
1754 rv = callback.WaitForResult();
1755 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501756 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171757 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1758
1759 trans.reset();
[email protected]2da659e2013-05-23 20:51:341760 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171761 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1762}
1763
[email protected]23e482282013-06-14 16:08:021764TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171765 HttpRequestInfo request;
1766 request.method = "GET";
bncce36dca22015-04-21 22:11:231767 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171768 request.load_flags = 0;
1769
mmenkee65e7af2015-10-13 17:16:421770 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361771 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501772 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171773
1774 MockRead data_reads[] = {
1775 MockRead("HTTP/1.0 200 OK\r\n"),
1776 MockRead("Connection: keep-alive\r\n"),
1777 MockRead("Content-Length: 100\r\n\r\n"),
1778 MockRead(SYNCHRONOUS, 0),
1779 };
1780 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071781 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171782
1783 TestCompletionCallback callback;
1784
1785 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1786 EXPECT_EQ(ERR_IO_PENDING, rv);
1787
1788 rv = callback.WaitForResult();
1789 EXPECT_EQ(OK, rv);
1790
1791 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501792 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171793 if (rv == ERR_IO_PENDING)
1794 rv = callback.WaitForResult();
1795 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1796
1797 trans.reset();
[email protected]2da659e2013-05-23 20:51:341798 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171799 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1800}
1801
[email protected]0b0bf032010-09-21 18:08:501802// Test that we correctly reuse a keep-alive connection after not explicitly
1803// reading the body.
[email protected]23e482282013-06-14 16:08:021804TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131805 HttpRequestInfo request;
1806 request.method = "GET";
1807 request.url = GURL("http://www.foo.com/");
1808 request.load_flags = 0;
1809
vishal.b62985ca92015-04-17 08:45:511810 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071811 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:421812 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271813
[email protected]0b0bf032010-09-21 18:08:501814 // Note that because all these reads happen in the same
1815 // StaticSocketDataProvider, it shows that the same socket is being reused for
1816 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131817 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501818 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1819 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131820 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501821 MockRead("HTTP/1.1 302 Found\r\n"
1822 "Content-Length: 0\r\n\r\n"),
1823 MockRead("HTTP/1.1 302 Found\r\n"
1824 "Content-Length: 5\r\n\r\n"
1825 "hello"),
1826 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1827 "Content-Length: 0\r\n\r\n"),
1828 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1829 "Content-Length: 5\r\n\r\n"
1830 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131831 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1832 MockRead("hello"),
1833 };
1834 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071835 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131836
1837 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061838 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131839 };
1840 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071841 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131842
[email protected]0b0bf032010-09-21 18:08:501843 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1844 std::string response_lines[kNumUnreadBodies];
1845
[email protected]58e32bb2013-01-21 18:23:251846 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501847 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411848 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131849
[email protected]262eec82013-03-19 21:01:361850 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501851 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131852
[email protected]49639fa2011-12-20 23:22:411853 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131854 EXPECT_EQ(ERR_IO_PENDING, rv);
1855
1856 rv = callback.WaitForResult();
1857 EXPECT_EQ(OK, rv);
1858
[email protected]58e32bb2013-01-21 18:23:251859 LoadTimingInfo load_timing_info;
1860 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1861 if (i == 0) {
1862 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1863 first_socket_log_id = load_timing_info.socket_log_id;
1864 } else {
1865 TestLoadTimingReused(load_timing_info);
1866 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1867 }
1868
[email protected]fc31d6a42010-06-24 18:05:131869 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501870 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131871
[email protected]90499482013-06-01 00:39:501872 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501873 response_lines[i] = response->headers->GetStatusLine();
1874
1875 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131876 }
[email protected]0b0bf032010-09-21 18:08:501877
1878 const char* const kStatusLines[] = {
1879 "HTTP/1.1 204 No Content",
1880 "HTTP/1.1 205 Reset Content",
1881 "HTTP/1.1 304 Not Modified",
1882 "HTTP/1.1 302 Found",
1883 "HTTP/1.1 302 Found",
1884 "HTTP/1.1 301 Moved Permanently",
1885 "HTTP/1.1 301 Moved Permanently",
1886 };
1887
mostynb91e0da982015-01-20 19:17:271888 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1889 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501890
1891 for (int i = 0; i < kNumUnreadBodies; ++i)
1892 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1893
[email protected]49639fa2011-12-20 23:22:411894 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361895 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501896 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411897 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501898 EXPECT_EQ(ERR_IO_PENDING, rv);
1899 rv = callback.WaitForResult();
1900 EXPECT_EQ(OK, rv);
1901 const HttpResponseInfo* response = trans->GetResponseInfo();
1902 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501903 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501904 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1905 std::string response_data;
1906 rv = ReadTransaction(trans.get(), &response_data);
1907 EXPECT_EQ(OK, rv);
1908 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131909}
1910
[email protected]038e9a32008-10-08 22:40:161911// Test the request-challenge-retry sequence for basic auth.
1912// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021913TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421914 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161915 request.method = "GET";
bncce36dca22015-04-21 22:11:231916 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161917 request.load_flags = 0;
1918
vishal.b62985ca92015-04-17 08:45:511919 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071920 session_deps_.net_log = &log;
mmenkee65e7af2015-10-13 17:16:421921 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271922 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411923 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271924
[email protected]f9ee6b52008-11-08 06:46:231925 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231926 MockWrite(
1927 "GET / HTTP/1.1\r\n"
1928 "Host: www.example.org\r\n"
1929 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231930 };
1931
[email protected]038e9a32008-10-08 22:40:161932 MockRead data_reads1[] = {
1933 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1934 // Give a couple authenticate options (only the middle one is actually
1935 // supported).
[email protected]22927ad2009-09-21 19:56:191936 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161937 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1938 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1939 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1940 // Large content-length -- won't matter, as connection will be reset.
1941 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061942 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161943 };
1944
1945 // After calling trans->RestartWithAuth(), this is the request we should
1946 // be issuing -- the final header line contains the credentials.
1947 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:231948 MockWrite(
1949 "GET / HTTP/1.1\r\n"
1950 "Host: www.example.org\r\n"
1951 "Connection: keep-alive\r\n"
1952 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:161953 };
1954
1955 // Lastly, the server responds with the actual content.
1956 MockRead data_reads2[] = {
1957 MockRead("HTTP/1.0 200 OK\r\n"),
1958 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1959 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061960 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161961 };
1962
[email protected]31a2bfe2010-02-09 08:03:391963 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1964 data_writes1, arraysize(data_writes1));
1965 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1966 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071967 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1968 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161969
[email protected]49639fa2011-12-20 23:22:411970 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161971
[email protected]49639fa2011-12-20 23:22:411972 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421973 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161974
1975 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421976 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161977
[email protected]58e32bb2013-01-21 18:23:251978 LoadTimingInfo load_timing_info1;
1979 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1980 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1981
sclittlefb249892015-09-10 21:33:221982 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
1983 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
1984 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:191985 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1986
[email protected]1c773ea12009-04-28 19:58:421987 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501988 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041989 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161990
[email protected]49639fa2011-12-20 23:22:411991 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161992
[email protected]49639fa2011-12-20 23:22:411993 rv = trans->RestartWithAuth(
1994 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421995 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161996
1997 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421998 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161999
[email protected]58e32bb2013-01-21 18:23:252000 LoadTimingInfo load_timing_info2;
2001 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2002 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2003 // The load timing after restart should have a new socket ID, and times after
2004 // those of the first load timing.
2005 EXPECT_LE(load_timing_info1.receive_headers_end,
2006 load_timing_info2.connect_timing.connect_start);
2007 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2008
sclittlefb249892015-09-10 21:33:222009 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2010 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2011 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
[email protected]b8015c42013-12-24 15:18:192012 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2013
[email protected]038e9a32008-10-08 22:40:162014 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502015 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:162016 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2017 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162018}
2019
ttuttled9dbc652015-09-29 20:00:592020// Test the request-challenge-retry sequence for basic auth.
2021// (basic auth is the easiest to mock, because it has no randomness).
2022TEST_P(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
2023 HttpRequestInfo request;
2024 request.method = "GET";
2025 request.url = GURL("http://www.example.org/");
2026 request.load_flags = 0;
2027
2028 TestNetLog log;
2029 MockHostResolver* resolver = new MockHostResolver();
2030 session_deps_.net_log = &log;
2031 session_deps_.host_resolver.reset(resolver);
mmenkee65e7af2015-10-13 17:16:422032 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
ttuttled9dbc652015-09-29 20:00:592033 scoped_ptr<HttpTransaction> trans(
2034 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2035
2036 resolver->rules()->ClearRules();
2037 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2038
2039 MockWrite data_writes1[] = {
2040 MockWrite("GET / HTTP/1.1\r\n"
2041 "Host: www.example.org\r\n"
2042 "Connection: keep-alive\r\n\r\n"),
2043 };
2044
2045 MockRead data_reads1[] = {
2046 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2047 // Give a couple authenticate options (only the middle one is actually
2048 // supported).
2049 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2050 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2051 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2052 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2053 // Large content-length -- won't matter, as connection will be reset.
2054 MockRead("Content-Length: 10000\r\n\r\n"),
2055 MockRead(SYNCHRONOUS, ERR_FAILED),
2056 };
2057
2058 // After calling trans->RestartWithAuth(), this is the request we should
2059 // be issuing -- the final header line contains the credentials.
2060 MockWrite data_writes2[] = {
2061 MockWrite("GET / HTTP/1.1\r\n"
2062 "Host: www.example.org\r\n"
2063 "Connection: keep-alive\r\n"
2064 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2065 };
2066
2067 // Lastly, the server responds with the actual content.
2068 MockRead data_reads2[] = {
2069 MockRead("HTTP/1.0 200 OK\r\n"),
2070 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2071 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2072 };
2073
2074 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2075 data_writes1, arraysize(data_writes1));
2076 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2077 data_writes2, arraysize(data_writes2));
2078 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2079 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2080
2081 TestCompletionCallback callback1;
2082
2083 EXPECT_EQ(OK, callback1.GetResult(trans->Start(&request, callback1.callback(),
2084 BoundNetLog())));
2085
2086 LoadTimingInfo load_timing_info1;
2087 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2088 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2089
2090 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2091 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2092 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
2093 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2094
2095 const HttpResponseInfo* response = trans->GetResponseInfo();
2096 ASSERT_TRUE(response);
2097 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2098
2099 IPEndPoint endpoint;
2100 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2101 ASSERT_FALSE(endpoint.address().empty());
2102 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2103
2104 resolver->rules()->ClearRules();
2105 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2106
2107 TestCompletionCallback callback2;
2108
2109 EXPECT_EQ(OK, callback2.GetResult(trans->RestartWithAuth(
2110 AuthCredentials(kFoo, kBar), callback2.callback())));
2111
2112 LoadTimingInfo load_timing_info2;
2113 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2114 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2115 // The load timing after restart should have a new socket ID, and times after
2116 // those of the first load timing.
2117 EXPECT_LE(load_timing_info1.receive_headers_end,
2118 load_timing_info2.connect_timing.connect_start);
2119 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2120
2121 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2122 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2123 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
2124 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2125
2126 response = trans->GetResponseInfo();
2127 ASSERT_TRUE(response);
2128 EXPECT_FALSE(response->auth_challenge.get());
2129 EXPECT_EQ(100, response->headers->GetContentLength());
2130
2131 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2132 ASSERT_FALSE(endpoint.address().empty());
2133 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2134}
2135
[email protected]23e482282013-06-14 16:08:022136TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462137 HttpRequestInfo request;
2138 request.method = "GET";
bncce36dca22015-04-21 22:11:232139 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292140 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462141
mmenkee65e7af2015-10-13 17:16:422142 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272143 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412144 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272145
[email protected]861fcd52009-08-26 02:33:462146 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232147 MockWrite(
2148 "GET / HTTP/1.1\r\n"
2149 "Host: www.example.org\r\n"
2150 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462151 };
2152
2153 MockRead data_reads[] = {
2154 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2155 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2156 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2157 // Large content-length -- won't matter, as connection will be reset.
2158 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062159 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462160 };
2161
[email protected]31a2bfe2010-02-09 08:03:392162 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2163 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072164 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412165 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462166
[email protected]49639fa2011-12-20 23:22:412167 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462168 EXPECT_EQ(ERR_IO_PENDING, rv);
2169
2170 rv = callback.WaitForResult();
2171 EXPECT_EQ(0, rv);
2172
sclittlefb249892015-09-10 21:33:222173 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2174 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2175 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
[email protected]b8015c42013-12-24 15:18:192176 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2177
[email protected]861fcd52009-08-26 02:33:462178 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502179 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462180 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2181}
2182
[email protected]2d2697f92009-02-18 21:00:322183// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2184// connection.
[email protected]23e482282013-06-14 16:08:022185TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422186 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322187 request.method = "GET";
bncce36dca22015-04-21 22:11:232188 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322189 request.load_flags = 0;
2190
vishal.b62985ca92015-04-17 08:45:512191 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072192 session_deps_.net_log = &log;
mmenkee65e7af2015-10-13 17:16:422193 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272194
[email protected]2d2697f92009-02-18 21:00:322195 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232196 MockWrite(
2197 "GET / HTTP/1.1\r\n"
2198 "Host: www.example.org\r\n"
2199 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322200
bncce36dca22015-04-21 22:11:232201 // After calling trans->RestartWithAuth(), this is the request we should
2202 // be issuing -- the final header line contains the credentials.
2203 MockWrite(
2204 "GET / HTTP/1.1\r\n"
2205 "Host: www.example.org\r\n"
2206 "Connection: keep-alive\r\n"
2207 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322208 };
2209
2210 MockRead data_reads1[] = {
2211 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2212 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2213 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2214 MockRead("Content-Length: 14\r\n\r\n"),
2215 MockRead("Unauthorized\r\n"),
2216
2217 // Lastly, the server responds with the actual content.
2218 MockRead("HTTP/1.1 200 OK\r\n"),
2219 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502220 MockRead("Content-Length: 5\r\n\r\n"),
2221 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322222 };
2223
[email protected]2d0a4f92011-05-05 16:38:462224 // If there is a regression where we disconnect a Keep-Alive
2225 // connection during an auth roundtrip, we'll end up reading this.
2226 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062227 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462228 };
2229
[email protected]31a2bfe2010-02-09 08:03:392230 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2231 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462232 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2233 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072234 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2235 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322236
[email protected]49639fa2011-12-20 23:22:412237 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322238
[email protected]262eec82013-03-19 21:01:362239 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502240 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412241 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422242 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322243
2244 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422245 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322246
[email protected]58e32bb2013-01-21 18:23:252247 LoadTimingInfo load_timing_info1;
2248 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2249 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2250
[email protected]1c773ea12009-04-28 19:58:422251 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502252 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042253 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322254
[email protected]49639fa2011-12-20 23:22:412255 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322256
[email protected]49639fa2011-12-20 23:22:412257 rv = trans->RestartWithAuth(
2258 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422259 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322260
2261 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422262 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322263
[email protected]58e32bb2013-01-21 18:23:252264 LoadTimingInfo load_timing_info2;
2265 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2266 TestLoadTimingReused(load_timing_info2);
2267 // The load timing after restart should have the same socket ID, and times
2268 // those of the first load timing.
2269 EXPECT_LE(load_timing_info1.receive_headers_end,
2270 load_timing_info2.send_start);
2271 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2272
[email protected]2d2697f92009-02-18 21:00:322273 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502274 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322275 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502276 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192277
2278 std::string response_data;
2279 rv = ReadTransaction(trans.get(), &response_data);
2280 EXPECT_EQ(OK, rv);
sclittlefb249892015-09-10 21:33:222281
2282 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2283 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2284 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:192285 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322286}
2287
2288// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2289// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022290TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422291 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322292 request.method = "GET";
bncce36dca22015-04-21 22:11:232293 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322294 request.load_flags = 0;
2295
mmenkee65e7af2015-10-13 17:16:422296 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272297
[email protected]2d2697f92009-02-18 21:00:322298 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232299 MockWrite(
2300 "GET / HTTP/1.1\r\n"
2301 "Host: www.example.org\r\n"
2302 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322303
bncce36dca22015-04-21 22:11:232304 // After calling trans->RestartWithAuth(), this is the request we should
2305 // be issuing -- the final header line contains the credentials.
2306 MockWrite(
2307 "GET / HTTP/1.1\r\n"
2308 "Host: www.example.org\r\n"
2309 "Connection: keep-alive\r\n"
2310 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322311 };
2312
[email protected]2d2697f92009-02-18 21:00:322313 MockRead data_reads1[] = {
2314 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2315 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312316 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322317
2318 // Lastly, the server responds with the actual content.
2319 MockRead("HTTP/1.1 200 OK\r\n"),
2320 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502321 MockRead("Content-Length: 5\r\n\r\n"),
2322 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322323 };
2324
[email protected]2d0a4f92011-05-05 16:38:462325 // An incorrect reconnect would cause this to be read.
2326 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062327 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462328 };
2329
[email protected]31a2bfe2010-02-09 08:03:392330 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2331 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462332 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2333 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072334 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2335 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322336
[email protected]49639fa2011-12-20 23:22:412337 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322338
[email protected]262eec82013-03-19 21:01:362339 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502340 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412341 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422342 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322343
2344 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422345 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322346
[email protected]1c773ea12009-04-28 19:58:422347 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502348 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042349 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322350
[email protected]49639fa2011-12-20 23:22:412351 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322352
[email protected]49639fa2011-12-20 23:22:412353 rv = trans->RestartWithAuth(
2354 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422355 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322356
2357 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422358 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322359
2360 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502361 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322362 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502363 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322364}
2365
2366// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2367// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022368TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422369 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322370 request.method = "GET";
bncce36dca22015-04-21 22:11:232371 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322372 request.load_flags = 0;
2373
mmenkee65e7af2015-10-13 17:16:422374 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272375
[email protected]2d2697f92009-02-18 21:00:322376 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232377 MockWrite(
2378 "GET / HTTP/1.1\r\n"
2379 "Host: www.example.org\r\n"
2380 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322381
bncce36dca22015-04-21 22:11:232382 // After calling trans->RestartWithAuth(), this is the request we should
2383 // be issuing -- the final header line contains the credentials.
2384 MockWrite(
2385 "GET / HTTP/1.1\r\n"
2386 "Host: www.example.org\r\n"
2387 "Connection: keep-alive\r\n"
2388 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322389 };
2390
2391 // Respond with 5 kb of response body.
2392 std::string large_body_string("Unauthorized");
2393 large_body_string.append(5 * 1024, ' ');
2394 large_body_string.append("\r\n");
2395
2396 MockRead data_reads1[] = {
2397 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2398 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2399 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2400 // 5134 = 12 + 5 * 1024 + 2
2401 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062402 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322403
2404 // Lastly, the server responds with the actual content.
2405 MockRead("HTTP/1.1 200 OK\r\n"),
2406 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502407 MockRead("Content-Length: 5\r\n\r\n"),
2408 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322409 };
2410
[email protected]2d0a4f92011-05-05 16:38:462411 // An incorrect reconnect would cause this to be read.
2412 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062413 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462414 };
2415
[email protected]31a2bfe2010-02-09 08:03:392416 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2417 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462418 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2419 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072420 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2421 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322422
[email protected]49639fa2011-12-20 23:22:412423 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322424
[email protected]262eec82013-03-19 21:01:362425 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502426 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412427 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422428 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322429
2430 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422431 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322432
[email protected]1c773ea12009-04-28 19:58:422433 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502434 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042435 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322436
[email protected]49639fa2011-12-20 23:22:412437 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322438
[email protected]49639fa2011-12-20 23:22:412439 rv = trans->RestartWithAuth(
2440 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422441 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322442
2443 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422444 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322445
2446 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502447 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322448 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502449 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322450}
2451
2452// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312453// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022454TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312455 HttpRequestInfo request;
2456 request.method = "GET";
bncce36dca22015-04-21 22:11:232457 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312458 request.load_flags = 0;
2459
mmenkee65e7af2015-10-13 17:16:422460 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272461
[email protected]11203f012009-11-12 23:02:312462 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232463 MockWrite(
2464 "GET / HTTP/1.1\r\n"
2465 "Host: www.example.org\r\n"
2466 "Connection: keep-alive\r\n\r\n"),
2467 // This simulates the seemingly successful write to a closed connection
2468 // if the bug is not fixed.
2469 MockWrite(
2470 "GET / HTTP/1.1\r\n"
2471 "Host: www.example.org\r\n"
2472 "Connection: keep-alive\r\n"
2473 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312474 };
2475
2476 MockRead data_reads1[] = {
2477 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2478 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2479 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2480 MockRead("Content-Length: 14\r\n\r\n"),
2481 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062482 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312483 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062484 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312485 };
2486
2487 // After calling trans->RestartWithAuth(), this is the request we should
2488 // be issuing -- the final header line contains the credentials.
2489 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232490 MockWrite(
2491 "GET / HTTP/1.1\r\n"
2492 "Host: www.example.org\r\n"
2493 "Connection: keep-alive\r\n"
2494 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312495 };
2496
2497 // Lastly, the server responds with the actual content.
2498 MockRead data_reads2[] = {
2499 MockRead("HTTP/1.1 200 OK\r\n"),
2500 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502501 MockRead("Content-Length: 5\r\n\r\n"),
2502 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312503 };
2504
[email protected]31a2bfe2010-02-09 08:03:392505 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2506 data_writes1, arraysize(data_writes1));
2507 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2508 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072509 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2510 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312511
[email protected]49639fa2011-12-20 23:22:412512 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312513
[email protected]262eec82013-03-19 21:01:362514 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502515 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412516 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312517 EXPECT_EQ(ERR_IO_PENDING, rv);
2518
2519 rv = callback1.WaitForResult();
2520 EXPECT_EQ(OK, rv);
2521
2522 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502523 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042524 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312525
[email protected]49639fa2011-12-20 23:22:412526 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312527
[email protected]49639fa2011-12-20 23:22:412528 rv = trans->RestartWithAuth(
2529 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312530 EXPECT_EQ(ERR_IO_PENDING, rv);
2531
2532 rv = callback2.WaitForResult();
2533 EXPECT_EQ(OK, rv);
2534
2535 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502536 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312537 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502538 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312539}
2540
[email protected]394816e92010-08-03 07:38:592541// Test the request-challenge-retry sequence for basic auth, over a connection
2542// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012543TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2544 HttpRequestInfo request;
2545 request.method = "GET";
bncce36dca22015-04-21 22:11:232546 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012547 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292548 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012549
2550 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032551 session_deps_.proxy_service =
2552 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512553 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012554 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422555 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012556
2557 // Since we have proxy, should try to establish tunnel.
2558 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542559 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2560 "Host: www.example.org\r\n"
2561 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012562 };
2563
mmenkee71e15332015-10-07 16:39:542564 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012565 // connection.
2566 MockRead data_reads1[] = {
2567 // No credentials.
2568 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2569 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542570 };
ttuttle34f63b52015-03-05 04:33:012571
mmenkee71e15332015-10-07 16:39:542572 // Since the first connection couldn't be reused, need to establish another
2573 // once given credentials.
2574 MockWrite data_writes2[] = {
2575 // After calling trans->RestartWithAuth(), this is the request we should
2576 // be issuing -- the final header line contains the credentials.
2577 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2578 "Host: www.example.org\r\n"
2579 "Proxy-Connection: keep-alive\r\n"
2580 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2581
2582 MockWrite("GET / HTTP/1.1\r\n"
2583 "Host: www.example.org\r\n"
2584 "Connection: keep-alive\r\n\r\n"),
2585 };
2586
2587 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012588 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2589
2590 MockRead("HTTP/1.1 200 OK\r\n"),
2591 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2592 MockRead("Content-Length: 5\r\n\r\n"),
2593 MockRead(SYNCHRONOUS, "hello"),
2594 };
2595
2596 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2597 data_writes1, arraysize(data_writes1));
2598 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542599 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2600 data_writes2, arraysize(data_writes2));
2601 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012602 SSLSocketDataProvider ssl(ASYNC, OK);
2603 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2604
2605 TestCompletionCallback callback1;
2606
2607 scoped_ptr<HttpTransaction> trans(
2608 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2609
2610 int rv = trans->Start(&request, callback1.callback(), log.bound());
2611 EXPECT_EQ(ERR_IO_PENDING, rv);
2612
2613 rv = callback1.WaitForResult();
2614 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462615 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012616 log.GetEntries(&entries);
2617 size_t pos = ExpectLogContainsSomewhere(
2618 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2619 NetLog::PHASE_NONE);
2620 ExpectLogContainsSomewhere(
2621 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2622 NetLog::PHASE_NONE);
2623
2624 const HttpResponseInfo* response = trans->GetResponseInfo();
2625 ASSERT_TRUE(response != NULL);
2626 EXPECT_FALSE(response->headers->IsKeepAlive());
2627 ASSERT_FALSE(response->headers.get() == NULL);
2628 EXPECT_EQ(407, response->headers->response_code());
2629 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2630 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2631
2632 LoadTimingInfo load_timing_info;
2633 // CONNECT requests and responses are handled at the connect job level, so
2634 // the transaction does not yet have a connection.
2635 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2636
2637 TestCompletionCallback callback2;
2638
2639 rv =
2640 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2641 EXPECT_EQ(ERR_IO_PENDING, rv);
2642
2643 rv = callback2.WaitForResult();
2644 EXPECT_EQ(OK, rv);
2645
2646 response = trans->GetResponseInfo();
2647 ASSERT_TRUE(response != NULL);
2648
2649 EXPECT_TRUE(response->headers->IsKeepAlive());
2650 EXPECT_EQ(200, response->headers->response_code());
2651 EXPECT_EQ(5, response->headers->GetContentLength());
2652 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2653
2654 // The password prompt info should not be set.
2655 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2656
2657 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2658 TestLoadTimingNotReusedWithPac(load_timing_info,
2659 CONNECT_TIMING_HAS_SSL_TIMES);
2660
2661 trans.reset();
2662 session->CloseAllConnections();
2663}
2664
2665// Test the request-challenge-retry sequence for basic auth, over a connection
2666// that requires a restart when setting up an SSL tunnel.
2667TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592668 HttpRequestInfo request;
2669 request.method = "GET";
bncce36dca22015-04-21 22:11:232670 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592671 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292672 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592673
[email protected]cb9bf6ca2011-01-28 13:15:272674 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032675 session_deps_.proxy_service =
2676 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512677 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072678 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422679 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272680
[email protected]394816e92010-08-03 07:38:592681 // Since we have proxy, should try to establish tunnel.
2682 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542683 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2684 "Host: www.example.org\r\n"
2685 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:112686 };
2687
mmenkee71e15332015-10-07 16:39:542688 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:082689 // connection.
2690 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:542691 // No credentials.
2692 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2693 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2694 MockRead("Proxy-Connection: close\r\n\r\n"),
2695 };
mmenkee0b5c882015-08-26 20:29:112696
mmenkee71e15332015-10-07 16:39:542697 MockWrite data_writes2[] = {
2698 // After calling trans->RestartWithAuth(), this is the request we should
2699 // be issuing -- the final header line contains the credentials.
2700 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2701 "Host: www.example.org\r\n"
2702 "Proxy-Connection: keep-alive\r\n"
2703 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:082704
mmenkee71e15332015-10-07 16:39:542705 MockWrite("GET / HTTP/1.1\r\n"
2706 "Host: www.example.org\r\n"
2707 "Connection: keep-alive\r\n\r\n"),
2708 };
2709
2710 MockRead data_reads2[] = {
2711 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2712
2713 MockRead("HTTP/1.1 200 OK\r\n"),
2714 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2715 MockRead("Content-Length: 5\r\n\r\n"),
2716 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592717 };
2718
2719 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2720 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072721 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542722 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2723 data_writes2, arraysize(data_writes2));
2724 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:062725 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072726 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592727
[email protected]49639fa2011-12-20 23:22:412728 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592729
[email protected]262eec82013-03-19 21:01:362730 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502731 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502732
[email protected]49639fa2011-12-20 23:22:412733 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592734 EXPECT_EQ(ERR_IO_PENDING, rv);
2735
2736 rv = callback1.WaitForResult();
2737 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462738 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402739 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592740 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402741 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592742 NetLog::PHASE_NONE);
2743 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402744 entries, pos,
[email protected]394816e92010-08-03 07:38:592745 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2746 NetLog::PHASE_NONE);
2747
2748 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502749 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012750 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502751 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592752 EXPECT_EQ(407, response->headers->response_code());
2753 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042754 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592755
[email protected]029c83b62013-01-24 05:28:202756 LoadTimingInfo load_timing_info;
2757 // CONNECT requests and responses are handled at the connect job level, so
2758 // the transaction does not yet have a connection.
2759 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2760
[email protected]49639fa2011-12-20 23:22:412761 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592762
[email protected]49639fa2011-12-20 23:22:412763 rv = trans->RestartWithAuth(
2764 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592765 EXPECT_EQ(ERR_IO_PENDING, rv);
2766
2767 rv = callback2.WaitForResult();
2768 EXPECT_EQ(OK, rv);
2769
2770 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502771 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592772
2773 EXPECT_TRUE(response->headers->IsKeepAlive());
2774 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502775 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592776 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2777
2778 // The password prompt info should not be set.
2779 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502780
[email protected]029c83b62013-01-24 05:28:202781 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2782 TestLoadTimingNotReusedWithPac(load_timing_info,
2783 CONNECT_TIMING_HAS_SSL_TIMES);
2784
[email protected]0b0bf032010-09-21 18:08:502785 trans.reset();
[email protected]102e27c2011-02-23 01:01:312786 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592787}
2788
[email protected]11203f012009-11-12 23:02:312789// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012790// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2791TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2792 HttpRequestInfo request;
2793 request.method = "GET";
bncce36dca22015-04-21 22:11:232794 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012795 // Ensure that proxy authentication is attempted even
2796 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292797 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012798
2799 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032800 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:512801 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012802 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422803 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012804
2805 scoped_ptr<HttpTransaction> trans(
2806 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2807
2808 // Since we have proxy, should try to establish tunnel.
2809 MockWrite data_writes1[] = {
2810 MockWrite(
bncce36dca22015-04-21 22:11:232811 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2812 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012813 "Proxy-Connection: keep-alive\r\n\r\n"),
2814
2815 // After calling trans->RestartWithAuth(), this is the request we should
2816 // be issuing -- the final header line contains the credentials.
2817 MockWrite(
bncce36dca22015-04-21 22:11:232818 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2819 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012820 "Proxy-Connection: keep-alive\r\n"
2821 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2822 };
2823
2824 // The proxy responds to the connect with a 407, using a persistent
2825 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2826 MockRead data_reads1[] = {
2827 // No credentials.
2828 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2829 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2830 MockRead("Proxy-Connection: keep-alive\r\n"),
2831 MockRead("Content-Length: 10\r\n\r\n"),
2832 MockRead("0123456789"),
2833
2834 // Wrong credentials (wrong password).
2835 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2836 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2837 MockRead("Proxy-Connection: keep-alive\r\n"),
2838 MockRead("Content-Length: 10\r\n\r\n"),
2839 // No response body because the test stops reading here.
2840 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2841 };
2842
2843 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2844 data_writes1, arraysize(data_writes1));
2845 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2846
2847 TestCompletionCallback callback1;
2848
2849 int rv = trans->Start(&request, callback1.callback(), log.bound());
2850 EXPECT_EQ(ERR_IO_PENDING, rv);
2851
2852 rv = callback1.WaitForResult();
2853 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462854 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012855 log.GetEntries(&entries);
2856 size_t pos = ExpectLogContainsSomewhere(
2857 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2858 NetLog::PHASE_NONE);
2859 ExpectLogContainsSomewhere(
2860 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2861 NetLog::PHASE_NONE);
2862
2863 const HttpResponseInfo* response = trans->GetResponseInfo();
2864 ASSERT_TRUE(response);
2865 ASSERT_TRUE(response->headers);
2866 EXPECT_TRUE(response->headers->IsKeepAlive());
2867 EXPECT_EQ(407, response->headers->response_code());
2868 EXPECT_EQ(10, response->headers->GetContentLength());
2869 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2870 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2871
2872 TestCompletionCallback callback2;
2873
2874 // Wrong password (should be "bar").
2875 rv =
2876 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2877 EXPECT_EQ(ERR_IO_PENDING, rv);
2878
2879 rv = callback2.WaitForResult();
2880 EXPECT_EQ(OK, rv);
2881
2882 response = trans->GetResponseInfo();
2883 ASSERT_TRUE(response);
2884 ASSERT_TRUE(response->headers);
2885 EXPECT_TRUE(response->headers->IsKeepAlive());
2886 EXPECT_EQ(407, response->headers->response_code());
2887 EXPECT_EQ(10, response->headers->GetContentLength());
2888 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2889 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2890
2891 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2892 // out of scope.
2893 session->CloseAllConnections();
2894}
2895
2896// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2897// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2898TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272899 HttpRequestInfo request;
2900 request.method = "GET";
bncce36dca22015-04-21 22:11:232901 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272902 // Ensure that proxy authentication is attempted even
2903 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292904 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:272905
[email protected]2d2697f92009-02-18 21:00:322906 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032907 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:512908 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072909 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422910 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322911
[email protected]262eec82013-03-19 21:01:362912 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502913 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322914
[email protected]2d2697f92009-02-18 21:00:322915 // Since we have proxy, should try to establish tunnel.
2916 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232917 MockWrite(
2918 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2919 "Host: www.example.org\r\n"
2920 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322921
bncce36dca22015-04-21 22:11:232922 // After calling trans->RestartWithAuth(), this is the request we should
2923 // be issuing -- the final header line contains the credentials.
2924 MockWrite(
2925 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2926 "Host: www.example.org\r\n"
2927 "Proxy-Connection: keep-alive\r\n"
2928 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322929 };
2930
2931 // The proxy responds to the connect with a 407, using a persistent
2932 // connection.
2933 MockRead data_reads1[] = {
2934 // No credentials.
2935 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2936 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2937 MockRead("Content-Length: 10\r\n\r\n"),
2938 MockRead("0123456789"),
2939
2940 // Wrong credentials (wrong password).
2941 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2942 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2943 MockRead("Content-Length: 10\r\n\r\n"),
2944 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062945 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322946 };
2947
[email protected]31a2bfe2010-02-09 08:03:392948 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2949 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072950 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322951
[email protected]49639fa2011-12-20 23:22:412952 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322953
[email protected]49639fa2011-12-20 23:22:412954 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422955 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322956
2957 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422958 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462959 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402960 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392961 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402962 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392963 NetLog::PHASE_NONE);
2964 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402965 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392966 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2967 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322968
[email protected]1c773ea12009-04-28 19:58:422969 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242970 ASSERT_TRUE(response);
2971 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322972 EXPECT_TRUE(response->headers->IsKeepAlive());
2973 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012974 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422975 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042976 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322977
[email protected]49639fa2011-12-20 23:22:412978 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322979
2980 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412981 rv = trans->RestartWithAuth(
2982 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422983 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322984
2985 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422986 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322987
2988 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242989 ASSERT_TRUE(response);
2990 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322991 EXPECT_TRUE(response->headers->IsKeepAlive());
2992 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012993 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422994 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042995 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132996
[email protected]e60e47a2010-07-14 03:37:182997 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2998 // out of scope.
[email protected]102e27c2011-02-23 01:01:312999 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323000}
3001
mmenkee71e15332015-10-07 16:39:543002// Test the case a proxy closes a socket while the challenge body is being
3003// drained.
3004TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
3005 HttpRequestInfo request;
3006 request.method = "GET";
3007 request.url = GURL("https://www.example.org/");
3008 // Ensure that proxy authentication is attempted even
3009 // when the no authentication data flag is set.
3010 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3011
3012 // Configure against proxy server "myproxy:70".
3013 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:423014 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543015
3016 scoped_ptr<HttpTransaction> trans(
3017 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3018
3019 // Since we have proxy, should try to establish tunnel.
3020 MockWrite data_writes1[] = {
3021 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3022 "Host: www.example.org\r\n"
3023 "Proxy-Connection: keep-alive\r\n\r\n"),
3024 };
3025
3026 // The proxy responds to the connect with a 407, using a persistent
3027 // connection.
3028 MockRead data_reads1[] = {
3029 // No credentials.
3030 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3031 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3032 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3033 // Server hands up in the middle of the body.
3034 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3035 };
3036
3037 MockWrite data_writes2[] = {
3038 // After calling trans->RestartWithAuth(), this is the request we should
3039 // be issuing -- the final header line contains the credentials.
3040 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3041 "Host: www.example.org\r\n"
3042 "Proxy-Connection: keep-alive\r\n"
3043 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3044
3045 MockWrite("GET / HTTP/1.1\r\n"
3046 "Host: www.example.org\r\n"
3047 "Connection: keep-alive\r\n\r\n"),
3048 };
3049
3050 MockRead data_reads2[] = {
3051 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3052
3053 MockRead("HTTP/1.1 200 OK\r\n"),
3054 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3055 MockRead("Content-Length: 5\r\n\r\n"),
3056 MockRead(SYNCHRONOUS, "hello"),
3057 };
3058
3059 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3060 data_writes1, arraysize(data_writes1));
3061 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3062 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3063 data_writes2, arraysize(data_writes2));
3064 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3065 SSLSocketDataProvider ssl(ASYNC, OK);
3066 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3067
3068 TestCompletionCallback callback;
3069
3070 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3071 EXPECT_EQ(OK, callback.GetResult(rv));
3072
3073 const HttpResponseInfo* response = trans->GetResponseInfo();
3074 ASSERT_TRUE(response);
3075 ASSERT_TRUE(response->headers);
3076 EXPECT_TRUE(response->headers->IsKeepAlive());
3077 EXPECT_EQ(407, response->headers->response_code());
3078 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3079
3080 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
3081 EXPECT_EQ(OK, callback.GetResult(rv));
3082
3083 response = trans->GetResponseInfo();
3084 ASSERT_TRUE(response);
3085 ASSERT_TRUE(response->headers);
3086 EXPECT_TRUE(response->headers->IsKeepAlive());
3087 EXPECT_EQ(200, response->headers->response_code());
3088 std::string body;
3089 EXPECT_EQ(OK, ReadTransaction(trans.get(), &body));
3090 EXPECT_EQ("hello", body);
3091}
3092
[email protected]a8e9b162009-03-12 00:06:443093// Test that we don't read the response body when we fail to establish a tunnel,
3094// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:023095TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273096 HttpRequestInfo request;
3097 request.method = "GET";
bncce36dca22015-04-21 22:11:233098 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273099 request.load_flags = 0;
3100
[email protected]a8e9b162009-03-12 00:06:443101 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033102 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443103
mmenkee65e7af2015-10-13 17:16:423104 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443105
[email protected]262eec82013-03-19 21:01:363106 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503107 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:443108
[email protected]a8e9b162009-03-12 00:06:443109 // Since we have proxy, should try to establish tunnel.
3110 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:233111 MockWrite(
3112 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3113 "Host: www.example.org\r\n"
3114 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443115 };
3116
3117 // The proxy responds to the connect with a 407.
3118 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243119 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3120 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3121 MockRead("Content-Length: 10\r\n\r\n"),
3122 MockRead("0123456789"), // Should not be reached.
3123 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443124 };
3125
[email protected]31a2bfe2010-02-09 08:03:393126 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3127 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073128 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443129
[email protected]49639fa2011-12-20 23:22:413130 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443131
[email protected]49639fa2011-12-20 23:22:413132 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423133 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:443134
3135 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423136 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:443137
[email protected]1c773ea12009-04-28 19:58:423138 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243139 ASSERT_TRUE(response);
3140 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443141 EXPECT_TRUE(response->headers->IsKeepAlive());
3142 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423143 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443144
3145 std::string response_data;
3146 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423147 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:183148
3149 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313150 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443151}
3152
ttuttle7933c112015-01-06 00:55:243153// Test that we don't pass extraneous headers from the proxy's response to the
3154// caller when the proxy responds to CONNECT with 407.
3155TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
3156 HttpRequestInfo request;
3157 request.method = "GET";
bncce36dca22015-04-21 22:11:233158 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243159 request.load_flags = 0;
3160
3161 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033162 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243163
mmenkee65e7af2015-10-13 17:16:423164 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243165
3166 scoped_ptr<HttpTransaction> trans(
3167 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3168
3169 // Since we have proxy, should try to establish tunnel.
3170 MockWrite data_writes[] = {
3171 MockWrite(
bncce36dca22015-04-21 22:11:233172 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3173 "Host: www.example.org\r\n"
ttuttle7933c112015-01-06 00:55:243174 "Proxy-Connection: keep-alive\r\n\r\n"),
3175 };
3176
3177 // The proxy responds to the connect with a 407.
3178 MockRead data_reads[] = {
3179 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3180 MockRead("X-Foo: bar\r\n"),
3181 MockRead("Set-Cookie: foo=bar\r\n"),
3182 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3183 MockRead("Content-Length: 10\r\n\r\n"),
3184 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
3185 };
3186
3187 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3188 arraysize(data_writes));
3189 session_deps_.socket_factory->AddSocketDataProvider(&data);
3190
3191 TestCompletionCallback callback;
3192
3193 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3194 EXPECT_EQ(ERR_IO_PENDING, rv);
3195
3196 rv = callback.WaitForResult();
3197 EXPECT_EQ(OK, rv);
3198
3199 const HttpResponseInfo* response = trans->GetResponseInfo();
3200 ASSERT_TRUE(response);
3201 ASSERT_TRUE(response->headers);
3202 EXPECT_TRUE(response->headers->IsKeepAlive());
3203 EXPECT_EQ(407, response->headers->response_code());
3204 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3205 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3206 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3207
3208 std::string response_data;
3209 rv = ReadTransaction(trans.get(), &response_data);
3210 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3211
3212 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3213 session->CloseAllConnections();
3214}
3215
[email protected]8fdbcd22010-05-05 02:54:523216// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3217// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:023218TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523219 HttpRequestInfo request;
3220 request.method = "GET";
bncce36dca22015-04-21 22:11:233221 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523222 request.load_flags = 0;
3223
[email protected]cb9bf6ca2011-01-28 13:15:273224 // We are using a DIRECT connection (i.e. no proxy) for this session.
mmenkee65e7af2015-10-13 17:16:423225 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273226 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:413227 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:273228
[email protected]8fdbcd22010-05-05 02:54:523229 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233230 MockWrite(
3231 "GET / HTTP/1.1\r\n"
3232 "Host: www.example.org\r\n"
3233 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523234 };
3235
3236 MockRead data_reads1[] = {
3237 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3238 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3239 // Large content-length -- won't matter, as connection will be reset.
3240 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063241 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523242 };
3243
3244 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3245 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073246 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523247
[email protected]49639fa2011-12-20 23:22:413248 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523249
[email protected]49639fa2011-12-20 23:22:413250 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523251 EXPECT_EQ(ERR_IO_PENDING, rv);
3252
3253 rv = callback.WaitForResult();
3254 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3255}
3256
[email protected]7a67a8152010-11-05 18:31:103257// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3258// through a non-authenticating proxy. The request should fail with
3259// ERR_UNEXPECTED_PROXY_AUTH.
3260// Note that it is impossible to detect if an HTTP server returns a 407 through
3261// a non-authenticating proxy - there is nothing to indicate whether the
3262// response came from the proxy or the server, so it is treated as if the proxy
3263// issued the challenge.
[email protected]23e482282013-06-14 16:08:023264TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233265 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273266 HttpRequestInfo request;
3267 request.method = "GET";
bncce36dca22015-04-21 22:11:233268 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273269
rdsmith82957ad2015-09-16 19:42:033270 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513271 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073272 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423273 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103274
[email protected]7a67a8152010-11-05 18:31:103275 // Since we have proxy, should try to establish tunnel.
3276 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233277 MockWrite(
3278 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3279 "Host: www.example.org\r\n"
3280 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103281
bncce36dca22015-04-21 22:11:233282 MockWrite(
3283 "GET / HTTP/1.1\r\n"
3284 "Host: www.example.org\r\n"
3285 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103286 };
3287
3288 MockRead data_reads1[] = {
3289 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3290
3291 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3292 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3293 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063294 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103295 };
3296
3297 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3298 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073299 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063300 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073301 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103302
[email protected]49639fa2011-12-20 23:22:413303 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103304
[email protected]262eec82013-03-19 21:01:363305 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103307
[email protected]49639fa2011-12-20 23:22:413308 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103309 EXPECT_EQ(ERR_IO_PENDING, rv);
3310
3311 rv = callback1.WaitForResult();
3312 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463313 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403314 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103315 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403316 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103317 NetLog::PHASE_NONE);
3318 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403319 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103320 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3321 NetLog::PHASE_NONE);
3322}
[email protected]2df19bb2010-08-25 20:13:463323
mmenke2a1781d2015-10-07 19:25:333324// Test a proxy auth scheme that allows default credentials and a proxy server
3325// that uses non-persistent connections.
3326TEST_P(HttpNetworkTransactionTest,
3327 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3328 HttpRequestInfo request;
3329 request.method = "GET";
3330 request.url = GURL("https://www.example.org/");
3331
3332 // Configure against proxy server "myproxy:70".
3333 session_deps_.proxy_service =
3334 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3335
3336 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3337 new HttpAuthHandlerMock::Factory());
3338 auth_handler_factory->set_do_init_from_challenge(true);
3339 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3340 mock_handler->set_allows_default_credentials(true);
3341 auth_handler_factory->AddMockHandler(mock_handler.release(),
3342 HttpAuth::AUTH_PROXY);
3343 session_deps_.http_auth_handler_factory = auth_handler_factory.Pass();
3344
3345 // Add NetLog just so can verify load timing information gets a NetLog ID.
3346 NetLog net_log;
3347 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423348 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333349
3350 // Since we have proxy, should try to establish tunnel.
3351 MockWrite data_writes1[] = {
3352 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3353 "Host: www.example.org\r\n"
3354 "Proxy-Connection: keep-alive\r\n\r\n"),
3355 };
3356
3357 // The proxy responds to the connect with a 407, using a non-persistent
3358 // connection.
3359 MockRead data_reads1[] = {
3360 // No credentials.
3361 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3362 MockRead("Proxy-Authenticate: Mock\r\n"),
3363 MockRead("Proxy-Connection: close\r\n\r\n"),
3364 };
3365
3366 // Since the first connection couldn't be reused, need to establish another
3367 // once given credentials.
3368 MockWrite data_writes2[] = {
3369 // After calling trans->RestartWithAuth(), this is the request we should
3370 // be issuing -- the final header line contains the credentials.
3371 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3372 "Host: www.example.org\r\n"
3373 "Proxy-Connection: keep-alive\r\n"
3374 "Proxy-Authorization: auth_token\r\n\r\n"),
3375
3376 MockWrite("GET / HTTP/1.1\r\n"
3377 "Host: www.example.org\r\n"
3378 "Connection: keep-alive\r\n\r\n"),
3379 };
3380
3381 MockRead data_reads2[] = {
3382 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3383
3384 MockRead("HTTP/1.1 200 OK\r\n"),
3385 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3386 MockRead("Content-Length: 5\r\n\r\n"),
3387 MockRead(SYNCHRONOUS, "hello"),
3388 };
3389
3390 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3391 data_writes1, arraysize(data_writes1));
3392 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3393 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3394 data_writes2, arraysize(data_writes2));
3395 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3396 SSLSocketDataProvider ssl(ASYNC, OK);
3397 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3398
3399 scoped_ptr<HttpTransaction> trans(
3400 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3401
3402 TestCompletionCallback callback;
3403 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3404 EXPECT_EQ(OK, callback.GetResult(rv));
3405
3406 const HttpResponseInfo* response = trans->GetResponseInfo();
3407 ASSERT_TRUE(response);
3408 ASSERT_TRUE(response->headers);
3409 EXPECT_FALSE(response->headers->IsKeepAlive());
3410 EXPECT_EQ(407, response->headers->response_code());
3411 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3412 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3413 EXPECT_FALSE(response->auth_challenge.get());
3414
3415 LoadTimingInfo load_timing_info;
3416 // CONNECT requests and responses are handled at the connect job level, so
3417 // the transaction does not yet have a connection.
3418 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3419
3420 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3421 EXPECT_EQ(OK, callback.GetResult(rv));
3422 response = trans->GetResponseInfo();
3423 ASSERT_TRUE(response);
3424 ASSERT_TRUE(response->headers);
3425 EXPECT_TRUE(response->headers->IsKeepAlive());
3426 EXPECT_EQ(200, response->headers->response_code());
3427 EXPECT_EQ(5, response->headers->GetContentLength());
3428 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3429
3430 // The password prompt info should not be set.
3431 EXPECT_FALSE(response->auth_challenge);
3432
3433 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3434 TestLoadTimingNotReusedWithPac(load_timing_info,
3435 CONNECT_TIMING_HAS_SSL_TIMES);
3436
3437 trans.reset();
3438 session->CloseAllConnections();
3439}
3440
3441// Test a proxy auth scheme that allows default credentials and a proxy server
3442// that hangs up when credentials are initially sent.
3443TEST_P(HttpNetworkTransactionTest,
3444 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3445 HttpRequestInfo request;
3446 request.method = "GET";
3447 request.url = GURL("https://www.example.org/");
3448
3449 // Configure against proxy server "myproxy:70".
3450 session_deps_.proxy_service =
3451 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3452
3453 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3454 new HttpAuthHandlerMock::Factory());
3455 auth_handler_factory->set_do_init_from_challenge(true);
3456 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3457 mock_handler->set_allows_default_credentials(true);
3458 auth_handler_factory->AddMockHandler(mock_handler.release(),
3459 HttpAuth::AUTH_PROXY);
3460 session_deps_.http_auth_handler_factory = auth_handler_factory.Pass();
3461
3462 // Add NetLog just so can verify load timing information gets a NetLog ID.
3463 NetLog net_log;
3464 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423465 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333466
3467 // Should try to establish tunnel.
3468 MockWrite data_writes1[] = {
3469 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3470 "Host: www.example.org\r\n"
3471 "Proxy-Connection: keep-alive\r\n\r\n"),
3472
3473 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3474 "Host: www.example.org\r\n"
3475 "Proxy-Connection: keep-alive\r\n"
3476 "Proxy-Authorization: auth_token\r\n\r\n"),
3477 };
3478
3479 // The proxy responds to the connect with a 407, using a non-persistent
3480 // connection.
3481 MockRead data_reads1[] = {
3482 // No credentials.
3483 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3484 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3485 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3486 };
3487
3488 // Since the first connection was closed, need to establish another once given
3489 // credentials.
3490 MockWrite data_writes2[] = {
3491 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3492 "Host: www.example.org\r\n"
3493 "Proxy-Connection: keep-alive\r\n"
3494 "Proxy-Authorization: auth_token\r\n\r\n"),
3495
3496 MockWrite("GET / HTTP/1.1\r\n"
3497 "Host: www.example.org\r\n"
3498 "Connection: keep-alive\r\n\r\n"),
3499 };
3500
3501 MockRead data_reads2[] = {
3502 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3503
3504 MockRead("HTTP/1.1 200 OK\r\n"),
3505 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3506 MockRead("Content-Length: 5\r\n\r\n"),
3507 MockRead(SYNCHRONOUS, "hello"),
3508 };
3509
3510 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3511 data_writes1, arraysize(data_writes1));
3512 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3513 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3514 data_writes2, arraysize(data_writes2));
3515 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3516 SSLSocketDataProvider ssl(ASYNC, OK);
3517 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3518
3519 scoped_ptr<HttpTransaction> trans(
3520 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3521
3522 TestCompletionCallback callback;
3523 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3524 EXPECT_EQ(OK, callback.GetResult(rv));
3525
3526 const HttpResponseInfo* response = trans->GetResponseInfo();
3527 ASSERT_TRUE(response);
3528 ASSERT_TRUE(response->headers);
3529 EXPECT_TRUE(response->headers->IsKeepAlive());
3530 EXPECT_EQ(407, response->headers->response_code());
3531 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3532 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3533 EXPECT_FALSE(response->auth_challenge);
3534
3535 LoadTimingInfo load_timing_info;
3536 // CONNECT requests and responses are handled at the connect job level, so
3537 // the transaction does not yet have a connection.
3538 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3539
3540 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3541 EXPECT_EQ(OK, callback.GetResult(rv));
3542
3543 response = trans->GetResponseInfo();
3544 ASSERT_TRUE(response);
3545 ASSERT_TRUE(response->headers);
3546 EXPECT_TRUE(response->headers->IsKeepAlive());
3547 EXPECT_EQ(200, response->headers->response_code());
3548 EXPECT_EQ(5, response->headers->GetContentLength());
3549 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3550
3551 // The password prompt info should not be set.
3552 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3553
3554 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3555 TestLoadTimingNotReusedWithPac(load_timing_info,
3556 CONNECT_TIMING_HAS_SSL_TIMES);
3557
3558 trans.reset();
3559 session->CloseAllConnections();
3560}
3561
3562// Test a proxy auth scheme that allows default credentials and a proxy server
3563// that hangs up when credentials are initially sent, and hangs up again when
3564// they are retried.
3565TEST_P(HttpNetworkTransactionTest,
3566 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
3567 HttpRequestInfo request;
3568 request.method = "GET";
3569 request.url = GURL("https://www.example.org/");
3570
3571 // Configure against proxy server "myproxy:70".
3572 session_deps_.proxy_service =
3573 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3574
3575 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3576 new HttpAuthHandlerMock::Factory());
3577 auth_handler_factory->set_do_init_from_challenge(true);
3578 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3579 mock_handler->set_allows_default_credentials(true);
3580 auth_handler_factory->AddMockHandler(mock_handler.release(),
3581 HttpAuth::AUTH_PROXY);
3582 session_deps_.http_auth_handler_factory = auth_handler_factory.Pass();
3583
3584 // Add NetLog just so can verify load timing information gets a NetLog ID.
3585 NetLog net_log;
3586 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423587 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333588
3589 // Should try to establish tunnel.
3590 MockWrite data_writes1[] = {
3591 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3592 "Host: www.example.org\r\n"
3593 "Proxy-Connection: keep-alive\r\n\r\n"),
3594
3595 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3596 "Host: www.example.org\r\n"
3597 "Proxy-Connection: keep-alive\r\n"
3598 "Proxy-Authorization: auth_token\r\n\r\n"),
3599 };
3600
3601 // The proxy responds to the connect with a 407, and then hangs up after the
3602 // second request is sent.
3603 MockRead data_reads1[] = {
3604 // No credentials.
3605 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3606 MockRead("Content-Length: 0\r\n"),
3607 MockRead("Proxy-Connection: keep-alive\r\n"),
3608 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3609 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3610 };
3611
3612 // HttpNetworkTransaction sees a reused connection that was closed with
3613 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
3614 // request.
3615 MockWrite data_writes2[] = {
3616 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3617 "Host: www.example.org\r\n"
3618 "Proxy-Connection: keep-alive\r\n\r\n"),
3619 };
3620
3621 // The proxy, having had more than enough of us, just hangs up.
3622 MockRead data_reads2[] = {
3623 // No credentials.
3624 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3625 };
3626
3627 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3628 data_writes1, arraysize(data_writes1));
3629 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3630 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3631 data_writes2, arraysize(data_writes2));
3632 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3633
3634 scoped_ptr<HttpTransaction> trans(
3635 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3636
3637 TestCompletionCallback callback;
3638 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3639 EXPECT_EQ(OK, callback.GetResult(rv));
3640
3641 const HttpResponseInfo* response = trans->GetResponseInfo();
3642 ASSERT_TRUE(response);
3643 ASSERT_TRUE(response->headers);
3644 EXPECT_TRUE(response->headers->IsKeepAlive());
3645 EXPECT_EQ(407, response->headers->response_code());
3646 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3647 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3648 EXPECT_FALSE(response->auth_challenge);
3649
3650 LoadTimingInfo load_timing_info;
3651 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3652
3653 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3654 EXPECT_EQ(ERR_EMPTY_RESPONSE, callback.GetResult(rv));
3655
3656 trans.reset();
3657 session->CloseAllConnections();
3658}
3659
3660// Test a proxy auth scheme that allows default credentials and a proxy server
3661// that hangs up when credentials are initially sent, and sends a challenge
3662// again they are retried.
3663TEST_P(HttpNetworkTransactionTest,
3664 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
3665 HttpRequestInfo request;
3666 request.method = "GET";
3667 request.url = GURL("https://www.example.org/");
3668
3669 // Configure against proxy server "myproxy:70".
3670 session_deps_.proxy_service =
3671 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3672
3673 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3674 new HttpAuthHandlerMock::Factory());
3675 auth_handler_factory->set_do_init_from_challenge(true);
3676 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3677 mock_handler->set_allows_default_credentials(true);
3678 auth_handler_factory->AddMockHandler(mock_handler.release(),
3679 HttpAuth::AUTH_PROXY);
3680 // Add another handler for the second challenge. It supports default
3681 // credentials, but they shouldn't be used, since they were already tried.
3682 mock_handler.reset(new HttpAuthHandlerMock());
3683 mock_handler->set_allows_default_credentials(true);
3684 auth_handler_factory->AddMockHandler(mock_handler.release(),
3685 HttpAuth::AUTH_PROXY);
3686 session_deps_.http_auth_handler_factory = auth_handler_factory.Pass();
3687
3688 // Add NetLog just so can verify load timing information gets a NetLog ID.
3689 NetLog net_log;
3690 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423691 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333692
3693 // Should try to establish tunnel.
3694 MockWrite data_writes1[] = {
3695 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3696 "Host: www.example.org\r\n"
3697 "Proxy-Connection: keep-alive\r\n\r\n"),
3698 };
3699
3700 // The proxy responds to the connect with a 407, using a non-persistent
3701 // connection.
3702 MockRead data_reads1[] = {
3703 // No credentials.
3704 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3705 MockRead("Proxy-Authenticate: Mock\r\n"),
3706 MockRead("Proxy-Connection: close\r\n\r\n"),
3707 };
3708
3709 // Since the first connection was closed, need to establish another once given
3710 // credentials.
3711 MockWrite data_writes2[] = {
3712 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3713 "Host: www.example.org\r\n"
3714 "Proxy-Connection: keep-alive\r\n"
3715 "Proxy-Authorization: auth_token\r\n\r\n"),
3716 };
3717
3718 MockRead data_reads2[] = {
3719 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3720 MockRead("Proxy-Authenticate: Mock\r\n"),
3721 MockRead("Proxy-Connection: close\r\n\r\n"),
3722 };
3723
3724 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3725 data_writes1, arraysize(data_writes1));
3726 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3727 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3728 data_writes2, arraysize(data_writes2));
3729 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3730 SSLSocketDataProvider ssl(ASYNC, OK);
3731 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3732
3733 scoped_ptr<HttpTransaction> trans(
3734 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3735
3736 TestCompletionCallback callback;
3737 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3738 EXPECT_EQ(OK, callback.GetResult(rv));
3739
3740 const HttpResponseInfo* response = trans->GetResponseInfo();
3741 ASSERT_TRUE(response);
3742 ASSERT_TRUE(response->headers);
3743 EXPECT_EQ(407, response->headers->response_code());
3744 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3745 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3746 EXPECT_FALSE(response->auth_challenge);
3747
3748 LoadTimingInfo load_timing_info;
3749 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3750
3751 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3752 EXPECT_EQ(OK, callback.GetResult(rv));
3753 response = trans->GetResponseInfo();
3754 ASSERT_TRUE(response);
3755 ASSERT_TRUE(response->headers);
3756 EXPECT_EQ(407, response->headers->response_code());
3757 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3758 EXPECT_TRUE(response->auth_challenge);
3759
3760 trans.reset();
3761 session->CloseAllConnections();
3762}
3763
[email protected]029c83b62013-01-24 05:28:203764// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023765TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203766 HttpRequestInfo request1;
3767 request1.method = "GET";
bncce36dca22015-04-21 22:11:233768 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203769
3770 HttpRequestInfo request2;
3771 request2.method = "GET";
bncce36dca22015-04-21 22:11:233772 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203773
3774 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033775 session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513776 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073777 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423778 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203779
3780 // Since we have proxy, should try to establish tunnel.
3781 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233782 MockWrite(
3783 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3784 "Host: www.example.org\r\n"
3785 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203786
bncce36dca22015-04-21 22:11:233787 MockWrite(
3788 "GET /1 HTTP/1.1\r\n"
3789 "Host: www.example.org\r\n"
3790 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203791
bncce36dca22015-04-21 22:11:233792 MockWrite(
3793 "GET /2 HTTP/1.1\r\n"
3794 "Host: www.example.org\r\n"
3795 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203796 };
3797
3798 // The proxy responds to the connect with a 407, using a persistent
3799 // connection.
3800 MockRead data_reads1[] = {
3801 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3802
3803 MockRead("HTTP/1.1 200 OK\r\n"),
3804 MockRead("Content-Length: 1\r\n\r\n"),
3805 MockRead(SYNCHRONOUS, "1"),
3806
3807 MockRead("HTTP/1.1 200 OK\r\n"),
3808 MockRead("Content-Length: 2\r\n\r\n"),
3809 MockRead(SYNCHRONOUS, "22"),
3810 };
3811
3812 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3813 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073814 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203815 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073816 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203817
3818 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363819 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503820 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203821
3822 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3823 EXPECT_EQ(ERR_IO_PENDING, rv);
3824
3825 rv = callback1.WaitForResult();
3826 EXPECT_EQ(OK, rv);
3827
3828 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3829 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503830 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203831 EXPECT_EQ(1, response1->headers->GetContentLength());
3832
3833 LoadTimingInfo load_timing_info1;
3834 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3835 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3836
3837 trans1.reset();
3838
3839 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363840 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503841 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203842
3843 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3844 EXPECT_EQ(ERR_IO_PENDING, rv);
3845
3846 rv = callback2.WaitForResult();
3847 EXPECT_EQ(OK, rv);
3848
3849 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3850 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503851 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203852 EXPECT_EQ(2, response2->headers->GetContentLength());
3853
3854 LoadTimingInfo load_timing_info2;
3855 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3856 TestLoadTimingReused(load_timing_info2);
3857
3858 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3859
3860 trans2.reset();
3861 session->CloseAllConnections();
3862}
3863
3864// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023865TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203866 HttpRequestInfo request1;
3867 request1.method = "GET";
bncce36dca22015-04-21 22:11:233868 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203869
3870 HttpRequestInfo request2;
3871 request2.method = "GET";
bncce36dca22015-04-21 22:11:233872 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203873
3874 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033875 session_deps_.proxy_service =
3876 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513877 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073878 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423879 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203880
3881 // Since we have proxy, should try to establish tunnel.
3882 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233883 MockWrite(
3884 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3885 "Host: www.example.org\r\n"
3886 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203887
bncce36dca22015-04-21 22:11:233888 MockWrite(
3889 "GET /1 HTTP/1.1\r\n"
3890 "Host: www.example.org\r\n"
3891 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203892
bncce36dca22015-04-21 22:11:233893 MockWrite(
3894 "GET /2 HTTP/1.1\r\n"
3895 "Host: www.example.org\r\n"
3896 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203897 };
3898
3899 // The proxy responds to the connect with a 407, using a persistent
3900 // connection.
3901 MockRead data_reads1[] = {
3902 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3903
3904 MockRead("HTTP/1.1 200 OK\r\n"),
3905 MockRead("Content-Length: 1\r\n\r\n"),
3906 MockRead(SYNCHRONOUS, "1"),
3907
3908 MockRead("HTTP/1.1 200 OK\r\n"),
3909 MockRead("Content-Length: 2\r\n\r\n"),
3910 MockRead(SYNCHRONOUS, "22"),
3911 };
3912
3913 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3914 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073915 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203916 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073917 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203918
3919 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363920 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503921 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203922
3923 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3924 EXPECT_EQ(ERR_IO_PENDING, rv);
3925
3926 rv = callback1.WaitForResult();
3927 EXPECT_EQ(OK, rv);
3928
3929 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3930 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503931 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203932 EXPECT_EQ(1, response1->headers->GetContentLength());
3933
3934 LoadTimingInfo load_timing_info1;
3935 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3936 TestLoadTimingNotReusedWithPac(load_timing_info1,
3937 CONNECT_TIMING_HAS_SSL_TIMES);
3938
3939 trans1.reset();
3940
3941 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363942 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503943 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203944
3945 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3946 EXPECT_EQ(ERR_IO_PENDING, rv);
3947
3948 rv = callback2.WaitForResult();
3949 EXPECT_EQ(OK, rv);
3950
3951 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3952 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503953 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203954 EXPECT_EQ(2, response2->headers->GetContentLength());
3955
3956 LoadTimingInfo load_timing_info2;
3957 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3958 TestLoadTimingReusedWithPac(load_timing_info2);
3959
3960 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3961
3962 trans2.reset();
3963 session->CloseAllConnections();
3964}
3965
[email protected]2df19bb2010-08-25 20:13:463966// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023967TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273968 HttpRequestInfo request;
3969 request.method = "GET";
bncce36dca22015-04-21 22:11:233970 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273971
[email protected]2df19bb2010-08-25 20:13:463972 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033973 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513974 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073975 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423976 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463977
[email protected]2df19bb2010-08-25 20:13:463978 // Since we have proxy, should use full url
3979 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233980 MockWrite(
3981 "GET http://www.example.org/ HTTP/1.1\r\n"
3982 "Host: www.example.org\r\n"
3983 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:463984 };
3985
3986 MockRead data_reads1[] = {
3987 MockRead("HTTP/1.1 200 OK\r\n"),
3988 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3989 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063990 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463991 };
3992
3993 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3994 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073995 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063996 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073997 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463998
[email protected]49639fa2011-12-20 23:22:413999 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464000
[email protected]262eec82013-03-19 21:01:364001 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504002 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504003
[email protected]49639fa2011-12-20 23:22:414004 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464005 EXPECT_EQ(ERR_IO_PENDING, rv);
4006
4007 rv = callback1.WaitForResult();
4008 EXPECT_EQ(OK, rv);
4009
[email protected]58e32bb2013-01-21 18:23:254010 LoadTimingInfo load_timing_info;
4011 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4012 TestLoadTimingNotReused(load_timing_info,
4013 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4014
[email protected]2df19bb2010-08-25 20:13:464015 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504016 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464017
4018 EXPECT_TRUE(response->headers->IsKeepAlive());
4019 EXPECT_EQ(200, response->headers->response_code());
4020 EXPECT_EQ(100, response->headers->GetContentLength());
4021 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4022
4023 // The password prompt info should not be set.
4024 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4025}
4026
[email protected]7642b5ae2010-09-01 20:55:174027// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024028TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274029 HttpRequestInfo request;
4030 request.method = "GET";
bncce36dca22015-04-21 22:11:234031 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274032 request.load_flags = 0;
4033
[email protected]7642b5ae2010-09-01 20:55:174034 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034035 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514036 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074037 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424038 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174039
bncce36dca22015-04-21 22:11:234040 // fetch http://www.example.org/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:464041 scoped_ptr<SpdyFrame> req(
4042 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134043 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174044
[email protected]23e482282013-06-14 16:08:024045 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4046 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174047 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134048 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174049 };
4050
rch8e6c6c42015-05-01 14:05:134051 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4052 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074053 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174054
[email protected]8ddf8322012-02-23 18:08:064055 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024056 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074057 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174058
[email protected]49639fa2011-12-20 23:22:414059 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174060
[email protected]262eec82013-03-19 21:01:364061 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504062 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504063
[email protected]49639fa2011-12-20 23:22:414064 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:174065 EXPECT_EQ(ERR_IO_PENDING, rv);
4066
4067 rv = callback1.WaitForResult();
4068 EXPECT_EQ(OK, rv);
4069
[email protected]58e32bb2013-01-21 18:23:254070 LoadTimingInfo load_timing_info;
4071 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4072 TestLoadTimingNotReused(load_timing_info,
4073 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4074
[email protected]7642b5ae2010-09-01 20:55:174075 const HttpResponseInfo* response = trans->GetResponseInfo();
4076 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504077 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:174078 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4079
4080 std::string response_data;
4081 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234082 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174083}
4084
[email protected]1c173852014-06-19 12:51:504085// Verifies that a session which races and wins against the owning transaction
4086// (completing prior to host resolution), doesn't fail the transaction.
4087// Regression test for crbug.com/334413.
4088TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
4089 HttpRequestInfo request;
4090 request.method = "GET";
bncce36dca22015-04-21 22:11:234091 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504092 request.load_flags = 0;
4093
4094 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034095 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514096 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504097 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424098 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504099
bncce36dca22015-04-21 22:11:234100 // Fetch http://www.example.org/ through the SPDY proxy.
[email protected]1c173852014-06-19 12:51:504101 scoped_ptr<SpdyFrame> req(
4102 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134103 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:504104
4105 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4106 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
4107 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134108 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504109 };
4110
rch8e6c6c42015-05-01 14:05:134111 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4112 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504113 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4114
4115 SSLSocketDataProvider ssl(ASYNC, OK);
4116 ssl.SetNextProto(GetParam());
4117 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4118
4119 TestCompletionCallback callback1;
4120
4121 scoped_ptr<HttpTransaction> trans(
4122 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4123
4124 // Stall the hostname resolution begun by the transaction.
4125 session_deps_.host_resolver->set_synchronous_mode(false);
4126 session_deps_.host_resolver->set_ondemand_mode(true);
4127
4128 int rv = trans->Start(&request, callback1.callback(), log.bound());
4129 EXPECT_EQ(ERR_IO_PENDING, rv);
4130
4131 // Race a session to the proxy, which completes first.
4132 session_deps_.host_resolver->set_ondemand_mode(false);
4133 SpdySessionKey key(
4134 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4135 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424136 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504137
4138 // Unstall the resolution begun by the transaction.
4139 session_deps_.host_resolver->set_ondemand_mode(true);
4140 session_deps_.host_resolver->ResolveAllPending();
4141
4142 EXPECT_FALSE(callback1.have_result());
4143 rv = callback1.WaitForResult();
4144 EXPECT_EQ(OK, rv);
4145
4146 const HttpResponseInfo* response = trans->GetResponseInfo();
4147 ASSERT_TRUE(response != NULL);
4148 ASSERT_TRUE(response->headers.get() != NULL);
4149 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4150
4151 std::string response_data;
4152 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4153 EXPECT_EQ(kUploadData, response_data);
4154}
4155
[email protected]dc7bd1c52010-11-12 00:01:134156// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024157TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274158 HttpRequestInfo request;
4159 request.method = "GET";
bncce36dca22015-04-21 22:11:234160 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274161 request.load_flags = 0;
4162
[email protected]79cb5c12011-09-12 13:12:044163 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034164 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514165 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074166 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424167 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134168
[email protected]dc7bd1c52010-11-12 00:01:134169 // The first request will be a bare GET, the second request will be a
4170 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:194171 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:464172 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134173 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464174 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134175 };
[email protected]ff98d7f02012-03-22 21:44:194176 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:464177 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
4178 arraysize(kExtraAuthorizationHeaders) / 2,
4179 false,
4180 3,
4181 LOWEST,
4182 false));
[email protected]dc7bd1c52010-11-12 00:01:134183 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134184 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134185 };
4186
4187 // The first response is a 407 proxy authentication challenge, and the second
4188 // response will be a 200 response since the second request includes a valid
4189 // Authorization header.
4190 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464191 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134192 };
[email protected]ff98d7f02012-03-22 21:44:194193 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:024194 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:134195 "407 Proxy Authentication Required",
4196 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
4197 1));
[email protected]ff98d7f02012-03-22 21:44:194198 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:024199 spdy_util_.ConstructSpdyBodyFrame(1, true));
4200 scoped_ptr<SpdyFrame> resp_data(
4201 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4202 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134203 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134204 CreateMockRead(*resp_authentication, 1),
4205 CreateMockRead(*body_authentication, 2),
4206 CreateMockRead(*resp_data, 4),
4207 CreateMockRead(*body_data, 5),
4208 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134209 };
4210
rch8e6c6c42015-05-01 14:05:134211 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4212 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074213 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134214
[email protected]8ddf8322012-02-23 18:08:064215 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024216 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074217 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134218
[email protected]49639fa2011-12-20 23:22:414219 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134220
[email protected]262eec82013-03-19 21:01:364221 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504222 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:134223
[email protected]49639fa2011-12-20 23:22:414224 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:134225 EXPECT_EQ(ERR_IO_PENDING, rv);
4226
4227 rv = callback1.WaitForResult();
4228 EXPECT_EQ(OK, rv);
4229
4230 const HttpResponseInfo* const response = trans->GetResponseInfo();
4231
4232 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504233 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:134234 EXPECT_EQ(407, response->headers->response_code());
4235 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:044236 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134237
[email protected]49639fa2011-12-20 23:22:414238 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134239
[email protected]49639fa2011-12-20 23:22:414240 rv = trans->RestartWithAuth(
4241 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:134242 EXPECT_EQ(ERR_IO_PENDING, rv);
4243
4244 rv = callback2.WaitForResult();
4245 EXPECT_EQ(OK, rv);
4246
4247 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
4248
4249 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:504250 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:134251 EXPECT_EQ(200, response_restart->headers->response_code());
4252 // The password prompt info should not be set.
4253 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
4254}
4255
[email protected]d9da5fe2010-10-13 22:37:164256// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:024257TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274258 HttpRequestInfo request;
4259 request.method = "GET";
bncce36dca22015-04-21 22:11:234260 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274261 request.load_flags = 0;
4262
[email protected]d9da5fe2010-10-13 22:37:164263 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034264 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514265 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074266 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424267 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164268
[email protected]262eec82013-03-19 21:01:364269 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504270 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164271
bncce36dca22015-04-21 22:11:234272 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:344273 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234274 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4275 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164276
bncce36dca22015-04-21 22:11:234277 const char get[] =
4278 "GET / HTTP/1.1\r\n"
4279 "Host: www.example.org\r\n"
4280 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:194281 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:024282 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
4283 scoped_ptr<SpdyFrame> conn_resp(
4284 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164285 const char resp[] = "HTTP/1.1 200 OK\r\n"
4286 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:194287 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024288 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:194289 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:024290 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:194291 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204292 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:044293
4294 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134295 CreateMockWrite(*connect, 0),
4296 CreateMockWrite(*wrapped_get, 2),
4297 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044298 };
4299
[email protected]d9da5fe2010-10-13 22:37:164300 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134301 CreateMockRead(*conn_resp, 1, ASYNC),
4302 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
4303 CreateMockRead(*wrapped_body, 4, ASYNC),
4304 CreateMockRead(*wrapped_body, 5, ASYNC),
4305 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164306 };
4307
rch8e6c6c42015-05-01 14:05:134308 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4309 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074310 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164311
[email protected]8ddf8322012-02-23 18:08:064312 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024313 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074314 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064315 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074316 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164317
[email protected]49639fa2011-12-20 23:22:414318 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164319
[email protected]49639fa2011-12-20 23:22:414320 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164321 EXPECT_EQ(ERR_IO_PENDING, rv);
4322
4323 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:134324 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:164325
[email protected]58e32bb2013-01-21 18:23:254326 LoadTimingInfo load_timing_info;
4327 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4328 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4329
[email protected]d9da5fe2010-10-13 22:37:164330 const HttpResponseInfo* response = trans->GetResponseInfo();
4331 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504332 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:164333 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4334
4335 std::string response_data;
4336 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4337 EXPECT_EQ("1234567890", response_data);
4338}
4339
4340// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:024341TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:274342 HttpRequestInfo request;
4343 request.method = "GET";
bncce36dca22015-04-21 22:11:234344 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274345 request.load_flags = 0;
4346
[email protected]d9da5fe2010-10-13 22:37:164347 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034348 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514349 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074350 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424351 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164352
[email protected]262eec82013-03-19 21:01:364353 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504354 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164355
bncce36dca22015-04-21 22:11:234356 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:344357 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234358 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4359 // fetch https://www.example.org/ via SPDY
4360 const char kMyUrl[] = "https://www.example.org/";
[email protected]cdf8f7e72013-05-23 10:56:464361 scoped_ptr<SpdyFrame> get(
4362 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:024363 scoped_ptr<SpdyFrame> wrapped_get(
4364 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
4365 scoped_ptr<SpdyFrame> conn_resp(
4366 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4367 scoped_ptr<SpdyFrame> get_resp(
4368 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:194369 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024370 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
4371 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4372 scoped_ptr<SpdyFrame> wrapped_body(
4373 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:194374 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:204375 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:194376 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:204377 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:044378
4379 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:094380 CreateMockWrite(*connect, 0),
4381 CreateMockWrite(*wrapped_get, 2),
4382 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:044383 CreateMockWrite(*window_update_body, 7),
4384 };
4385
[email protected]d9da5fe2010-10-13 22:37:164386 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:094387 CreateMockRead(*conn_resp, 1, ASYNC),
4388 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:134389 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:094390 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134391 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164392 };
4393
rch32320842015-05-16 15:57:094394 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4395 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074396 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164397
[email protected]8ddf8322012-02-23 18:08:064398 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024399 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074400 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064401 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024402 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074403 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164404
[email protected]49639fa2011-12-20 23:22:414405 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164406
[email protected]49639fa2011-12-20 23:22:414407 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164408 EXPECT_EQ(ERR_IO_PENDING, rv);
4409
rch32320842015-05-16 15:57:094410 // Allow the SpdyProxyClientSocket's write callback to complete.
4411 base::MessageLoop::current()->RunUntilIdle();
4412 // Now allow the read of the response to complete.
4413 spdy_data.CompleteRead();
[email protected]d9da5fe2010-10-13 22:37:164414 rv = callback1.WaitForResult();
4415 EXPECT_EQ(OK, rv);
4416
[email protected]58e32bb2013-01-21 18:23:254417 LoadTimingInfo load_timing_info;
4418 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4419 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4420
[email protected]d9da5fe2010-10-13 22:37:164421 const HttpResponseInfo* response = trans->GetResponseInfo();
4422 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504423 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:164424 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4425
4426 std::string response_data;
4427 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234428 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:164429}
4430
4431// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024432TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:274433 HttpRequestInfo request;
4434 request.method = "GET";
bncce36dca22015-04-21 22:11:234435 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274436 request.load_flags = 0;
4437
[email protected]d9da5fe2010-10-13 22:37:164438 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034439 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514440 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074441 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424442 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164443
[email protected]262eec82013-03-19 21:01:364444 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504445 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164446
bncce36dca22015-04-21 22:11:234447 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:344448 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234449 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:204450 scoped_ptr<SpdyFrame> get(
4451 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:164452
4453 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134454 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:164455 };
4456
[email protected]23e482282013-06-14 16:08:024457 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
4458 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:164459 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134460 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:164461 };
4462
rch8e6c6c42015-05-01 14:05:134463 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4464 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074465 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164466
[email protected]8ddf8322012-02-23 18:08:064467 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024468 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074469 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064470 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024471 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:074472 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164473
[email protected]49639fa2011-12-20 23:22:414474 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164475
[email protected]49639fa2011-12-20 23:22:414476 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164477 EXPECT_EQ(ERR_IO_PENDING, rv);
4478
4479 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:174480 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:164481
[email protected]4eddbc732012-08-09 05:40:174482 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:164483}
4484
[email protected]f6c63db52013-02-02 00:35:224485// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4486// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024487TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224488 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
4489 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034490 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514491 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074492 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424493 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504494 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224495
4496 HttpRequestInfo request1;
4497 request1.method = "GET";
bncce36dca22015-04-21 22:11:234498 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224499 request1.load_flags = 0;
4500
4501 HttpRequestInfo request2;
4502 request2.method = "GET";
bncce36dca22015-04-21 22:11:234503 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224504 request2.load_flags = 0;
4505
bncce36dca22015-04-21 22:11:234506 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:344507 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234508 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:024509 scoped_ptr<SpdyFrame> conn_resp1(
4510 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224511
bncce36dca22015-04-21 22:11:234512 // Fetch https://www.example.org/ via HTTP.
4513 const char get1[] =
4514 "GET / HTTP/1.1\r\n"
4515 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224516 "Connection: keep-alive\r\n\r\n";
4517 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024518 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224519 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4520 "Content-Length: 1\r\n\r\n";
4521 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024522 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
4523 scoped_ptr<SpdyFrame> wrapped_body1(
4524 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:224525 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204526 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224527
bncce36dca22015-04-21 22:11:234528 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:294529 SpdyHeaderBlock connect2_block;
bnc7ecc1122015-09-28 13:22:494530 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]745aa9c2014-06-27 02:21:294531 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnc9b79a572015-09-02 12:25:034532 if (GetParam() == kProtoHTTP2) {
bnc6b996d532015-07-29 10:51:324533 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
4534 } else {
bnc6b996d532015-07-29 10:51:324535 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
bnc7ecc1122015-09-28 13:22:494536 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
bnc6b996d532015-07-29 10:51:324537 }
[email protected]f6c63db52013-02-02 00:35:224538 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:294539 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:394540
[email protected]23e482282013-06-14 16:08:024541 scoped_ptr<SpdyFrame> conn_resp2(
4542 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:224543
bncce36dca22015-04-21 22:11:234544 // Fetch https://mail.example.org/ via HTTP.
4545 const char get2[] =
4546 "GET / HTTP/1.1\r\n"
4547 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224548 "Connection: keep-alive\r\n\r\n";
4549 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024550 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224551 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4552 "Content-Length: 2\r\n\r\n";
4553 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024554 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224555 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024556 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224557
4558 MockWrite spdy_writes[] = {
4559 CreateMockWrite(*connect1, 0),
4560 CreateMockWrite(*wrapped_get1, 2),
4561 CreateMockWrite(*connect2, 5),
4562 CreateMockWrite(*wrapped_get2, 7),
4563 };
4564
4565 MockRead spdy_reads[] = {
4566 CreateMockRead(*conn_resp1, 1, ASYNC),
4567 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4568 CreateMockRead(*wrapped_body1, 4, ASYNC),
4569 CreateMockRead(*conn_resp2, 6, ASYNC),
4570 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
4571 CreateMockRead(*wrapped_body2, 9, ASYNC),
4572 MockRead(ASYNC, 0, 10),
4573 };
4574
mmenke11eb5152015-06-09 14:50:504575 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4576 arraysize(spdy_writes));
4577 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224578
4579 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024580 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504581 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224582 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504583 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224584 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504585 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:224586
4587 TestCompletionCallback callback;
4588
[email protected]262eec82013-03-19 21:01:364589 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504590 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224591 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504592 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224593
4594 LoadTimingInfo load_timing_info;
4595 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4596 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4597
4598 const HttpResponseInfo* response = trans->GetResponseInfo();
4599 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504600 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224601 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4602
4603 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294604 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504605 rv = trans->Read(buf.get(), 256, callback.callback());
4606 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224607
[email protected]262eec82013-03-19 21:01:364608 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504609 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224610 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504611 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224612
4613 LoadTimingInfo load_timing_info2;
4614 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4615 // Even though the SPDY connection is reused, a new tunnelled connection has
4616 // to be created, so the socket's load timing looks like a fresh connection.
4617 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
4618
4619 // The requests should have different IDs, since they each are using their own
4620 // separate stream.
4621 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4622
mmenke11eb5152015-06-09 14:50:504623 rv = trans2->Read(buf.get(), 256, callback.callback());
4624 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224625}
4626
4627// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4628// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:024629TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224630 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
4631 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034632 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514633 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074634 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424635 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504636 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224637
4638 HttpRequestInfo request1;
4639 request1.method = "GET";
bncce36dca22015-04-21 22:11:234640 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224641 request1.load_flags = 0;
4642
4643 HttpRequestInfo request2;
4644 request2.method = "GET";
bncce36dca22015-04-21 22:11:234645 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:224646 request2.load_flags = 0;
4647
bncce36dca22015-04-21 22:11:234648 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:344649 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234650 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:024651 scoped_ptr<SpdyFrame> conn_resp1(
4652 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224653
bncce36dca22015-04-21 22:11:234654 // Fetch https://www.example.org/ via HTTP.
4655 const char get1[] =
4656 "GET / HTTP/1.1\r\n"
4657 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224658 "Connection: keep-alive\r\n\r\n";
4659 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024660 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224661 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4662 "Content-Length: 1\r\n\r\n";
4663 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024664 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
4665 scoped_ptr<SpdyFrame> wrapped_body1(
4666 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:224667 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204668 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224669
bncce36dca22015-04-21 22:11:234670 // Fetch https://www.example.org/2 via HTTP.
4671 const char get2[] =
4672 "GET /2 HTTP/1.1\r\n"
4673 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224674 "Connection: keep-alive\r\n\r\n";
4675 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024676 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224677 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4678 "Content-Length: 2\r\n\r\n";
4679 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024680 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224681 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024682 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224683
4684 MockWrite spdy_writes[] = {
4685 CreateMockWrite(*connect1, 0),
4686 CreateMockWrite(*wrapped_get1, 2),
4687 CreateMockWrite(*wrapped_get2, 5),
4688 };
4689
4690 MockRead spdy_reads[] = {
4691 CreateMockRead(*conn_resp1, 1, ASYNC),
4692 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4693 CreateMockRead(*wrapped_body1, 4, ASYNC),
4694 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4695 CreateMockRead(*wrapped_body2, 7, ASYNC),
4696 MockRead(ASYNC, 0, 8),
4697 };
4698
mmenke11eb5152015-06-09 14:50:504699 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4700 arraysize(spdy_writes));
4701 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224702
4703 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024704 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504705 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224706 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504707 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224708
4709 TestCompletionCallback callback;
4710
[email protected]262eec82013-03-19 21:01:364711 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504712 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224713 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4714 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:224715
4716 rv = callback.WaitForResult();
4717 EXPECT_EQ(OK, rv);
4718
4719 LoadTimingInfo load_timing_info;
4720 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4721 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4722
4723 const HttpResponseInfo* response = trans->GetResponseInfo();
4724 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504725 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224726 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4727
4728 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294729 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504730 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224731 trans.reset();
4732
[email protected]262eec82013-03-19 21:01:364733 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504734 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224735 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4736 EXPECT_EQ(ERR_IO_PENDING, rv);
4737
[email protected]f6c63db52013-02-02 00:35:224738 rv = callback.WaitForResult();
4739 EXPECT_EQ(OK, rv);
4740
4741 LoadTimingInfo load_timing_info2;
4742 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4743 TestLoadTimingReused(load_timing_info2);
4744
4745 // The requests should have the same ID.
4746 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4747
[email protected]90499482013-06-01 00:39:504748 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224749}
4750
4751// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4752// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:504753TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:224754 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034755 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514756 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074757 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424758 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504759 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224760
4761 HttpRequestInfo request1;
4762 request1.method = "GET";
bncce36dca22015-04-21 22:11:234763 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224764 request1.load_flags = 0;
4765
4766 HttpRequestInfo request2;
4767 request2.method = "GET";
bncce36dca22015-04-21 22:11:234768 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224769 request2.load_flags = 0;
4770
bncce36dca22015-04-21 22:11:234771 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024772 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234773 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294774 scoped_ptr<SpdyFrame> get1(
4775 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024776 scoped_ptr<SpdyFrame> get_resp1(
4777 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4778 scoped_ptr<SpdyFrame> body1(
4779 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224780
bncce36dca22015-04-21 22:11:234781 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024782 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234783 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294784 scoped_ptr<SpdyFrame> get2(
4785 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024786 scoped_ptr<SpdyFrame> get_resp2(
4787 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4788 scoped_ptr<SpdyFrame> body2(
4789 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224790
4791 MockWrite spdy_writes[] = {
4792 CreateMockWrite(*get1, 0),
4793 CreateMockWrite(*get2, 3),
4794 };
4795
4796 MockRead spdy_reads[] = {
4797 CreateMockRead(*get_resp1, 1, ASYNC),
4798 CreateMockRead(*body1, 2, ASYNC),
4799 CreateMockRead(*get_resp2, 4, ASYNC),
4800 CreateMockRead(*body2, 5, ASYNC),
4801 MockRead(ASYNC, 0, 6),
4802 };
4803
mmenke11eb5152015-06-09 14:50:504804 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4805 arraysize(spdy_writes));
4806 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224807
4808 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024809 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504810 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224811
4812 TestCompletionCallback callback;
4813
[email protected]262eec82013-03-19 21:01:364814 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504815 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224816 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504817 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224818
4819 LoadTimingInfo load_timing_info;
4820 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4821 TestLoadTimingNotReused(load_timing_info,
4822 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4823
4824 const HttpResponseInfo* response = trans->GetResponseInfo();
4825 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504826 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224827 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4828
4829 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294830 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504831 rv = trans->Read(buf.get(), 256, callback.callback());
4832 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224833 // Delete the first request, so the second one can reuse the socket.
4834 trans.reset();
4835
[email protected]262eec82013-03-19 21:01:364836 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504837 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224838 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504839 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224840
4841 LoadTimingInfo load_timing_info2;
4842 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4843 TestLoadTimingReused(load_timing_info2);
4844
4845 // The requests should have the same ID.
4846 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4847
mmenke11eb5152015-06-09 14:50:504848 rv = trans2->Read(buf.get(), 256, callback.callback());
4849 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224850}
4851
[email protected]2df19bb2010-08-25 20:13:464852// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024853TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464854 HttpRequestInfo request;
4855 request.method = "GET";
bncce36dca22015-04-21 22:11:234856 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464857 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294858 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464859
[email protected]79cb5c12011-09-12 13:12:044860 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034861 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514862 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074863 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424864 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274865
[email protected]2df19bb2010-08-25 20:13:464866 // Since we have proxy, should use full url
4867 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234868 MockWrite(
4869 "GET http://www.example.org/ HTTP/1.1\r\n"
4870 "Host: www.example.org\r\n"
4871 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464872
bncce36dca22015-04-21 22:11:234873 // After calling trans->RestartWithAuth(), this is the request we should
4874 // be issuing -- the final header line contains the credentials.
4875 MockWrite(
4876 "GET http://www.example.org/ HTTP/1.1\r\n"
4877 "Host: www.example.org\r\n"
4878 "Proxy-Connection: keep-alive\r\n"
4879 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464880 };
4881
4882 // The proxy responds to the GET with a 407, using a persistent
4883 // connection.
4884 MockRead data_reads1[] = {
4885 // No credentials.
4886 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4887 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4888 MockRead("Proxy-Connection: keep-alive\r\n"),
4889 MockRead("Content-Length: 0\r\n\r\n"),
4890
4891 MockRead("HTTP/1.1 200 OK\r\n"),
4892 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4893 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064894 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464895 };
4896
4897 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4898 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074899 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064900 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074901 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464902
[email protected]49639fa2011-12-20 23:22:414903 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464904
[email protected]262eec82013-03-19 21:01:364905 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504906 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504907
[email protected]49639fa2011-12-20 23:22:414908 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464909 EXPECT_EQ(ERR_IO_PENDING, rv);
4910
4911 rv = callback1.WaitForResult();
4912 EXPECT_EQ(OK, rv);
4913
[email protected]58e32bb2013-01-21 18:23:254914 LoadTimingInfo load_timing_info;
4915 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4916 TestLoadTimingNotReused(load_timing_info,
4917 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4918
[email protected]2df19bb2010-08-25 20:13:464919 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504920 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504921 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464922 EXPECT_EQ(407, response->headers->response_code());
4923 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044924 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464925
[email protected]49639fa2011-12-20 23:22:414926 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464927
[email protected]49639fa2011-12-20 23:22:414928 rv = trans->RestartWithAuth(
4929 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464930 EXPECT_EQ(ERR_IO_PENDING, rv);
4931
4932 rv = callback2.WaitForResult();
4933 EXPECT_EQ(OK, rv);
4934
[email protected]58e32bb2013-01-21 18:23:254935 load_timing_info = LoadTimingInfo();
4936 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4937 // Retrying with HTTP AUTH is considered to be reusing a socket.
4938 TestLoadTimingReused(load_timing_info);
4939
[email protected]2df19bb2010-08-25 20:13:464940 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504941 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464942
4943 EXPECT_TRUE(response->headers->IsKeepAlive());
4944 EXPECT_EQ(200, response->headers->response_code());
4945 EXPECT_EQ(100, response->headers->GetContentLength());
4946 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4947
4948 // The password prompt info should not be set.
4949 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4950}
4951
[email protected]23e482282013-06-14 16:08:024952void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084953 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424954 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084955 request.method = "GET";
bncce36dca22015-04-21 22:11:234956 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084957 request.load_flags = 0;
4958
[email protected]cb9bf6ca2011-01-28 13:15:274959 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034960 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:424961 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274962
[email protected]c744cf22009-02-27 07:28:084963 // Since we have proxy, should try to establish tunnel.
4964 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:234965 MockWrite(
4966 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4967 "Host: www.example.org\r\n"
4968 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084969 };
4970
4971 MockRead data_reads[] = {
4972 status,
4973 MockRead("Content-Length: 10\r\n\r\n"),
4974 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064975 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084976 };
4977
[email protected]31a2bfe2010-02-09 08:03:394978 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4979 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074980 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084981
[email protected]49639fa2011-12-20 23:22:414982 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084983
[email protected]262eec82013-03-19 21:01:364984 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504985 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504986
[email protected]49639fa2011-12-20 23:22:414987 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424988 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084989
4990 rv = callback.WaitForResult();
4991 EXPECT_EQ(expected_status, rv);
4992}
4993
[email protected]23e482282013-06-14 16:08:024994void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234995 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084996 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424997 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084998}
4999
[email protected]23e482282013-06-14 16:08:025000TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085001 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5002}
5003
[email protected]23e482282013-06-14 16:08:025004TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085005 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5006}
5007
[email protected]23e482282013-06-14 16:08:025008TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085009 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5010}
5011
[email protected]23e482282013-06-14 16:08:025012TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085013 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5014}
5015
[email protected]23e482282013-06-14 16:08:025016TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085017 ConnectStatusHelper(
5018 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5019}
5020
[email protected]23e482282013-06-14 16:08:025021TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085022 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5023}
5024
[email protected]23e482282013-06-14 16:08:025025TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085026 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5027}
5028
[email protected]23e482282013-06-14 16:08:025029TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085030 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5031}
5032
[email protected]23e482282013-06-14 16:08:025033TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085034 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5035}
5036
[email protected]23e482282013-06-14 16:08:025037TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085038 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5039}
5040
[email protected]23e482282013-06-14 16:08:025041TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085042 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5043}
5044
[email protected]23e482282013-06-14 16:08:025045TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085046 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5047}
5048
[email protected]23e482282013-06-14 16:08:025049TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085050 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5051}
5052
[email protected]23e482282013-06-14 16:08:025053TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085054 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5055}
5056
[email protected]23e482282013-06-14 16:08:025057TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085058 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5059}
5060
[email protected]23e482282013-06-14 16:08:025061TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085062 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5063}
5064
[email protected]0a17aab32014-04-24 03:32:375065TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
5066 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5067}
5068
[email protected]23e482282013-06-14 16:08:025069TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085070 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5071}
5072
[email protected]23e482282013-06-14 16:08:025073TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085074 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5075}
5076
[email protected]23e482282013-06-14 16:08:025077TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085078 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5079}
5080
[email protected]23e482282013-06-14 16:08:025081TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085082 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5083}
5084
[email protected]23e482282013-06-14 16:08:025085TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085086 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5087}
5088
[email protected]23e482282013-06-14 16:08:025089TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085090 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5091}
5092
[email protected]23e482282013-06-14 16:08:025093TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085094 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5095}
5096
[email protected]23e482282013-06-14 16:08:025097TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085098 ConnectStatusHelperWithExpectedStatus(
5099 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545100 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085101}
5102
[email protected]23e482282013-06-14 16:08:025103TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085104 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5105}
5106
[email protected]23e482282013-06-14 16:08:025107TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085108 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5109}
5110
[email protected]23e482282013-06-14 16:08:025111TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085112 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5113}
5114
[email protected]23e482282013-06-14 16:08:025115TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085116 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5117}
5118
[email protected]23e482282013-06-14 16:08:025119TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085120 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5121}
5122
[email protected]23e482282013-06-14 16:08:025123TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085124 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5125}
5126
[email protected]23e482282013-06-14 16:08:025127TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085128 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5129}
5130
[email protected]23e482282013-06-14 16:08:025131TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085132 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5133}
5134
[email protected]23e482282013-06-14 16:08:025135TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085136 ConnectStatusHelper(
5137 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5138}
5139
[email protected]23e482282013-06-14 16:08:025140TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085141 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5142}
5143
[email protected]23e482282013-06-14 16:08:025144TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085145 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5146}
5147
[email protected]23e482282013-06-14 16:08:025148TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085149 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5150}
5151
[email protected]23e482282013-06-14 16:08:025152TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085153 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5154}
5155
[email protected]23e482282013-06-14 16:08:025156TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085157 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5158}
5159
[email protected]23e482282013-06-14 16:08:025160TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085161 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5162}
5163
[email protected]23e482282013-06-14 16:08:025164TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085165 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5166}
5167
[email protected]038e9a32008-10-08 22:40:165168// Test the flow when both the proxy server AND origin server require
5169// authentication. Again, this uses basic auth for both since that is
5170// the simplest to mock.
[email protected]23e482282013-06-14 16:08:025171TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275172 HttpRequestInfo request;
5173 request.method = "GET";
bncce36dca22015-04-21 22:11:235174 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275175 request.load_flags = 0;
5176
[email protected]038e9a32008-10-08 22:40:165177 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035178 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:425179 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075180
5181 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415182 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:165183
[email protected]f9ee6b52008-11-08 06:46:235184 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235185 MockWrite(
5186 "GET http://www.example.org/ HTTP/1.1\r\n"
5187 "Host: www.example.org\r\n"
5188 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235189 };
5190
[email protected]038e9a32008-10-08 22:40:165191 MockRead data_reads1[] = {
5192 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5193 // Give a couple authenticate options (only the middle one is actually
5194 // supported).
[email protected]22927ad2009-09-21 19:56:195195 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165196 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5197 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5198 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5199 // Large content-length -- won't matter, as connection will be reset.
5200 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065201 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165202 };
5203
5204 // After calling trans->RestartWithAuth() the first time, this is the
5205 // request we should be issuing -- the final header line contains the
5206 // proxy's credentials.
5207 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235208 MockWrite(
5209 "GET http://www.example.org/ HTTP/1.1\r\n"
5210 "Host: www.example.org\r\n"
5211 "Proxy-Connection: keep-alive\r\n"
5212 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165213 };
5214
5215 // Now the proxy server lets the request pass through to origin server.
5216 // The origin server responds with a 401.
5217 MockRead data_reads2[] = {
5218 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5219 // Note: We are using the same realm-name as the proxy server. This is
5220 // completely valid, as realms are unique across hosts.
5221 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5222 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5223 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065224 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165225 };
5226
5227 // After calling trans->RestartWithAuth() the second time, we should send
5228 // the credentials for both the proxy and origin server.
5229 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235230 MockWrite(
5231 "GET http://www.example.org/ HTTP/1.1\r\n"
5232 "Host: www.example.org\r\n"
5233 "Proxy-Connection: keep-alive\r\n"
5234 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5235 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165236 };
5237
5238 // Lastly we get the desired content.
5239 MockRead data_reads3[] = {
5240 MockRead("HTTP/1.0 200 OK\r\n"),
5241 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5242 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065243 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165244 };
5245
[email protected]31a2bfe2010-02-09 08:03:395246 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5247 data_writes1, arraysize(data_writes1));
5248 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5249 data_writes2, arraysize(data_writes2));
5250 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5251 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075252 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5253 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5254 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165255
[email protected]49639fa2011-12-20 23:22:415256 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165257
[email protected]49639fa2011-12-20 23:22:415258 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425259 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165260
5261 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425262 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165263
[email protected]1c773ea12009-04-28 19:58:425264 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505265 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045266 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165267
[email protected]49639fa2011-12-20 23:22:415268 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165269
[email protected]49639fa2011-12-20 23:22:415270 rv = trans->RestartWithAuth(
5271 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425272 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165273
5274 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425275 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165276
5277 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505278 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045279 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165280
[email protected]49639fa2011-12-20 23:22:415281 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165282
[email protected]49639fa2011-12-20 23:22:415283 rv = trans->RestartWithAuth(
5284 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425285 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165286
5287 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425288 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165289
5290 response = trans->GetResponseInfo();
5291 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5292 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165293}
[email protected]4ddaf2502008-10-23 18:26:195294
[email protected]ea9dc9a2009-09-05 00:43:325295// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5296// can't hook into its internals to cause it to generate predictable NTLM
5297// authorization headers.
5298#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295299// The NTLM authentication unit tests were generated by capturing the HTTP
5300// requests and responses using Fiddler 2 and inspecting the generated random
5301// bytes in the debugger.
5302
5303// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:025304TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425305 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245306 request.method = "GET";
5307 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545308
5309 // Ensure load is not disrupted by flags which suppress behaviour specific
5310 // to other auth schemes.
5311 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245312
[email protected]cb9bf6ca2011-01-28 13:15:275313 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5314 MockGetHostName);
mmenkee65e7af2015-10-13 17:16:425315 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275316
[email protected]3f918782009-02-28 01:29:245317 MockWrite data_writes1[] = {
5318 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5319 "Host: 172.22.68.17\r\n"
5320 "Connection: keep-alive\r\n\r\n"),
5321 };
5322
5323 MockRead data_reads1[] = {
5324 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045325 // Negotiate and NTLM are often requested together. However, we only want
5326 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5327 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245328 MockRead("WWW-Authenticate: NTLM\r\n"),
5329 MockRead("Connection: close\r\n"),
5330 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365331 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245332 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065333 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245334 };
5335
5336 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225337 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:245338 // request we should be issuing -- the final header line contains a Type
5339 // 1 message.
5340 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5341 "Host: 172.22.68.17\r\n"
5342 "Connection: keep-alive\r\n"
5343 "Authorization: NTLM "
5344 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5345
5346 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5347 // (the credentials for the origin server). The second request continues
5348 // on the same connection.
5349 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5350 "Host: 172.22.68.17\r\n"
5351 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:295352 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5353 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5354 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5355 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5356 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245357 };
5358
5359 MockRead data_reads2[] = {
5360 // The origin server responds with a Type 2 message.
5361 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5362 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295363 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245364 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5365 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5366 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5367 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5368 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5369 "BtAAAAAAA=\r\n"),
5370 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365371 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245372 MockRead("You are not authorized to view this page\r\n"),
5373
5374 // Lastly we get the desired content.
5375 MockRead("HTTP/1.1 200 OK\r\n"),
5376 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5377 MockRead("Content-Length: 13\r\n\r\n"),
5378 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065379 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245380 };
5381
[email protected]31a2bfe2010-02-09 08:03:395382 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5383 data_writes1, arraysize(data_writes1));
5384 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5385 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075386 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5387 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245388
[email protected]49639fa2011-12-20 23:22:415389 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245390
[email protected]262eec82013-03-19 21:01:365391 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505392 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505393
[email protected]49639fa2011-12-20 23:22:415394 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425395 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245396
5397 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425398 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245399
[email protected]0757e7702009-03-27 04:00:225400 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5401
[email protected]1c773ea12009-04-28 19:58:425402 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:045403 ASSERT_FALSE(response == NULL);
5404 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245405
[email protected]49639fa2011-12-20 23:22:415406 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255407
[email protected]f3cf9802011-10-28 18:44:585408 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415409 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:255410 EXPECT_EQ(ERR_IO_PENDING, rv);
5411
5412 rv = callback2.WaitForResult();
5413 EXPECT_EQ(OK, rv);
5414
5415 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5416
5417 response = trans->GetResponseInfo();
5418 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:255419 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5420
[email protected]49639fa2011-12-20 23:22:415421 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245422
[email protected]49639fa2011-12-20 23:22:415423 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425424 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245425
[email protected]0757e7702009-03-27 04:00:225426 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425427 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245428
5429 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505430 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:245431 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5432 EXPECT_EQ(13, response->headers->GetContentLength());
5433}
5434
[email protected]385a4672009-03-11 22:21:295435// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:025436TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425437 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295438 request.method = "GET";
5439 request.url = GURL("http://172.22.68.17/kids/login.aspx");
5440 request.load_flags = 0;
5441
[email protected]cb9bf6ca2011-01-28 13:15:275442 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5443 MockGetHostName);
mmenkee65e7af2015-10-13 17:16:425444 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275445
[email protected]385a4672009-03-11 22:21:295446 MockWrite data_writes1[] = {
5447 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5448 "Host: 172.22.68.17\r\n"
5449 "Connection: keep-alive\r\n\r\n"),
5450 };
5451
5452 MockRead data_reads1[] = {
5453 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045454 // Negotiate and NTLM are often requested together. However, we only want
5455 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5456 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:295457 MockRead("WWW-Authenticate: NTLM\r\n"),
5458 MockRead("Connection: close\r\n"),
5459 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365460 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295461 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065462 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295463 };
5464
5465 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225466 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295467 // request we should be issuing -- the final header line contains a Type
5468 // 1 message.
5469 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5470 "Host: 172.22.68.17\r\n"
5471 "Connection: keep-alive\r\n"
5472 "Authorization: NTLM "
5473 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5474
5475 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5476 // (the credentials for the origin server). The second request continues
5477 // on the same connection.
5478 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5479 "Host: 172.22.68.17\r\n"
5480 "Connection: keep-alive\r\n"
5481 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5482 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5483 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
5484 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
5485 "4Ww7b7E=\r\n\r\n"),
5486 };
5487
5488 MockRead data_reads2[] = {
5489 // The origin server responds with a Type 2 message.
5490 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5491 MockRead("WWW-Authenticate: NTLM "
5492 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
5493 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5494 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5495 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5496 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5497 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5498 "BtAAAAAAA=\r\n"),
5499 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365500 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295501 MockRead("You are not authorized to view this page\r\n"),
5502
5503 // Wrong password.
5504 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:295505 MockRead("WWW-Authenticate: NTLM\r\n"),
5506 MockRead("Connection: close\r\n"),
5507 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365508 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295509 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065510 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295511 };
5512
5513 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:225514 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295515 // request we should be issuing -- the final header line contains a Type
5516 // 1 message.
5517 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5518 "Host: 172.22.68.17\r\n"
5519 "Connection: keep-alive\r\n"
5520 "Authorization: NTLM "
5521 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5522
5523 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5524 // (the credentials for the origin server). The second request continues
5525 // on the same connection.
5526 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5527 "Host: 172.22.68.17\r\n"
5528 "Connection: keep-alive\r\n"
5529 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5530 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5531 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
5532 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
5533 "+4MUm7c=\r\n\r\n"),
5534 };
5535
5536 MockRead data_reads3[] = {
5537 // The origin server responds with a Type 2 message.
5538 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5539 MockRead("WWW-Authenticate: NTLM "
5540 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
5541 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5542 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5543 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5544 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5545 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5546 "BtAAAAAAA=\r\n"),
5547 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365548 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295549 MockRead("You are not authorized to view this page\r\n"),
5550
5551 // Lastly we get the desired content.
5552 MockRead("HTTP/1.1 200 OK\r\n"),
5553 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5554 MockRead("Content-Length: 13\r\n\r\n"),
5555 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065556 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:295557 };
5558
[email protected]31a2bfe2010-02-09 08:03:395559 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5560 data_writes1, arraysize(data_writes1));
5561 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5562 data_writes2, arraysize(data_writes2));
5563 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5564 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075565 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5566 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5567 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:295568
[email protected]49639fa2011-12-20 23:22:415569 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:295570
[email protected]262eec82013-03-19 21:01:365571 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505572 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505573
[email protected]49639fa2011-12-20 23:22:415574 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425575 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295576
5577 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425578 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295579
[email protected]0757e7702009-03-27 04:00:225580 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:295581
[email protected]1c773ea12009-04-28 19:58:425582 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505583 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045584 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:295585
[email protected]49639fa2011-12-20 23:22:415586 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:295587
[email protected]0757e7702009-03-27 04:00:225588 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:585589 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:415590 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425591 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295592
[email protected]10af5fe72011-01-31 16:17:255593 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425594 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295595
[email protected]0757e7702009-03-27 04:00:225596 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415597 TestCompletionCallback callback3;
5598 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425599 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:255600 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425601 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225602 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5603
5604 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:045605 ASSERT_FALSE(response == NULL);
5606 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:225607
[email protected]49639fa2011-12-20 23:22:415608 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:225609
5610 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:585611 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415612 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:255613 EXPECT_EQ(ERR_IO_PENDING, rv);
5614
5615 rv = callback4.WaitForResult();
5616 EXPECT_EQ(OK, rv);
5617
5618 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5619
[email protected]49639fa2011-12-20 23:22:415620 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:255621
5622 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:415623 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:425624 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225625
5626 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425627 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225628
[email protected]385a4672009-03-11 22:21:295629 response = trans->GetResponseInfo();
5630 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5631 EXPECT_EQ(13, response->headers->GetContentLength());
5632}
[email protected]ea9dc9a2009-09-05 00:43:325633#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:295634
[email protected]4ddaf2502008-10-23 18:26:195635// Test reading a server response which has only headers, and no body.
5636// After some maximum number of bytes is consumed, the transaction should
5637// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:025638TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:425639 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:195640 request.method = "GET";
bncce36dca22015-04-21 22:11:235641 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:195642 request.load_flags = 0;
5643
mmenkee65e7af2015-10-13 17:16:425644 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275645 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415646 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275647
[email protected]b75b7b2f2009-10-06 00:54:535648 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:435649 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:535650 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:195651
5652 MockRead data_reads[] = {
5653 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065654 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:195655 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:065656 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:195657 };
[email protected]31a2bfe2010-02-09 08:03:395658 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075659 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:195660
[email protected]49639fa2011-12-20 23:22:415661 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:195662
[email protected]49639fa2011-12-20 23:22:415663 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425664 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:195665
5666 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425667 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:195668}
[email protected]f4e426b2008-11-05 00:24:495669
5670// Make sure that we don't try to reuse a TCPClientSocket when failing to
5671// establish tunnel.
5672// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:025673TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:235674 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275675 HttpRequestInfo request;
5676 request.method = "GET";
bncce36dca22015-04-21 22:11:235677 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275678 request.load_flags = 0;
5679
[email protected]f4e426b2008-11-05 00:24:495680 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035681 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:015682
mmenkee65e7af2015-10-13 17:16:425683 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495684
[email protected]262eec82013-03-19 21:01:365685 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505686 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495687
[email protected]f4e426b2008-11-05 00:24:495688 // Since we have proxy, should try to establish tunnel.
5689 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235690 MockWrite(
5691 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5692 "Host: www.example.org\r\n"
5693 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495694 };
5695
[email protected]77848d12008-11-14 00:00:225696 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495697 // connection. Usually a proxy would return 501 (not implemented),
5698 // or 200 (tunnel established).
5699 MockRead data_reads1[] = {
5700 MockRead("HTTP/1.1 404 Not Found\r\n"),
5701 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065702 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495703 };
5704
[email protected]31a2bfe2010-02-09 08:03:395705 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5706 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075707 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495708
[email protected]49639fa2011-12-20 23:22:415709 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495710
[email protected]49639fa2011-12-20 23:22:415711 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425712 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495713
5714 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425715 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495716
[email protected]b4404c02009-04-10 16:38:525717 // Empty the current queue. This is necessary because idle sockets are
5718 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345719 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525720
[email protected]f4e426b2008-11-05 00:24:495721 // We now check to make sure the TCPClientSocket was not added back to
5722 // the pool.
[email protected]90499482013-06-01 00:39:505723 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495724 trans.reset();
[email protected]2da659e2013-05-23 20:51:345725 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495726 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505727 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495728}
[email protected]372d34a2008-11-05 21:30:515729
[email protected]1b157c02009-04-21 01:55:405730// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025731TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425732 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405733 request.method = "GET";
bncce36dca22015-04-21 22:11:235734 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405735 request.load_flags = 0;
5736
mmenkee65e7af2015-10-13 17:16:425737 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275738
[email protected]262eec82013-03-19 21:01:365739 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505740 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275741
[email protected]1b157c02009-04-21 01:55:405742 MockRead data_reads[] = {
5743 // A part of the response body is received with the response headers.
5744 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5745 // The rest of the response body is received in two parts.
5746 MockRead("lo"),
5747 MockRead(" world"),
5748 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065749 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405750 };
5751
[email protected]31a2bfe2010-02-09 08:03:395752 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075753 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405754
[email protected]49639fa2011-12-20 23:22:415755 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405756
[email protected]49639fa2011-12-20 23:22:415757 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425758 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405759
5760 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425761 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405762
[email protected]1c773ea12009-04-28 19:58:425763 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505764 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405765
[email protected]90499482013-06-01 00:39:505766 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405767 std::string status_line = response->headers->GetStatusLine();
5768 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5769
[email protected]90499482013-06-01 00:39:505770 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405771
5772 std::string response_data;
5773 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425774 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405775 EXPECT_EQ("hello world", response_data);
5776
5777 // Empty the current queue. This is necessary because idle sockets are
5778 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345779 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405780
5781 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505782 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405783}
5784
[email protected]76a505b2010-08-25 06:23:005785// Make sure that we recycle a SSL socket after reading all of the response
5786// body.
[email protected]23e482282013-06-14 16:08:025787TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005788 HttpRequestInfo request;
5789 request.method = "GET";
bncce36dca22015-04-21 22:11:235790 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005791 request.load_flags = 0;
5792
5793 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235794 MockWrite(
5795 "GET / HTTP/1.1\r\n"
5796 "Host: www.example.org\r\n"
5797 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005798 };
5799
5800 MockRead data_reads[] = {
5801 MockRead("HTTP/1.1 200 OK\r\n"),
5802 MockRead("Content-Length: 11\r\n\r\n"),
5803 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065804 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005805 };
5806
[email protected]8ddf8322012-02-23 18:08:065807 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075808 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005809
5810 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5811 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075812 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005813
[email protected]49639fa2011-12-20 23:22:415814 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005815
mmenkee65e7af2015-10-13 17:16:425816 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365817 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505818 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005819
[email protected]49639fa2011-12-20 23:22:415820 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005821
5822 EXPECT_EQ(ERR_IO_PENDING, rv);
5823 EXPECT_EQ(OK, callback.WaitForResult());
5824
5825 const HttpResponseInfo* response = trans->GetResponseInfo();
5826 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505827 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005828 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5829
[email protected]90499482013-06-01 00:39:505830 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005831
5832 std::string response_data;
5833 rv = ReadTransaction(trans.get(), &response_data);
5834 EXPECT_EQ(OK, rv);
5835 EXPECT_EQ("hello world", response_data);
5836
5837 // Empty the current queue. This is necessary because idle sockets are
5838 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345839 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005840
5841 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505842 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005843}
5844
5845// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5846// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025847TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005848 HttpRequestInfo request;
5849 request.method = "GET";
bncce36dca22015-04-21 22:11:235850 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005851 request.load_flags = 0;
5852
5853 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235854 MockWrite(
5855 "GET / HTTP/1.1\r\n"
5856 "Host: www.example.org\r\n"
5857 "Connection: keep-alive\r\n\r\n"),
5858 MockWrite(
5859 "GET / HTTP/1.1\r\n"
5860 "Host: www.example.org\r\n"
5861 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005862 };
5863
5864 MockRead data_reads[] = {
5865 MockRead("HTTP/1.1 200 OK\r\n"),
5866 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065867 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005868 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065869 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005870 };
5871
[email protected]8ddf8322012-02-23 18:08:065872 SSLSocketDataProvider ssl(ASYNC, OK);
5873 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5875 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005876
5877 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5878 data_writes, arraysize(data_writes));
5879 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5880 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075881 session_deps_.socket_factory->AddSocketDataProvider(&data);
5882 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005883
[email protected]49639fa2011-12-20 23:22:415884 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005885
mmenkee65e7af2015-10-13 17:16:425886 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365887 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505888 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005889
[email protected]49639fa2011-12-20 23:22:415890 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005891
5892 EXPECT_EQ(ERR_IO_PENDING, rv);
5893 EXPECT_EQ(OK, callback.WaitForResult());
5894
5895 const HttpResponseInfo* response = trans->GetResponseInfo();
5896 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505897 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005898 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5899
[email protected]90499482013-06-01 00:39:505900 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005901
5902 std::string response_data;
5903 rv = ReadTransaction(trans.get(), &response_data);
5904 EXPECT_EQ(OK, rv);
5905 EXPECT_EQ("hello world", response_data);
5906
5907 // Empty the current queue. This is necessary because idle sockets are
5908 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345909 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005910
5911 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505912 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005913
5914 // Now start the second transaction, which should reuse the previous socket.
5915
[email protected]90499482013-06-01 00:39:505916 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005917
[email protected]49639fa2011-12-20 23:22:415918 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005919
5920 EXPECT_EQ(ERR_IO_PENDING, rv);
5921 EXPECT_EQ(OK, callback.WaitForResult());
5922
5923 response = trans->GetResponseInfo();
5924 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505925 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005926 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5927
[email protected]90499482013-06-01 00:39:505928 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005929
5930 rv = ReadTransaction(trans.get(), &response_data);
5931 EXPECT_EQ(OK, rv);
5932 EXPECT_EQ("hello world", response_data);
5933
5934 // Empty the current queue. This is necessary because idle sockets are
5935 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345936 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005937
5938 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505939 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005940}
5941
[email protected]b4404c02009-04-10 16:38:525942// Make sure that we recycle a socket after a zero-length response.
5943// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025944TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425945 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525946 request.method = "GET";
bncce36dca22015-04-21 22:11:235947 request.url = GURL(
5948 "http://www.example.org/csi?v=3&s=web&action=&"
5949 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5950 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5951 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525952 request.load_flags = 0;
5953
mmenkee65e7af2015-10-13 17:16:425954 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275955
[email protected]262eec82013-03-19 21:01:365956 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505957 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275958
[email protected]b4404c02009-04-10 16:38:525959 MockRead data_reads[] = {
5960 MockRead("HTTP/1.1 204 No Content\r\n"
5961 "Content-Length: 0\r\n"
5962 "Content-Type: text/html\r\n\r\n"),
5963 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065964 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525965 };
5966
[email protected]31a2bfe2010-02-09 08:03:395967 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075968 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525969
[email protected]49639fa2011-12-20 23:22:415970 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525971
[email protected]49639fa2011-12-20 23:22:415972 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425973 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525974
5975 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425976 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525977
[email protected]1c773ea12009-04-28 19:58:425978 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505979 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525980
[email protected]90499482013-06-01 00:39:505981 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525982 std::string status_line = response->headers->GetStatusLine();
5983 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5984
[email protected]90499482013-06-01 00:39:505985 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525986
5987 std::string response_data;
5988 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425989 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525990 EXPECT_EQ("", response_data);
5991
5992 // Empty the current queue. This is necessary because idle sockets are
5993 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345994 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525995
5996 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505997 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525998}
5999
[email protected]23e482282013-06-14 16:08:026000TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:066001 ScopedVector<UploadElementReader> element_readers;
6002 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:076003 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:276004
[email protected]1c773ea12009-04-28 19:58:426005 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516006 // Transaction 1: a GET request that succeeds. The socket is recycled
6007 // after use.
6008 request[0].method = "GET";
6009 request[0].url = GURL("http://www.google.com/");
6010 request[0].load_flags = 0;
6011 // Transaction 2: a POST request. Reuses the socket kept alive from
6012 // transaction 1. The first attempts fails when writing the POST data.
6013 // This causes the transaction to retry with a new socket. The second
6014 // attempt succeeds.
6015 request[1].method = "POST";
6016 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276017 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516018 request[1].load_flags = 0;
6019
mmenkee65e7af2015-10-13 17:16:426020 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516021
6022 // The first socket is used for transaction 1 and the first attempt of
6023 // transaction 2.
6024
6025 // The response of transaction 1.
6026 MockRead data_reads1[] = {
6027 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6028 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066029 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516030 };
6031 // The mock write results of transaction 1 and the first attempt of
6032 // transaction 2.
6033 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066034 MockWrite(SYNCHRONOUS, 64), // GET
6035 MockWrite(SYNCHRONOUS, 93), // POST
6036 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516037 };
[email protected]31a2bfe2010-02-09 08:03:396038 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6039 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516040
6041 // The second socket is used for the second attempt of transaction 2.
6042
6043 // The response of transaction 2.
6044 MockRead data_reads2[] = {
6045 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6046 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066047 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516048 };
6049 // The mock write results of the second attempt of transaction 2.
6050 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066051 MockWrite(SYNCHRONOUS, 93), // POST
6052 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516053 };
[email protected]31a2bfe2010-02-09 08:03:396054 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6055 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516056
[email protected]bb88e1d32013-05-03 23:11:076057 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6058 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516059
thestig9d3bb0c2015-01-24 00:49:516060 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516061 "hello world", "welcome"
6062 };
6063
6064 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:426065 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506066 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:516067
[email protected]49639fa2011-12-20 23:22:416068 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516069
[email protected]49639fa2011-12-20 23:22:416070 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426071 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:516072
6073 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426074 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516075
[email protected]1c773ea12009-04-28 19:58:426076 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506077 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:516078
[email protected]90499482013-06-01 00:39:506079 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:516080 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6081
6082 std::string response_data;
6083 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426084 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516085 EXPECT_EQ(kExpectedResponseData[i], response_data);
6086 }
6087}
[email protected]f9ee6b52008-11-08 06:46:236088
6089// Test the request-challenge-retry sequence for basic auth when there is
6090// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166091// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:026092TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426093 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236094 request.method = "GET";
bncce36dca22015-04-21 22:11:236095 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416096 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296097
mmenkee65e7af2015-10-13 17:16:426098 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276099 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416100 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276101
[email protected]a97cca42009-08-14 01:00:296102 // The password contains an escaped character -- for this test to pass it
6103 // will need to be unescaped by HttpNetworkTransaction.
6104 EXPECT_EQ("b%40r", request.url.password());
6105
[email protected]f9ee6b52008-11-08 06:46:236106 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236107 MockWrite(
6108 "GET / HTTP/1.1\r\n"
6109 "Host: www.example.org\r\n"
6110 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236111 };
6112
6113 MockRead data_reads1[] = {
6114 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6115 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6116 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066117 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236118 };
6119
[email protected]2262e3a2012-05-22 16:08:166120 // After the challenge above, the transaction will be restarted using the
6121 // identity from the url (foo, b@r) to answer the challenge.
6122 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236123 MockWrite(
6124 "GET / HTTP/1.1\r\n"
6125 "Host: www.example.org\r\n"
6126 "Connection: keep-alive\r\n"
6127 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166128 };
6129
6130 MockRead data_reads2[] = {
6131 MockRead("HTTP/1.0 200 OK\r\n"),
6132 MockRead("Content-Length: 100\r\n\r\n"),
6133 MockRead(SYNCHRONOUS, OK),
6134 };
6135
[email protected]31a2bfe2010-02-09 08:03:396136 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6137 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166138 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6139 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076140 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6141 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236142
[email protected]49639fa2011-12-20 23:22:416143 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:416144 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426145 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236146 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426147 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:166148 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6149
6150 TestCompletionCallback callback2;
6151 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6152 EXPECT_EQ(ERR_IO_PENDING, rv);
6153 rv = callback2.WaitForResult();
6154 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226155 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6156
[email protected]2262e3a2012-05-22 16:08:166157 const HttpResponseInfo* response = trans->GetResponseInfo();
6158 ASSERT_TRUE(response != NULL);
6159
6160 // There is no challenge info, since the identity in URL worked.
6161 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6162
6163 EXPECT_EQ(100, response->headers->GetContentLength());
6164
6165 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:346166 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166167}
6168
6169// Test the request-challenge-retry sequence for basic auth when there is an
6170// incorrect identity in the URL. The identity from the URL should be used only
6171// once.
[email protected]23e482282013-06-14 16:08:026172TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166173 HttpRequestInfo request;
6174 request.method = "GET";
6175 // Note: the URL has a username:password in it. The password "baz" is
6176 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236177 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166178
6179 request.load_flags = LOAD_NORMAL;
6180
mmenkee65e7af2015-10-13 17:16:426181 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:166182 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416183 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:166184
6185 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236186 MockWrite(
6187 "GET / HTTP/1.1\r\n"
6188 "Host: www.example.org\r\n"
6189 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166190 };
6191
6192 MockRead data_reads1[] = {
6193 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6194 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6195 MockRead("Content-Length: 10\r\n\r\n"),
6196 MockRead(SYNCHRONOUS, ERR_FAILED),
6197 };
6198
6199 // After the challenge above, the transaction will be restarted using the
6200 // identity from the url (foo, baz) to answer the challenge.
6201 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236202 MockWrite(
6203 "GET / HTTP/1.1\r\n"
6204 "Host: www.example.org\r\n"
6205 "Connection: keep-alive\r\n"
6206 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166207 };
6208
6209 MockRead data_reads2[] = {
6210 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6211 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6212 MockRead("Content-Length: 10\r\n\r\n"),
6213 MockRead(SYNCHRONOUS, ERR_FAILED),
6214 };
6215
6216 // After the challenge above, the transaction will be restarted using the
6217 // identity supplied by the user (foo, bar) to answer the challenge.
6218 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236219 MockWrite(
6220 "GET / HTTP/1.1\r\n"
6221 "Host: www.example.org\r\n"
6222 "Connection: keep-alive\r\n"
6223 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166224 };
6225
6226 MockRead data_reads3[] = {
6227 MockRead("HTTP/1.0 200 OK\r\n"),
6228 MockRead("Content-Length: 100\r\n\r\n"),
6229 MockRead(SYNCHRONOUS, OK),
6230 };
6231
6232 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6233 data_writes1, arraysize(data_writes1));
6234 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6235 data_writes2, arraysize(data_writes2));
6236 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6237 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076238 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6239 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6240 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166241
6242 TestCompletionCallback callback1;
6243
6244 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6245 EXPECT_EQ(ERR_IO_PENDING, rv);
6246
6247 rv = callback1.WaitForResult();
6248 EXPECT_EQ(OK, rv);
6249
6250 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6251 TestCompletionCallback callback2;
6252 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6253 EXPECT_EQ(ERR_IO_PENDING, rv);
6254 rv = callback2.WaitForResult();
6255 EXPECT_EQ(OK, rv);
6256 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6257
6258 const HttpResponseInfo* response = trans->GetResponseInfo();
6259 ASSERT_TRUE(response != NULL);
6260 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6261
6262 TestCompletionCallback callback3;
6263 rv = trans->RestartWithAuth(
6264 AuthCredentials(kFoo, kBar), callback3.callback());
6265 EXPECT_EQ(ERR_IO_PENDING, rv);
6266 rv = callback3.WaitForResult();
6267 EXPECT_EQ(OK, rv);
6268 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6269
6270 response = trans->GetResponseInfo();
6271 ASSERT_TRUE(response != NULL);
6272
6273 // There is no challenge info, since the identity worked.
6274 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6275
6276 EXPECT_EQ(100, response->headers->GetContentLength());
6277
[email protected]ea9dc9a2009-09-05 00:43:326278 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:346279 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326280}
6281
[email protected]2217aa22013-10-11 03:03:546282
6283// Test the request-challenge-retry sequence for basic auth when there is a
6284// correct identity in the URL, but its use is being suppressed. The identity
6285// from the URL should never be used.
6286TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
6287 HttpRequestInfo request;
6288 request.method = "GET";
bncce36dca22015-04-21 22:11:236289 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546290 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6291
mmenkee65e7af2015-10-13 17:16:426292 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:546293 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416294 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:546295
6296 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236297 MockWrite(
6298 "GET / HTTP/1.1\r\n"
6299 "Host: www.example.org\r\n"
6300 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546301 };
6302
6303 MockRead data_reads1[] = {
6304 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6305 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6306 MockRead("Content-Length: 10\r\n\r\n"),
6307 MockRead(SYNCHRONOUS, ERR_FAILED),
6308 };
6309
6310 // After the challenge above, the transaction will be restarted using the
6311 // identity supplied by the user, not the one in the URL, to answer the
6312 // challenge.
6313 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236314 MockWrite(
6315 "GET / HTTP/1.1\r\n"
6316 "Host: www.example.org\r\n"
6317 "Connection: keep-alive\r\n"
6318 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546319 };
6320
6321 MockRead data_reads3[] = {
6322 MockRead("HTTP/1.0 200 OK\r\n"),
6323 MockRead("Content-Length: 100\r\n\r\n"),
6324 MockRead(SYNCHRONOUS, OK),
6325 };
6326
6327 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6328 data_writes1, arraysize(data_writes1));
6329 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6330 data_writes3, arraysize(data_writes3));
6331 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6332 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6333
6334 TestCompletionCallback callback1;
6335 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6336 EXPECT_EQ(ERR_IO_PENDING, rv);
6337 rv = callback1.WaitForResult();
6338 EXPECT_EQ(OK, rv);
6339 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6340
6341 const HttpResponseInfo* response = trans->GetResponseInfo();
6342 ASSERT_TRUE(response != NULL);
6343 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6344
6345 TestCompletionCallback callback3;
6346 rv = trans->RestartWithAuth(
6347 AuthCredentials(kFoo, kBar), callback3.callback());
6348 EXPECT_EQ(ERR_IO_PENDING, rv);
6349 rv = callback3.WaitForResult();
6350 EXPECT_EQ(OK, rv);
6351 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6352
6353 response = trans->GetResponseInfo();
6354 ASSERT_TRUE(response != NULL);
6355
6356 // There is no challenge info, since the identity worked.
6357 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6358 EXPECT_EQ(100, response->headers->GetContentLength());
6359
6360 // Empty the current queue.
6361 base::MessageLoop::current()->RunUntilIdle();
6362}
6363
[email protected]f9ee6b52008-11-08 06:46:236364// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:026365TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
mmenkee65e7af2015-10-13 17:16:426366 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:236367
6368 // Transaction 1: authenticate (foo, bar) on MyRealm1
6369 {
[email protected]1c773ea12009-04-28 19:58:426370 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236371 request.method = "GET";
bncce36dca22015-04-21 22:11:236372 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:236373 request.load_flags = 0;
6374
[email protected]262eec82013-03-19 21:01:366375 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506376 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276377
[email protected]f9ee6b52008-11-08 06:46:236378 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236379 MockWrite(
6380 "GET /x/y/z HTTP/1.1\r\n"
6381 "Host: www.example.org\r\n"
6382 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236383 };
6384
6385 MockRead data_reads1[] = {
6386 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6387 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6388 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066389 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236390 };
6391
6392 // Resend with authorization (username=foo, password=bar)
6393 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236394 MockWrite(
6395 "GET /x/y/z HTTP/1.1\r\n"
6396 "Host: www.example.org\r\n"
6397 "Connection: keep-alive\r\n"
6398 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236399 };
6400
6401 // Sever accepts the authorization.
6402 MockRead data_reads2[] = {
6403 MockRead("HTTP/1.0 200 OK\r\n"),
6404 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066405 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236406 };
6407
[email protected]31a2bfe2010-02-09 08:03:396408 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6409 data_writes1, arraysize(data_writes1));
6410 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6411 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076412 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6413 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236414
[email protected]49639fa2011-12-20 23:22:416415 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236416
[email protected]49639fa2011-12-20 23:22:416417 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426418 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236419
6420 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426421 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236422
[email protected]1c773ea12009-04-28 19:58:426423 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506424 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046425 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236426
[email protected]49639fa2011-12-20 23:22:416427 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236428
[email protected]49639fa2011-12-20 23:22:416429 rv = trans->RestartWithAuth(
6430 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426431 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236432
6433 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426434 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236435
6436 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506437 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236438 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6439 EXPECT_EQ(100, response->headers->GetContentLength());
6440 }
6441
6442 // ------------------------------------------------------------------------
6443
6444 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
6445 {
[email protected]1c773ea12009-04-28 19:58:426446 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236447 request.method = "GET";
6448 // Note that Transaction 1 was at /x/y/z, so this is in the same
6449 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:236450 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:236451 request.load_flags = 0;
6452
[email protected]262eec82013-03-19 21:01:366453 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506454 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276455
[email protected]f9ee6b52008-11-08 06:46:236456 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236457 MockWrite(
6458 "GET /x/y/a/b HTTP/1.1\r\n"
6459 "Host: www.example.org\r\n"
6460 "Connection: keep-alive\r\n"
6461 // Send preemptive authorization for MyRealm1
6462 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236463 };
6464
6465 // The server didn't like the preemptive authorization, and
6466 // challenges us for a different realm (MyRealm2).
6467 MockRead data_reads1[] = {
6468 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6469 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
6470 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066471 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236472 };
6473
6474 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
6475 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236476 MockWrite(
6477 "GET /x/y/a/b HTTP/1.1\r\n"
6478 "Host: www.example.org\r\n"
6479 "Connection: keep-alive\r\n"
6480 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236481 };
6482
6483 // Sever accepts the authorization.
6484 MockRead data_reads2[] = {
6485 MockRead("HTTP/1.0 200 OK\r\n"),
6486 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066487 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236488 };
6489
[email protected]31a2bfe2010-02-09 08:03:396490 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6491 data_writes1, arraysize(data_writes1));
6492 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6493 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076494 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6495 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236496
[email protected]49639fa2011-12-20 23:22:416497 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236498
[email protected]49639fa2011-12-20 23:22:416499 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426500 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236501
6502 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426503 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236504
[email protected]1c773ea12009-04-28 19:58:426505 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506506 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046507 ASSERT_TRUE(response->auth_challenge.get());
6508 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:236509 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:046510 response->auth_challenge->challenger.ToString());
6511 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
6512 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:236513
[email protected]49639fa2011-12-20 23:22:416514 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236515
[email protected]49639fa2011-12-20 23:22:416516 rv = trans->RestartWithAuth(
6517 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426518 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236519
6520 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426521 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236522
6523 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506524 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236525 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6526 EXPECT_EQ(100, response->headers->GetContentLength());
6527 }
6528
6529 // ------------------------------------------------------------------------
6530
6531 // Transaction 3: Resend a request in MyRealm's protection space --
6532 // succeed with preemptive authorization.
6533 {
[email protected]1c773ea12009-04-28 19:58:426534 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236535 request.method = "GET";
bncce36dca22015-04-21 22:11:236536 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:236537 request.load_flags = 0;
6538
[email protected]262eec82013-03-19 21:01:366539 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506540 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276541
[email protected]f9ee6b52008-11-08 06:46:236542 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236543 MockWrite(
6544 "GET /x/y/z2 HTTP/1.1\r\n"
6545 "Host: www.example.org\r\n"
6546 "Connection: keep-alive\r\n"
6547 // The authorization for MyRealm1 gets sent preemptively
6548 // (since the url is in the same protection space)
6549 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236550 };
6551
6552 // Sever accepts the preemptive authorization
6553 MockRead data_reads1[] = {
6554 MockRead("HTTP/1.0 200 OK\r\n"),
6555 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066556 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236557 };
6558
[email protected]31a2bfe2010-02-09 08:03:396559 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6560 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076561 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:236562
[email protected]49639fa2011-12-20 23:22:416563 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236564
[email protected]49639fa2011-12-20 23:22:416565 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426566 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236567
6568 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426569 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236570
[email protected]1c773ea12009-04-28 19:58:426571 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506572 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236573
6574 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6575 EXPECT_EQ(100, response->headers->GetContentLength());
6576 }
6577
6578 // ------------------------------------------------------------------------
6579
6580 // Transaction 4: request another URL in MyRealm (however the
6581 // url is not known to belong to the protection space, so no pre-auth).
6582 {
[email protected]1c773ea12009-04-28 19:58:426583 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236584 request.method = "GET";
bncce36dca22015-04-21 22:11:236585 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:236586 request.load_flags = 0;
6587
[email protected]262eec82013-03-19 21:01:366588 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506589 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276590
[email protected]f9ee6b52008-11-08 06:46:236591 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236592 MockWrite(
6593 "GET /x/1 HTTP/1.1\r\n"
6594 "Host: www.example.org\r\n"
6595 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236596 };
6597
6598 MockRead data_reads1[] = {
6599 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6600 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6601 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066602 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236603 };
6604
6605 // Resend with authorization from MyRealm's cache.
6606 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236607 MockWrite(
6608 "GET /x/1 HTTP/1.1\r\n"
6609 "Host: www.example.org\r\n"
6610 "Connection: keep-alive\r\n"
6611 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236612 };
6613
6614 // Sever accepts the authorization.
6615 MockRead data_reads2[] = {
6616 MockRead("HTTP/1.0 200 OK\r\n"),
6617 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066618 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236619 };
6620
[email protected]31a2bfe2010-02-09 08:03:396621 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6622 data_writes1, arraysize(data_writes1));
6623 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6624 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076625 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6626 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236627
[email protected]49639fa2011-12-20 23:22:416628 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236629
[email protected]49639fa2011-12-20 23:22:416630 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426631 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236632
6633 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426634 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236635
[email protected]0757e7702009-03-27 04:00:226636 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416637 TestCompletionCallback callback2;
6638 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426639 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226640 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426641 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226642 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6643
[email protected]1c773ea12009-04-28 19:58:426644 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506645 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236646 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6647 EXPECT_EQ(100, response->headers->GetContentLength());
6648 }
6649
6650 // ------------------------------------------------------------------------
6651
6652 // Transaction 5: request a URL in MyRealm, but the server rejects the
6653 // cached identity. Should invalidate and re-prompt.
6654 {
[email protected]1c773ea12009-04-28 19:58:426655 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236656 request.method = "GET";
bncce36dca22015-04-21 22:11:236657 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:236658 request.load_flags = 0;
6659
[email protected]262eec82013-03-19 21:01:366660 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506661 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276662
[email protected]f9ee6b52008-11-08 06:46:236663 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236664 MockWrite(
6665 "GET /p/q/t HTTP/1.1\r\n"
6666 "Host: www.example.org\r\n"
6667 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236668 };
6669
6670 MockRead data_reads1[] = {
6671 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6672 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6673 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066674 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236675 };
6676
6677 // Resend with authorization from cache for MyRealm.
6678 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236679 MockWrite(
6680 "GET /p/q/t HTTP/1.1\r\n"
6681 "Host: www.example.org\r\n"
6682 "Connection: keep-alive\r\n"
6683 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236684 };
6685
6686 // Sever rejects the authorization.
6687 MockRead data_reads2[] = {
6688 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6689 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6690 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066691 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236692 };
6693
6694 // At this point we should prompt for new credentials for MyRealm.
6695 // Restart with username=foo3, password=foo4.
6696 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236697 MockWrite(
6698 "GET /p/q/t HTTP/1.1\r\n"
6699 "Host: www.example.org\r\n"
6700 "Connection: keep-alive\r\n"
6701 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236702 };
6703
6704 // Sever accepts the authorization.
6705 MockRead data_reads3[] = {
6706 MockRead("HTTP/1.0 200 OK\r\n"),
6707 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066708 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236709 };
6710
[email protected]31a2bfe2010-02-09 08:03:396711 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6712 data_writes1, arraysize(data_writes1));
6713 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6714 data_writes2, arraysize(data_writes2));
6715 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6716 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076717 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6718 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6719 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236720
[email protected]49639fa2011-12-20 23:22:416721 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236722
[email protected]49639fa2011-12-20 23:22:416723 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426724 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236725
6726 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426727 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236728
[email protected]0757e7702009-03-27 04:00:226729 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416730 TestCompletionCallback callback2;
6731 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426732 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226733 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426734 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226735 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6736
[email protected]1c773ea12009-04-28 19:58:426737 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506738 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046739 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236740
[email protected]49639fa2011-12-20 23:22:416741 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236742
[email protected]49639fa2011-12-20 23:22:416743 rv = trans->RestartWithAuth(
6744 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426745 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236746
[email protected]0757e7702009-03-27 04:00:226747 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426748 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236749
6750 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506751 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236752 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6753 EXPECT_EQ(100, response->headers->GetContentLength());
6754 }
6755}
[email protected]89ceba9a2009-03-21 03:46:066756
[email protected]3c32c5f2010-05-18 15:18:126757// Tests that nonce count increments when multiple auth attempts
6758// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026759TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446760 HttpAuthHandlerDigest::Factory* digest_factory =
6761 new HttpAuthHandlerDigest::Factory();
6762 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6763 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6764 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076765 session_deps_.http_auth_handler_factory.reset(digest_factory);
mmenkee65e7af2015-10-13 17:16:426766 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126767
6768 // Transaction 1: authenticate (foo, bar) on MyRealm1
6769 {
[email protected]3c32c5f2010-05-18 15:18:126770 HttpRequestInfo request;
6771 request.method = "GET";
bncce36dca22015-04-21 22:11:236772 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126773 request.load_flags = 0;
6774
[email protected]262eec82013-03-19 21:01:366775 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506776 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276777
[email protected]3c32c5f2010-05-18 15:18:126778 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236779 MockWrite(
6780 "GET /x/y/z HTTP/1.1\r\n"
6781 "Host: www.example.org\r\n"
6782 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126783 };
6784
6785 MockRead data_reads1[] = {
6786 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6787 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6788 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066789 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126790 };
6791
6792 // Resend with authorization (username=foo, password=bar)
6793 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236794 MockWrite(
6795 "GET /x/y/z HTTP/1.1\r\n"
6796 "Host: www.example.org\r\n"
6797 "Connection: keep-alive\r\n"
6798 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6799 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6800 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6801 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126802 };
6803
6804 // Sever accepts the authorization.
6805 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:086806 MockRead("HTTP/1.0 200 OK\r\n"),
6807 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126808 };
6809
6810 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6811 data_writes1, arraysize(data_writes1));
6812 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6813 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076814 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6815 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126816
[email protected]49639fa2011-12-20 23:22:416817 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126818
[email protected]49639fa2011-12-20 23:22:416819 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126820 EXPECT_EQ(ERR_IO_PENDING, rv);
6821
6822 rv = callback1.WaitForResult();
6823 EXPECT_EQ(OK, rv);
6824
6825 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506826 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046827 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126828
[email protected]49639fa2011-12-20 23:22:416829 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126830
[email protected]49639fa2011-12-20 23:22:416831 rv = trans->RestartWithAuth(
6832 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126833 EXPECT_EQ(ERR_IO_PENDING, rv);
6834
6835 rv = callback2.WaitForResult();
6836 EXPECT_EQ(OK, rv);
6837
6838 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506839 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126840 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6841 }
6842
6843 // ------------------------------------------------------------------------
6844
6845 // Transaction 2: Request another resource in digestive's protection space.
6846 // This will preemptively add an Authorization header which should have an
6847 // "nc" value of 2 (as compared to 1 in the first use.
6848 {
[email protected]3c32c5f2010-05-18 15:18:126849 HttpRequestInfo request;
6850 request.method = "GET";
6851 // Note that Transaction 1 was at /x/y/z, so this is in the same
6852 // protection space as digest.
bncce36dca22015-04-21 22:11:236853 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126854 request.load_flags = 0;
6855
[email protected]262eec82013-03-19 21:01:366856 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506857 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276858
[email protected]3c32c5f2010-05-18 15:18:126859 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236860 MockWrite(
6861 "GET /x/y/a/b HTTP/1.1\r\n"
6862 "Host: www.example.org\r\n"
6863 "Connection: keep-alive\r\n"
6864 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6865 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6866 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6867 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126868 };
6869
6870 // Sever accepts the authorization.
6871 MockRead data_reads1[] = {
6872 MockRead("HTTP/1.0 200 OK\r\n"),
6873 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066874 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126875 };
6876
6877 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6878 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076879 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126880
[email protected]49639fa2011-12-20 23:22:416881 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126882
[email protected]49639fa2011-12-20 23:22:416883 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126884 EXPECT_EQ(ERR_IO_PENDING, rv);
6885
6886 rv = callback1.WaitForResult();
6887 EXPECT_EQ(OK, rv);
6888
6889 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506890 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126891 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6892 }
6893}
6894
[email protected]89ceba9a2009-03-21 03:46:066895// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026896TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066897 // Create a transaction (the dependencies aren't important).
mmenkee65e7af2015-10-13 17:16:426898 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406899 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416900 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066901
6902 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066903 trans->read_buf_ = new IOBuffer(15);
6904 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206905 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066906
6907 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146908 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576909 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086910 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576911 response->response_time = base::Time::Now();
6912 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066913
6914 { // Setup state for response_.vary_data
6915 HttpRequestInfo request;
6916 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6917 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276918 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436919 request.extra_headers.SetHeader("Foo", "1");
6920 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506921 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066922 }
6923
6924 // Cause the above state to be reset.
6925 trans->ResetStateForRestart();
6926
6927 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076928 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066929 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206930 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576931 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6932 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046933 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086934 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576935 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066936}
6937
[email protected]bacff652009-03-31 17:50:336938// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026939TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336940 HttpRequestInfo request;
6941 request.method = "GET";
bncce36dca22015-04-21 22:11:236942 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336943 request.load_flags = 0;
6944
mmenkee65e7af2015-10-13 17:16:426945 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276946 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416947 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276948
[email protected]bacff652009-03-31 17:50:336949 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236950 MockWrite(
6951 "GET / HTTP/1.1\r\n"
6952 "Host: www.example.org\r\n"
6953 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336954 };
6955
6956 MockRead data_reads[] = {
6957 MockRead("HTTP/1.0 200 OK\r\n"),
6958 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6959 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066960 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336961 };
6962
[email protected]5ecc992a42009-11-11 01:41:596963 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396964 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6965 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066966 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6967 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336968
[email protected]bb88e1d32013-05-03 23:11:076969 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6970 session_deps_.socket_factory->AddSocketDataProvider(&data);
6971 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6972 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336973
[email protected]49639fa2011-12-20 23:22:416974 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336975
[email protected]49639fa2011-12-20 23:22:416976 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336977 EXPECT_EQ(ERR_IO_PENDING, rv);
6978
6979 rv = callback.WaitForResult();
6980 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6981
[email protected]49639fa2011-12-20 23:22:416982 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336983 EXPECT_EQ(ERR_IO_PENDING, rv);
6984
6985 rv = callback.WaitForResult();
6986 EXPECT_EQ(OK, rv);
6987
6988 const HttpResponseInfo* response = trans->GetResponseInfo();
6989
[email protected]fe2255a2011-09-20 19:37:506990 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336991 EXPECT_EQ(100, response->headers->GetContentLength());
6992}
6993
6994// Test HTTPS connections to a site with a bad certificate, going through a
6995// proxy
[email protected]23e482282013-06-14 16:08:026996TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:036997 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:336998
6999 HttpRequestInfo request;
7000 request.method = "GET";
bncce36dca22015-04-21 22:11:237001 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337002 request.load_flags = 0;
7003
7004 MockWrite proxy_writes[] = {
bncce36dca22015-04-21 22:11:237005 MockWrite(
7006 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7007 "Host: www.example.org\r\n"
7008 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337009 };
7010
7011 MockRead proxy_reads[] = {
7012 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067013 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337014 };
7015
7016 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237017 MockWrite(
7018 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7019 "Host: www.example.org\r\n"
7020 "Proxy-Connection: keep-alive\r\n\r\n"),
7021 MockWrite(
7022 "GET / HTTP/1.1\r\n"
7023 "Host: www.example.org\r\n"
7024 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337025 };
7026
7027 MockRead data_reads[] = {
7028 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7029 MockRead("HTTP/1.0 200 OK\r\n"),
7030 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7031 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067032 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337033 };
7034
[email protected]31a2bfe2010-02-09 08:03:397035 StaticSocketDataProvider ssl_bad_certificate(
7036 proxy_reads, arraysize(proxy_reads),
7037 proxy_writes, arraysize(proxy_writes));
7038 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7039 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067040 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7041 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337042
[email protected]bb88e1d32013-05-03 23:11:077043 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7044 session_deps_.socket_factory->AddSocketDataProvider(&data);
7045 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7046 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337047
[email protected]49639fa2011-12-20 23:22:417048 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337049
7050 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077051 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337052
mmenkee65e7af2015-10-13 17:16:427053 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:407054 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417055 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:337056
[email protected]49639fa2011-12-20 23:22:417057 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:337058 EXPECT_EQ(ERR_IO_PENDING, rv);
7059
7060 rv = callback.WaitForResult();
7061 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7062
[email protected]49639fa2011-12-20 23:22:417063 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337064 EXPECT_EQ(ERR_IO_PENDING, rv);
7065
7066 rv = callback.WaitForResult();
7067 EXPECT_EQ(OK, rv);
7068
7069 const HttpResponseInfo* response = trans->GetResponseInfo();
7070
[email protected]fe2255a2011-09-20 19:37:507071 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:337072 EXPECT_EQ(100, response->headers->GetContentLength());
7073 }
7074}
7075
[email protected]2df19bb2010-08-25 20:13:467076
7077// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:027078TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037079 session_deps_.proxy_service =
7080 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517081 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077082 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467083
7084 HttpRequestInfo request;
7085 request.method = "GET";
bncce36dca22015-04-21 22:11:237086 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467087 request.load_flags = 0;
7088
7089 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237090 MockWrite(
7091 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7092 "Host: www.example.org\r\n"
7093 "Proxy-Connection: keep-alive\r\n\r\n"),
7094 MockWrite(
7095 "GET / HTTP/1.1\r\n"
7096 "Host: www.example.org\r\n"
7097 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467098 };
7099
7100 MockRead data_reads[] = {
7101 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7102 MockRead("HTTP/1.1 200 OK\r\n"),
7103 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7104 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067105 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467106 };
7107
7108 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7109 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067110 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7111 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467112
[email protected]bb88e1d32013-05-03 23:11:077113 session_deps_.socket_factory->AddSocketDataProvider(&data);
7114 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7115 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467116
[email protected]49639fa2011-12-20 23:22:417117 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467118
mmenkee65e7af2015-10-13 17:16:427119 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467120 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417121 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467122
[email protected]49639fa2011-12-20 23:22:417123 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467124 EXPECT_EQ(ERR_IO_PENDING, rv);
7125
7126 rv = callback.WaitForResult();
7127 EXPECT_EQ(OK, rv);
7128 const HttpResponseInfo* response = trans->GetResponseInfo();
7129
[email protected]fe2255a2011-09-20 19:37:507130 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467131
7132 EXPECT_TRUE(response->headers->IsKeepAlive());
7133 EXPECT_EQ(200, response->headers->response_code());
7134 EXPECT_EQ(100, response->headers->GetContentLength());
7135 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207136
7137 LoadTimingInfo load_timing_info;
7138 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7139 TestLoadTimingNotReusedWithPac(load_timing_info,
7140 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467141}
7142
[email protected]511f6f52010-12-17 03:58:297143// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027144TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037145 session_deps_.proxy_service =
7146 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517147 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077148 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297149
7150 HttpRequestInfo request;
7151 request.method = "GET";
bncce36dca22015-04-21 22:11:237152 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297153 request.load_flags = 0;
7154
7155 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237156 MockWrite(
7157 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7158 "Host: www.example.org\r\n"
7159 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297160 };
7161
7162 MockRead data_reads[] = {
7163 MockRead("HTTP/1.1 302 Redirect\r\n"),
7164 MockRead("Location: http://login.example.com/\r\n"),
7165 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067166 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297167 };
7168
7169 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7170 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067171 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297172
[email protected]bb88e1d32013-05-03 23:11:077173 session_deps_.socket_factory->AddSocketDataProvider(&data);
7174 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297175
[email protected]49639fa2011-12-20 23:22:417176 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297177
mmenkee65e7af2015-10-13 17:16:427178 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297179 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417180 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297181
[email protected]49639fa2011-12-20 23:22:417182 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297183 EXPECT_EQ(ERR_IO_PENDING, rv);
7184
7185 rv = callback.WaitForResult();
7186 EXPECT_EQ(OK, rv);
7187 const HttpResponseInfo* response = trans->GetResponseInfo();
7188
[email protected]fe2255a2011-09-20 19:37:507189 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:297190
7191 EXPECT_EQ(302, response->headers->response_code());
7192 std::string url;
7193 EXPECT_TRUE(response->headers->IsRedirect(&url));
7194 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207195
7196 // In the case of redirects from proxies, HttpNetworkTransaction returns
7197 // timing for the proxy connection instead of the connection to the host,
7198 // and no send / receive times.
7199 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7200 LoadTimingInfo load_timing_info;
7201 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7202
7203 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:297204 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207205
7206 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7207 EXPECT_LE(load_timing_info.proxy_resolve_start,
7208 load_timing_info.proxy_resolve_end);
7209 EXPECT_LE(load_timing_info.proxy_resolve_end,
7210 load_timing_info.connect_timing.connect_start);
7211 ExpectConnectTimingHasTimes(
7212 load_timing_info.connect_timing,
7213 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7214
7215 EXPECT_TRUE(load_timing_info.send_start.is_null());
7216 EXPECT_TRUE(load_timing_info.send_end.is_null());
7217 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297218}
7219
7220// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027221TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037222 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297223
7224 HttpRequestInfo request;
7225 request.method = "GET";
bncce36dca22015-04-21 22:11:237226 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297227 request.load_flags = 0;
7228
lgarrona91df87f2014-12-05 00:51:347229 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237230 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:207231 scoped_ptr<SpdyFrame> goaway(
7232 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297233 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137234 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
7235 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297236 };
7237
7238 static const char* const kExtraHeaders[] = {
7239 "location",
7240 "http://login.example.com/",
7241 };
[email protected]ff98d7f02012-03-22 21:44:197242 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:027243 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:297244 arraysize(kExtraHeaders)/2, 1));
7245 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137246 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297247 };
7248
rch8e6c6c42015-05-01 14:05:137249 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7250 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067251 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:027252 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:297253
[email protected]bb88e1d32013-05-03 23:11:077254 session_deps_.socket_factory->AddSocketDataProvider(&data);
7255 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297256
[email protected]49639fa2011-12-20 23:22:417257 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297258
mmenkee65e7af2015-10-13 17:16:427259 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297260 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417261 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297262
[email protected]49639fa2011-12-20 23:22:417263 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297264 EXPECT_EQ(ERR_IO_PENDING, rv);
7265
7266 rv = callback.WaitForResult();
7267 EXPECT_EQ(OK, rv);
7268 const HttpResponseInfo* response = trans->GetResponseInfo();
7269
[email protected]fe2255a2011-09-20 19:37:507270 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:297271
7272 EXPECT_EQ(302, response->headers->response_code());
7273 std::string url;
7274 EXPECT_TRUE(response->headers->IsRedirect(&url));
7275 EXPECT_EQ("http://login.example.com/", url);
7276}
7277
[email protected]4eddbc732012-08-09 05:40:177278// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027279TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177280 ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037281 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297282
7283 HttpRequestInfo request;
7284 request.method = "GET";
bncce36dca22015-04-21 22:11:237285 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297286 request.load_flags = 0;
7287
7288 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237289 MockWrite(
7290 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7291 "Host: www.example.org\r\n"
7292 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297293 };
7294
7295 MockRead data_reads[] = {
7296 MockRead("HTTP/1.1 404 Not Found\r\n"),
7297 MockRead("Content-Length: 23\r\n\r\n"),
7298 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067299 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297300 };
7301
7302 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7303 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067304 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297305
[email protected]bb88e1d32013-05-03 23:11:077306 session_deps_.socket_factory->AddSocketDataProvider(&data);
7307 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297308
[email protected]49639fa2011-12-20 23:22:417309 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297310
mmenkee65e7af2015-10-13 17:16:427311 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297312 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417313 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297314
[email protected]49639fa2011-12-20 23:22:417315 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297316 EXPECT_EQ(ERR_IO_PENDING, rv);
7317
7318 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177319 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297320
[email protected]4eddbc732012-08-09 05:40:177321 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297322}
7323
[email protected]4eddbc732012-08-09 05:40:177324// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027325TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177326 ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037327 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297328
7329 HttpRequestInfo request;
7330 request.method = "GET";
bncce36dca22015-04-21 22:11:237331 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297332 request.load_flags = 0;
7333
lgarrona91df87f2014-12-05 00:51:347334 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237335 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:207336 scoped_ptr<SpdyFrame> rst(
7337 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297338 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137339 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:297340 };
7341
7342 static const char* const kExtraHeaders[] = {
7343 "location",
7344 "http://login.example.com/",
7345 };
[email protected]ff98d7f02012-03-22 21:44:197346 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:027347 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:297348 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:197349 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:027350 spdy_util_.ConstructSpdyBodyFrame(
7351 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297352 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137353 CreateMockRead(*resp.get(), 1),
7354 CreateMockRead(*body.get(), 2),
7355 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297356 };
7357
rch8e6c6c42015-05-01 14:05:137358 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7359 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067360 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:027361 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:297362
[email protected]bb88e1d32013-05-03 23:11:077363 session_deps_.socket_factory->AddSocketDataProvider(&data);
7364 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297365
[email protected]49639fa2011-12-20 23:22:417366 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297367
mmenkee65e7af2015-10-13 17:16:427368 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297369 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417370 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297371
[email protected]49639fa2011-12-20 23:22:417372 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297373 EXPECT_EQ(ERR_IO_PENDING, rv);
7374
7375 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177376 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297377
[email protected]4eddbc732012-08-09 05:40:177378 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297379}
7380
[email protected]0c5fb722012-02-28 11:50:357381// Test the request-challenge-retry sequence for basic auth, through
7382// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:027383TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:357384 HttpRequestInfo request;
7385 request.method = "GET";
bncce36dca22015-04-21 22:11:237386 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:357387 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:297388 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:357389
7390 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037391 session_deps_.proxy_service =
7392 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:517393 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077394 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:427395 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:357396
7397 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:347398 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237399 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:207400 scoped_ptr<SpdyFrame> rst(
7401 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:357402
7403 // After calling trans->RestartWithAuth(), this is the request we should
7404 // be issuing -- the final header line contains the credentials.
7405 const char* const kAuthCredentials[] = {
7406 "proxy-authorization", "Basic Zm9vOmJhcg==",
7407 };
[email protected]fba2dbde2013-05-24 16:09:017408 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:347409 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:237410 HostPortPair("www.example.org", 443)));
7411 // fetch https://www.example.org/ via HTTP
7412 const char get[] =
7413 "GET / HTTP/1.1\r\n"
7414 "Host: www.example.org\r\n"
7415 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:197416 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:027417 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:357418
7419 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137420 CreateMockWrite(*req, 0, ASYNC),
7421 CreateMockWrite(*rst, 2, ASYNC),
7422 CreateMockWrite(*connect2, 3),
7423 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:357424 };
7425
7426 // The proxy responds to the connect with a 407, using a persistent
7427 // connection.
thestig9d3bb0c2015-01-24 00:49:517428 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:357429 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:357430 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
7431 };
[email protected]745aa9c2014-06-27 02:21:297432 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
7433 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:357434
[email protected]23e482282013-06-14 16:08:027435 scoped_ptr<SpdyFrame> conn_resp(
7436 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:357437 const char resp[] = "HTTP/1.1 200 OK\r\n"
7438 "Content-Length: 5\r\n\r\n";
7439
[email protected]ff98d7f02012-03-22 21:44:197440 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:027441 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:197442 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:027443 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:357444 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137445 CreateMockRead(*conn_auth_resp, 1, ASYNC),
7446 CreateMockRead(*conn_resp, 4, ASYNC),
7447 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
7448 CreateMockRead(*wrapped_body, 7, ASYNC),
7449 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:357450 };
7451
rch8e6c6c42015-05-01 14:05:137452 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7453 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077454 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:357455 // Negotiate SPDY to the proxy
7456 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027457 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077458 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:357459 // Vanilla SSL to the server
7460 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077461 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:357462
7463 TestCompletionCallback callback1;
7464
[email protected]262eec82013-03-19 21:01:367465 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507466 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:357467
7468 int rv = trans->Start(&request, callback1.callback(), log.bound());
7469 EXPECT_EQ(ERR_IO_PENDING, rv);
7470
7471 rv = callback1.WaitForResult();
7472 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:467473 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:357474 log.GetEntries(&entries);
7475 size_t pos = ExpectLogContainsSomewhere(
7476 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
7477 NetLog::PHASE_NONE);
7478 ExpectLogContainsSomewhere(
7479 entries, pos,
7480 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
7481 NetLog::PHASE_NONE);
7482
7483 const HttpResponseInfo* response = trans->GetResponseInfo();
7484 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507485 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:357486 EXPECT_EQ(407, response->headers->response_code());
7487 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7488 EXPECT_TRUE(response->auth_challenge.get() != NULL);
7489 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
7490
7491 TestCompletionCallback callback2;
7492
7493 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
7494 callback2.callback());
7495 EXPECT_EQ(ERR_IO_PENDING, rv);
7496
7497 rv = callback2.WaitForResult();
7498 EXPECT_EQ(OK, rv);
7499
7500 response = trans->GetResponseInfo();
7501 ASSERT_TRUE(response != NULL);
7502
7503 EXPECT_TRUE(response->headers->IsKeepAlive());
7504 EXPECT_EQ(200, response->headers->response_code());
7505 EXPECT_EQ(5, response->headers->GetContentLength());
7506 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7507
7508 // The password prompt info should not be set.
7509 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7510
[email protected]029c83b62013-01-24 05:28:207511 LoadTimingInfo load_timing_info;
7512 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7513 TestLoadTimingNotReusedWithPac(load_timing_info,
7514 CONNECT_TIMING_HAS_SSL_TIMES);
7515
[email protected]0c5fb722012-02-28 11:50:357516 trans.reset();
7517 session->CloseAllConnections();
7518}
7519
[email protected]7c6f7ba2012-04-03 04:09:297520// Test that an explicitly trusted SPDY proxy can push a resource from an
7521// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:027522TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:297523 HttpRequestInfo request;
7524 HttpRequestInfo push_request;
7525
[email protected]7c6f7ba2012-04-03 04:09:297526 request.method = "GET";
bncce36dca22015-04-21 22:11:237527 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:297528 push_request.method = "GET";
7529 push_request.url = GURL("http://www.another-origin.com/foo.dat");
7530
[email protected]7c6f7ba2012-04-03 04:09:297531 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037532 session_deps_.proxy_service =
7533 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:517534 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077535 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507536
7537 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:077538 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:507539
mmenkee65e7af2015-10-13 17:16:427540 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:297541
[email protected]cdf8f7e72013-05-23 10:56:467542 scoped_ptr<SpdyFrame> stream1_syn(
7543 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:297544
7545 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137546 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:297547 };
7548
7549 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027550 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:297551
7552 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027553 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:297554
7555 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027556 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:297557 0,
7558 2,
7559 1,
7560 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:437561 const char kPushedData[] = "pushed";
7562 scoped_ptr<SpdyFrame> stream2_body(
7563 spdy_util_.ConstructSpdyBodyFrame(
7564 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:297565
7566 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137567 CreateMockRead(*stream1_reply, 1, ASYNC),
7568 CreateMockRead(*stream2_syn, 2, ASYNC),
7569 CreateMockRead(*stream1_body, 3, ASYNC),
7570 CreateMockRead(*stream2_body, 4, ASYNC),
7571 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:297572 };
7573
rch8e6c6c42015-05-01 14:05:137574 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7575 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077576 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:297577 // Negotiate SPDY to the proxy
7578 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027579 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077580 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:297581
[email protected]262eec82013-03-19 21:01:367582 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507583 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:297584 TestCompletionCallback callback;
7585 int rv = trans->Start(&request, callback.callback(), log.bound());
7586 EXPECT_EQ(ERR_IO_PENDING, rv);
7587
7588 rv = callback.WaitForResult();
7589 EXPECT_EQ(OK, rv);
7590 const HttpResponseInfo* response = trans->GetResponseInfo();
7591
[email protected]262eec82013-03-19 21:01:367592 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:507593 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7594 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:297595 EXPECT_EQ(ERR_IO_PENDING, rv);
7596
7597 rv = callback.WaitForResult();
7598 EXPECT_EQ(OK, rv);
7599 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
7600
7601 ASSERT_TRUE(response != NULL);
7602 EXPECT_TRUE(response->headers->IsKeepAlive());
7603
7604 EXPECT_EQ(200, response->headers->response_code());
7605 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7606
7607 std::string response_data;
7608 rv = ReadTransaction(trans.get(), &response_data);
7609 EXPECT_EQ(OK, rv);
7610 EXPECT_EQ("hello!", response_data);
7611
[email protected]029c83b62013-01-24 05:28:207612 LoadTimingInfo load_timing_info;
7613 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7614 TestLoadTimingNotReusedWithPac(load_timing_info,
7615 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7616
[email protected]7c6f7ba2012-04-03 04:09:297617 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:507618 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:297619 EXPECT_EQ(200, push_response->headers->response_code());
7620
7621 rv = ReadTransaction(push_trans.get(), &response_data);
7622 EXPECT_EQ(OK, rv);
7623 EXPECT_EQ("pushed", response_data);
7624
[email protected]029c83b62013-01-24 05:28:207625 LoadTimingInfo push_load_timing_info;
7626 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
7627 TestLoadTimingReusedWithPac(push_load_timing_info);
7628 // The transactions should share a socket ID, despite being for different
7629 // origins.
7630 EXPECT_EQ(load_timing_info.socket_log_id,
7631 push_load_timing_info.socket_log_id);
7632
[email protected]7c6f7ba2012-04-03 04:09:297633 trans.reset();
7634 push_trans.reset();
7635 session->CloseAllConnections();
7636}
7637
[email protected]8c843192012-04-05 07:15:007638// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:027639TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:007640 HttpRequestInfo request;
7641
7642 request.method = "GET";
bncce36dca22015-04-21 22:11:237643 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:007644
[email protected]8c843192012-04-05 07:15:007645 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037646 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:517647 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077648 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507649
7650 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:077651 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:507652
mmenkee65e7af2015-10-13 17:16:427653 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:007654
[email protected]cdf8f7e72013-05-23 10:56:467655 scoped_ptr<SpdyFrame> stream1_syn(
7656 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:007657
7658 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:207659 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:007660
7661 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137662 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:007663 };
7664
7665 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027666 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:007667
7668 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027669 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:007670
7671 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027672 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:007673 0,
7674 2,
7675 1,
7676 "https://www.another-origin.com/foo.dat"));
7677
7678 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137679 CreateMockRead(*stream1_reply, 1, ASYNC),
7680 CreateMockRead(*stream2_syn, 2, ASYNC),
7681 CreateMockRead(*stream1_body, 4, ASYNC),
7682 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:007683 };
7684
rch8e6c6c42015-05-01 14:05:137685 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7686 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077687 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007688 // Negotiate SPDY to the proxy
7689 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027690 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077691 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007692
[email protected]262eec82013-03-19 21:01:367693 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507694 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007695 TestCompletionCallback callback;
7696 int rv = trans->Start(&request, callback.callback(), log.bound());
7697 EXPECT_EQ(ERR_IO_PENDING, rv);
7698
7699 rv = callback.WaitForResult();
7700 EXPECT_EQ(OK, rv);
7701 const HttpResponseInfo* response = trans->GetResponseInfo();
7702
7703 ASSERT_TRUE(response != NULL);
7704 EXPECT_TRUE(response->headers->IsKeepAlive());
7705
7706 EXPECT_EQ(200, response->headers->response_code());
7707 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7708
7709 std::string response_data;
7710 rv = ReadTransaction(trans.get(), &response_data);
7711 EXPECT_EQ(OK, rv);
7712 EXPECT_EQ("hello!", response_data);
7713
7714 trans.reset();
7715 session->CloseAllConnections();
7716}
7717
[email protected]2df19bb2010-08-25 20:13:467718// Test HTTPS connections to a site with a bad certificate, going through an
7719// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027720TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037721 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:467722
7723 HttpRequestInfo request;
7724 request.method = "GET";
bncce36dca22015-04-21 22:11:237725 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467726 request.load_flags = 0;
7727
7728 // Attempt to fetch the URL from a server with a bad cert
7729 MockWrite bad_cert_writes[] = {
bncce36dca22015-04-21 22:11:237730 MockWrite(
7731 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7732 "Host: www.example.org\r\n"
7733 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467734 };
7735
7736 MockRead bad_cert_reads[] = {
7737 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067738 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467739 };
7740
7741 // Attempt to fetch the URL with a good cert
7742 MockWrite good_data_writes[] = {
bncce36dca22015-04-21 22:11:237743 MockWrite(
7744 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7745 "Host: www.example.org\r\n"
7746 "Proxy-Connection: keep-alive\r\n\r\n"),
7747 MockWrite(
7748 "GET / HTTP/1.1\r\n"
7749 "Host: www.example.org\r\n"
7750 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467751 };
7752
7753 MockRead good_cert_reads[] = {
7754 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7755 MockRead("HTTP/1.0 200 OK\r\n"),
7756 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7757 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067758 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467759 };
7760
7761 StaticSocketDataProvider ssl_bad_certificate(
7762 bad_cert_reads, arraysize(bad_cert_reads),
7763 bad_cert_writes, arraysize(bad_cert_writes));
7764 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7765 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067766 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7767 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467768
7769 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077770 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7771 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7772 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467773
7774 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077775 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7776 session_deps_.socket_factory->AddSocketDataProvider(&data);
7777 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467778
[email protected]49639fa2011-12-20 23:22:417779 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467780
mmenkee65e7af2015-10-13 17:16:427781 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467782 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417783 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467784
[email protected]49639fa2011-12-20 23:22:417785 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467786 EXPECT_EQ(ERR_IO_PENDING, rv);
7787
7788 rv = callback.WaitForResult();
7789 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7790
[email protected]49639fa2011-12-20 23:22:417791 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467792 EXPECT_EQ(ERR_IO_PENDING, rv);
7793
7794 rv = callback.WaitForResult();
7795 EXPECT_EQ(OK, rv);
7796
7797 const HttpResponseInfo* response = trans->GetResponseInfo();
7798
[email protected]fe2255a2011-09-20 19:37:507799 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467800 EXPECT_EQ(100, response->headers->GetContentLength());
7801}
7802
[email protected]23e482282013-06-14 16:08:027803TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427804 HttpRequestInfo request;
7805 request.method = "GET";
bncce36dca22015-04-21 22:11:237806 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437807 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7808 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427809
mmenkee65e7af2015-10-13 17:16:427810 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277811 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417812 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277813
[email protected]1c773ea12009-04-28 19:58:427814 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237815 MockWrite(
7816 "GET / HTTP/1.1\r\n"
7817 "Host: www.example.org\r\n"
7818 "Connection: keep-alive\r\n"
7819 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427820 };
7821
7822 // Lastly, the server responds with the actual content.
7823 MockRead data_reads[] = {
7824 MockRead("HTTP/1.0 200 OK\r\n"),
7825 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7826 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067827 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427828 };
7829
[email protected]31a2bfe2010-02-09 08:03:397830 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7831 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077832 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427833
[email protected]49639fa2011-12-20 23:22:417834 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427835
[email protected]49639fa2011-12-20 23:22:417836 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427837 EXPECT_EQ(ERR_IO_PENDING, rv);
7838
7839 rv = callback.WaitForResult();
7840 EXPECT_EQ(OK, rv);
7841}
7842
[email protected]23e482282013-06-14 16:08:027843TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297844 HttpRequestInfo request;
7845 request.method = "GET";
bncce36dca22015-04-21 22:11:237846 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297847 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7848 "Chromium Ultra Awesome X Edition");
7849
rdsmith82957ad2015-09-16 19:42:037850 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:427851 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277852 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417853 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277854
[email protected]da81f132010-08-18 23:39:297855 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237856 MockWrite(
7857 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7858 "Host: www.example.org\r\n"
7859 "Proxy-Connection: keep-alive\r\n"
7860 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297861 };
7862 MockRead data_reads[] = {
7863 // Return an error, so the transaction stops here (this test isn't
7864 // interested in the rest).
7865 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7866 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7867 MockRead("Proxy-Connection: close\r\n\r\n"),
7868 };
7869
7870 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7871 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077872 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297873
[email protected]49639fa2011-12-20 23:22:417874 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297875
[email protected]49639fa2011-12-20 23:22:417876 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297877 EXPECT_EQ(ERR_IO_PENDING, rv);
7878
7879 rv = callback.WaitForResult();
7880 EXPECT_EQ(OK, rv);
7881}
7882
[email protected]23e482282013-06-14 16:08:027883TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427884 HttpRequestInfo request;
7885 request.method = "GET";
bncce36dca22015-04-21 22:11:237886 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427887 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167888 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7889 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427890
mmenkee65e7af2015-10-13 17:16:427891 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277892 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277894
[email protected]1c773ea12009-04-28 19:58:427895 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237896 MockWrite(
7897 "GET / HTTP/1.1\r\n"
7898 "Host: www.example.org\r\n"
7899 "Connection: keep-alive\r\n"
7900 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427901 };
7902
7903 // Lastly, the server responds with the actual content.
7904 MockRead data_reads[] = {
7905 MockRead("HTTP/1.0 200 OK\r\n"),
7906 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7907 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067908 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427909 };
7910
[email protected]31a2bfe2010-02-09 08:03:397911 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7912 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077913 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427914
[email protected]49639fa2011-12-20 23:22:417915 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427916
[email protected]49639fa2011-12-20 23:22:417917 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427918 EXPECT_EQ(ERR_IO_PENDING, rv);
7919
7920 rv = callback.WaitForResult();
7921 EXPECT_EQ(OK, rv);
7922}
7923
[email protected]23e482282013-06-14 16:08:027924TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427925 HttpRequestInfo request;
7926 request.method = "POST";
bncce36dca22015-04-21 22:11:237927 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427928
mmenkee65e7af2015-10-13 17:16:427929 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277930 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417931 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277932
[email protected]1c773ea12009-04-28 19:58:427933 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237934 MockWrite(
7935 "POST / HTTP/1.1\r\n"
7936 "Host: www.example.org\r\n"
7937 "Connection: keep-alive\r\n"
7938 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427939 };
7940
7941 // Lastly, the server responds with the actual content.
7942 MockRead data_reads[] = {
7943 MockRead("HTTP/1.0 200 OK\r\n"),
7944 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7945 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067946 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427947 };
7948
[email protected]31a2bfe2010-02-09 08:03:397949 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7950 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077951 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427952
[email protected]49639fa2011-12-20 23:22:417953 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427954
[email protected]49639fa2011-12-20 23:22:417955 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427956 EXPECT_EQ(ERR_IO_PENDING, rv);
7957
7958 rv = callback.WaitForResult();
7959 EXPECT_EQ(OK, rv);
7960}
7961
[email protected]23e482282013-06-14 16:08:027962TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427963 HttpRequestInfo request;
7964 request.method = "PUT";
bncce36dca22015-04-21 22:11:237965 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427966
mmenkee65e7af2015-10-13 17:16:427967 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277968 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417969 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277970
[email protected]1c773ea12009-04-28 19:58:427971 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237972 MockWrite(
7973 "PUT / HTTP/1.1\r\n"
7974 "Host: www.example.org\r\n"
7975 "Connection: keep-alive\r\n"
7976 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427977 };
7978
7979 // Lastly, the server responds with the actual content.
7980 MockRead data_reads[] = {
7981 MockRead("HTTP/1.0 200 OK\r\n"),
7982 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7983 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067984 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427985 };
7986
[email protected]31a2bfe2010-02-09 08:03:397987 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7988 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077989 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427990
[email protected]49639fa2011-12-20 23:22:417991 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427992
[email protected]49639fa2011-12-20 23:22:417993 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427994 EXPECT_EQ(ERR_IO_PENDING, rv);
7995
7996 rv = callback.WaitForResult();
7997 EXPECT_EQ(OK, rv);
7998}
7999
[email protected]23e482282013-06-14 16:08:028000TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428001 HttpRequestInfo request;
8002 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238003 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428004
mmenkee65e7af2015-10-13 17:16:428005 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278006 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418007 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278008
[email protected]1c773ea12009-04-28 19:58:428009 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138010 MockWrite("HEAD / HTTP/1.1\r\n"
8011 "Host: www.example.org\r\n"
8012 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428013 };
8014
8015 // Lastly, the server responds with the actual content.
8016 MockRead data_reads[] = {
8017 MockRead("HTTP/1.0 200 OK\r\n"),
8018 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8019 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068020 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428021 };
8022
[email protected]31a2bfe2010-02-09 08:03:398023 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8024 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078025 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428026
[email protected]49639fa2011-12-20 23:22:418027 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428028
[email protected]49639fa2011-12-20 23:22:418029 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428030 EXPECT_EQ(ERR_IO_PENDING, rv);
8031
8032 rv = callback.WaitForResult();
8033 EXPECT_EQ(OK, rv);
8034}
8035
[email protected]23e482282013-06-14 16:08:028036TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428037 HttpRequestInfo request;
8038 request.method = "GET";
bncce36dca22015-04-21 22:11:238039 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428040 request.load_flags = LOAD_BYPASS_CACHE;
8041
mmenkee65e7af2015-10-13 17:16:428042 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278043 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418044 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278045
[email protected]1c773ea12009-04-28 19:58:428046 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238047 MockWrite(
8048 "GET / HTTP/1.1\r\n"
8049 "Host: www.example.org\r\n"
8050 "Connection: keep-alive\r\n"
8051 "Pragma: no-cache\r\n"
8052 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428053 };
8054
8055 // Lastly, the server responds with the actual content.
8056 MockRead data_reads[] = {
8057 MockRead("HTTP/1.0 200 OK\r\n"),
8058 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8059 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068060 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428061 };
8062
[email protected]31a2bfe2010-02-09 08:03:398063 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8064 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078065 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428066
[email protected]49639fa2011-12-20 23:22:418067 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428068
[email protected]49639fa2011-12-20 23:22:418069 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428070 EXPECT_EQ(ERR_IO_PENDING, rv);
8071
8072 rv = callback.WaitForResult();
8073 EXPECT_EQ(OK, rv);
8074}
8075
[email protected]23e482282013-06-14 16:08:028076TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:428077 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428078 HttpRequestInfo request;
8079 request.method = "GET";
bncce36dca22015-04-21 22:11:238080 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428081 request.load_flags = LOAD_VALIDATE_CACHE;
8082
mmenkee65e7af2015-10-13 17:16:428083 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278084 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418085 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278086
[email protected]1c773ea12009-04-28 19:58:428087 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238088 MockWrite(
8089 "GET / HTTP/1.1\r\n"
8090 "Host: www.example.org\r\n"
8091 "Connection: keep-alive\r\n"
8092 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428093 };
8094
8095 // Lastly, the server responds with the actual content.
8096 MockRead data_reads[] = {
8097 MockRead("HTTP/1.0 200 OK\r\n"),
8098 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8099 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068100 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428101 };
8102
[email protected]31a2bfe2010-02-09 08:03:398103 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8104 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078105 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428106
[email protected]49639fa2011-12-20 23:22:418107 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428108
[email protected]49639fa2011-12-20 23:22:418109 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428110 EXPECT_EQ(ERR_IO_PENDING, rv);
8111
8112 rv = callback.WaitForResult();
8113 EXPECT_EQ(OK, rv);
8114}
8115
[email protected]23e482282013-06-14 16:08:028116TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428117 HttpRequestInfo request;
8118 request.method = "GET";
bncce36dca22015-04-21 22:11:238119 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438120 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428121
mmenkee65e7af2015-10-13 17:16:428122 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278123 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418124 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278125
[email protected]1c773ea12009-04-28 19:58:428126 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238127 MockWrite(
8128 "GET / HTTP/1.1\r\n"
8129 "Host: www.example.org\r\n"
8130 "Connection: keep-alive\r\n"
8131 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428132 };
8133
8134 // Lastly, the server responds with the actual content.
8135 MockRead data_reads[] = {
8136 MockRead("HTTP/1.0 200 OK\r\n"),
8137 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8138 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068139 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428140 };
8141
[email protected]31a2bfe2010-02-09 08:03:398142 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8143 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078144 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428145
[email protected]49639fa2011-12-20 23:22:418146 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428147
[email protected]49639fa2011-12-20 23:22:418148 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428149 EXPECT_EQ(ERR_IO_PENDING, rv);
8150
8151 rv = callback.WaitForResult();
8152 EXPECT_EQ(OK, rv);
8153}
8154
[email protected]23e482282013-06-14 16:08:028155TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478156 HttpRequestInfo request;
8157 request.method = "GET";
bncce36dca22015-04-21 22:11:238158 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438159 request.extra_headers.SetHeader("referer", "www.foo.com");
8160 request.extra_headers.SetHeader("hEllo", "Kitty");
8161 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478162
mmenkee65e7af2015-10-13 17:16:428163 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278164 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418165 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278166
[email protected]270c6412010-03-29 22:02:478167 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238168 MockWrite(
8169 "GET / HTTP/1.1\r\n"
8170 "Host: www.example.org\r\n"
8171 "Connection: keep-alive\r\n"
8172 "referer: www.foo.com\r\n"
8173 "hEllo: Kitty\r\n"
8174 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478175 };
8176
8177 // Lastly, the server responds with the actual content.
8178 MockRead data_reads[] = {
8179 MockRead("HTTP/1.0 200 OK\r\n"),
8180 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8181 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068182 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478183 };
8184
8185 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8186 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078187 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478188
[email protected]49639fa2011-12-20 23:22:418189 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478190
[email protected]49639fa2011-12-20 23:22:418191 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:478192 EXPECT_EQ(ERR_IO_PENDING, rv);
8193
8194 rv = callback.WaitForResult();
8195 EXPECT_EQ(OK, rv);
8196}
8197
[email protected]23e482282013-06-14 16:08:028198TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278199 HttpRequestInfo request;
8200 request.method = "GET";
bncce36dca22015-04-21 22:11:238201 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278202 request.load_flags = 0;
8203
rdsmith82957ad2015-09-16 19:42:038204 session_deps_.proxy_service =
8205 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518206 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078207 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028208
mmenkee65e7af2015-10-13 17:16:428209 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:028210 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418211 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028212
[email protected]3cd17242009-06-23 02:59:028213 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8214 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8215
8216 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238217 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8218 MockWrite(
8219 "GET / HTTP/1.1\r\n"
8220 "Host: www.example.org\r\n"
8221 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028222
8223 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068224 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028225 MockRead("HTTP/1.0 200 OK\r\n"),
8226 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8227 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068228 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028229 };
8230
[email protected]31a2bfe2010-02-09 08:03:398231 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8232 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078233 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028234
[email protected]49639fa2011-12-20 23:22:418235 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028236
[email protected]49639fa2011-12-20 23:22:418237 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028238 EXPECT_EQ(ERR_IO_PENDING, rv);
8239
8240 rv = callback.WaitForResult();
8241 EXPECT_EQ(OK, rv);
8242
8243 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508244 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:028245
[email protected]029c83b62013-01-24 05:28:208246 LoadTimingInfo load_timing_info;
8247 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8248 TestLoadTimingNotReusedWithPac(load_timing_info,
8249 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8250
[email protected]3cd17242009-06-23 02:59:028251 std::string response_text;
8252 rv = ReadTransaction(trans.get(), &response_text);
8253 EXPECT_EQ(OK, rv);
8254 EXPECT_EQ("Payload", response_text);
8255}
8256
[email protected]23e482282013-06-14 16:08:028257TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278258 HttpRequestInfo request;
8259 request.method = "GET";
bncce36dca22015-04-21 22:11:238260 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278261 request.load_flags = 0;
8262
rdsmith82957ad2015-09-16 19:42:038263 session_deps_.proxy_service =
8264 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518265 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078266 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028267
mmenkee65e7af2015-10-13 17:16:428268 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:028269 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418270 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028271
[email protected]3cd17242009-06-23 02:59:028272 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8273 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8274
8275 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238276 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8277 arraysize(write_buffer)),
8278 MockWrite(
8279 "GET / HTTP/1.1\r\n"
8280 "Host: www.example.org\r\n"
8281 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028282
8283 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018284 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8285 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358286 MockRead("HTTP/1.0 200 OK\r\n"),
8287 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8288 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068289 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358290 };
8291
[email protected]31a2bfe2010-02-09 08:03:398292 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8293 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078294 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358295
[email protected]8ddf8322012-02-23 18:08:068296 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078297 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358298
[email protected]49639fa2011-12-20 23:22:418299 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358300
[email protected]49639fa2011-12-20 23:22:418301 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358302 EXPECT_EQ(ERR_IO_PENDING, rv);
8303
8304 rv = callback.WaitForResult();
8305 EXPECT_EQ(OK, rv);
8306
[email protected]029c83b62013-01-24 05:28:208307 LoadTimingInfo load_timing_info;
8308 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8309 TestLoadTimingNotReusedWithPac(load_timing_info,
8310 CONNECT_TIMING_HAS_SSL_TIMES);
8311
[email protected]e0c27be2009-07-15 13:09:358312 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508313 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:358314
8315 std::string response_text;
8316 rv = ReadTransaction(trans.get(), &response_text);
8317 EXPECT_EQ(OK, rv);
8318 EXPECT_EQ("Payload", response_text);
8319}
8320
[email protected]23e482282013-06-14 16:08:028321TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:208322 HttpRequestInfo request;
8323 request.method = "GET";
bncce36dca22015-04-21 22:11:238324 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:208325 request.load_flags = 0;
8326
rdsmith82957ad2015-09-16 19:42:038327 session_deps_.proxy_service =
8328 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518329 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078330 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:208331
mmenkee65e7af2015-10-13 17:16:428332 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:208333 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418334 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:208335
8336 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8337 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8338
8339 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238340 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8341 MockWrite(
8342 "GET / HTTP/1.1\r\n"
8343 "Host: www.example.org\r\n"
8344 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:208345
8346 MockRead data_reads[] = {
8347 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
8348 MockRead("HTTP/1.0 200 OK\r\n"),
8349 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8350 MockRead("Payload"),
8351 MockRead(SYNCHRONOUS, OK)
8352 };
8353
8354 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8355 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078356 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:208357
8358 TestCompletionCallback callback;
8359
8360 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8361 EXPECT_EQ(ERR_IO_PENDING, rv);
8362
8363 rv = callback.WaitForResult();
8364 EXPECT_EQ(OK, rv);
8365
8366 const HttpResponseInfo* response = trans->GetResponseInfo();
8367 ASSERT_TRUE(response != NULL);
8368
8369 LoadTimingInfo load_timing_info;
8370 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8371 TestLoadTimingNotReused(load_timing_info,
8372 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8373
8374 std::string response_text;
8375 rv = ReadTransaction(trans.get(), &response_text);
8376 EXPECT_EQ(OK, rv);
8377 EXPECT_EQ("Payload", response_text);
8378}
8379
[email protected]23e482282013-06-14 16:08:028380TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278381 HttpRequestInfo request;
8382 request.method = "GET";
bncce36dca22015-04-21 22:11:238383 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278384 request.load_flags = 0;
8385
rdsmith82957ad2015-09-16 19:42:038386 session_deps_.proxy_service =
8387 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518388 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078389 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358390
mmenkee65e7af2015-10-13 17:16:428391 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:358392 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418393 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358394
[email protected]e0c27be2009-07-15 13:09:358395 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8396 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378397 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238398 0x05, // Version
8399 0x01, // Command (CONNECT)
8400 0x00, // Reserved.
8401 0x03, // Address type (DOMAINNAME).
8402 0x0F, // Length of domain (15)
8403 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8404 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:378405 };
[email protected]e0c27be2009-07-15 13:09:358406 const char kSOCKS5OkResponse[] =
8407 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
8408
8409 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238410 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8411 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
8412 MockWrite(
8413 "GET / HTTP/1.1\r\n"
8414 "Host: www.example.org\r\n"
8415 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358416
8417 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018418 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8419 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:358420 MockRead("HTTP/1.0 200 OK\r\n"),
8421 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8422 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068423 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358424 };
8425
[email protected]31a2bfe2010-02-09 08:03:398426 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8427 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078428 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358429
[email protected]49639fa2011-12-20 23:22:418430 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358431
[email protected]49639fa2011-12-20 23:22:418432 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358433 EXPECT_EQ(ERR_IO_PENDING, rv);
8434
8435 rv = callback.WaitForResult();
8436 EXPECT_EQ(OK, rv);
8437
8438 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508439 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:358440
[email protected]029c83b62013-01-24 05:28:208441 LoadTimingInfo load_timing_info;
8442 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8443 TestLoadTimingNotReusedWithPac(load_timing_info,
8444 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8445
[email protected]e0c27be2009-07-15 13:09:358446 std::string response_text;
8447 rv = ReadTransaction(trans.get(), &response_text);
8448 EXPECT_EQ(OK, rv);
8449 EXPECT_EQ("Payload", response_text);
8450}
8451
[email protected]23e482282013-06-14 16:08:028452TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278453 HttpRequestInfo request;
8454 request.method = "GET";
bncce36dca22015-04-21 22:11:238455 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278456 request.load_flags = 0;
8457
rdsmith82957ad2015-09-16 19:42:038458 session_deps_.proxy_service =
8459 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518460 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078461 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358462
mmenkee65e7af2015-10-13 17:16:428463 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:358464 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418465 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358466
[email protected]e0c27be2009-07-15 13:09:358467 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8468 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378469 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238470 0x05, // Version
8471 0x01, // Command (CONNECT)
8472 0x00, // Reserved.
8473 0x03, // Address type (DOMAINNAME).
8474 0x0F, // Length of domain (15)
8475 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8476 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:378477 };
8478
[email protected]e0c27be2009-07-15 13:09:358479 const char kSOCKS5OkResponse[] =
8480 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
8481
8482 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238483 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8484 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
8485 arraysize(kSOCKS5OkRequest)),
8486 MockWrite(
8487 "GET / HTTP/1.1\r\n"
8488 "Host: www.example.org\r\n"
8489 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358490
8491 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018492 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8493 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:028494 MockRead("HTTP/1.0 200 OK\r\n"),
8495 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8496 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068497 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028498 };
8499
[email protected]31a2bfe2010-02-09 08:03:398500 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8501 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078502 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028503
[email protected]8ddf8322012-02-23 18:08:068504 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078505 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:028506
[email protected]49639fa2011-12-20 23:22:418507 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028508
[email protected]49639fa2011-12-20 23:22:418509 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028510 EXPECT_EQ(ERR_IO_PENDING, rv);
8511
8512 rv = callback.WaitForResult();
8513 EXPECT_EQ(OK, rv);
8514
8515 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508516 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:028517
[email protected]029c83b62013-01-24 05:28:208518 LoadTimingInfo load_timing_info;
8519 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8520 TestLoadTimingNotReusedWithPac(load_timing_info,
8521 CONNECT_TIMING_HAS_SSL_TIMES);
8522
[email protected]3cd17242009-06-23 02:59:028523 std::string response_text;
8524 rv = ReadTransaction(trans.get(), &response_text);
8525 EXPECT_EQ(OK, rv);
8526 EXPECT_EQ("Payload", response_text);
8527}
8528
[email protected]448d4ca52012-03-04 04:12:238529namespace {
8530
[email protected]04e5be32009-06-26 20:00:318531// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:068532
8533struct GroupNameTest {
8534 std::string proxy_server;
8535 std::string url;
8536 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:188537 bool ssl;
[email protected]2d731a32010-04-29 01:04:068538};
8539
mmenkee65e7af2015-10-13 17:16:428540scoped_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:438541 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:078542 SpdySessionDependencies* session_deps_) {
mmenkee65e7af2015-10-13 17:16:428543 scoped_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:068544
[email protected]30d4c022013-07-18 22:58:168545 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538546 session->http_server_properties();
bnccacc0992015-03-20 20:22:228547 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:258548 AlternateProtocolFromNextProto(next_proto), "", 443);
bnc7dc7e1b42015-07-28 14:43:128549 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:228550 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:128551 HostPortPair("host.with.alternate", 80), alternative_service, 1.0,
8552 expiration);
[email protected]2d731a32010-04-29 01:04:068553
8554 return session;
8555}
8556
mmenkee65e7af2015-10-13 17:16:428557int GroupNameTransactionHelper(const std::string& url,
8558 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:068559 HttpRequestInfo request;
8560 request.method = "GET";
8561 request.url = GURL(url);
8562 request.load_flags = 0;
8563
[email protected]262eec82013-03-19 21:01:368564 scoped_ptr<HttpTransaction> trans(
mmenkee65e7af2015-10-13 17:16:428565 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:278566
[email protected]49639fa2011-12-20 23:22:418567 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:068568
8569 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:418570 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:068571}
8572
[email protected]448d4ca52012-03-04 04:12:238573} // namespace
8574
[email protected]23e482282013-06-14 16:08:028575TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:068576 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238577 {
8578 "", // unused
8579 "http://www.example.org/direct",
8580 "www.example.org:80",
8581 false,
8582 },
8583 {
8584 "", // unused
8585 "http://[2001:1418:13:1::25]/direct",
8586 "[2001:1418:13:1::25]:80",
8587 false,
8588 },
[email protected]04e5be32009-06-26 20:00:318589
bncce36dca22015-04-21 22:11:238590 // SSL Tests
8591 {
8592 "", // unused
8593 "https://www.example.org/direct_ssl",
8594 "ssl/www.example.org:443",
8595 true,
8596 },
8597 {
8598 "", // unused
8599 "https://[2001:1418:13:1::25]/direct",
8600 "ssl/[2001:1418:13:1::25]:443",
8601 true,
8602 },
8603 {
8604 "", // unused
8605 "http://host.with.alternate/direct",
8606 "ssl/host.with.alternate:443",
8607 true,
8608 },
[email protected]2d731a32010-04-29 01:04:068609 };
[email protected]2ff8b312010-04-26 22:20:548610
bnc55ff9da2015-08-19 18:42:358611 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068612
viettrungluue4a8b882014-10-16 06:17:388613 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038614 session_deps_.proxy_service =
8615 ProxyService::CreateFixed(tests[i].proxy_server);
mmenkee65e7af2015-10-13 17:16:428616 scoped_ptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438617 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068618
mmenkee65e7af2015-10-13 17:16:428619 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:288620 CaptureGroupNameTransportSocketPool* transport_conn_pool =
8621 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138622 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348623 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:448624 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8625 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028626 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
8627 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518628 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068629
8630 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:428631 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:188632 if (tests[i].ssl)
8633 EXPECT_EQ(tests[i].expected_group_name,
8634 ssl_conn_pool->last_group_name_received());
8635 else
8636 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:288637 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068638 }
[email protected]2d731a32010-04-29 01:04:068639}
8640
[email protected]23e482282013-06-14 16:08:028641TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:068642 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238643 {
8644 "http_proxy",
8645 "http://www.example.org/http_proxy_normal",
8646 "www.example.org:80",
8647 false,
8648 },
[email protected]2d731a32010-04-29 01:04:068649
bncce36dca22015-04-21 22:11:238650 // SSL Tests
8651 {
8652 "http_proxy",
8653 "https://www.example.org/http_connect_ssl",
8654 "ssl/www.example.org:443",
8655 true,
8656 },
[email protected]af3490e2010-10-16 21:02:298657
bncce36dca22015-04-21 22:11:238658 {
8659 "http_proxy",
8660 "http://host.with.alternate/direct",
8661 "ssl/host.with.alternate:443",
8662 true,
8663 },
[email protected]45499252013-01-23 17:12:568664
bncce36dca22015-04-21 22:11:238665 {
8666 "http_proxy",
8667 "ftp://ftp.google.com/http_proxy_normal",
8668 "ftp/ftp.google.com:21",
8669 false,
8670 },
[email protected]2d731a32010-04-29 01:04:068671 };
8672
bnc55ff9da2015-08-19 18:42:358673 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068674
viettrungluue4a8b882014-10-16 06:17:388675 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038676 session_deps_.proxy_service =
8677 ProxyService::CreateFixed(tests[i].proxy_server);
mmenkee65e7af2015-10-13 17:16:428678 scoped_ptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438679 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068680
mmenkee65e7af2015-10-13 17:16:428681 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:068682
[email protected]e60e47a2010-07-14 03:37:188683 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138684 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348685 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138686 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348687 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028688
[email protected]831e4a32013-11-14 02:14:448689 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8690 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028691 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8692 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518693 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068694
8695 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:428696 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:188697 if (tests[i].ssl)
8698 EXPECT_EQ(tests[i].expected_group_name,
8699 ssl_conn_pool->last_group_name_received());
8700 else
8701 EXPECT_EQ(tests[i].expected_group_name,
8702 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068703 }
[email protected]2d731a32010-04-29 01:04:068704}
8705
[email protected]23e482282013-06-14 16:08:028706TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068707 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238708 {
8709 "socks4://socks_proxy:1080",
8710 "http://www.example.org/socks4_direct",
8711 "socks4/www.example.org:80",
8712 false,
8713 },
8714 {
8715 "socks5://socks_proxy:1080",
8716 "http://www.example.org/socks5_direct",
8717 "socks5/www.example.org:80",
8718 false,
8719 },
[email protected]2d731a32010-04-29 01:04:068720
bncce36dca22015-04-21 22:11:238721 // SSL Tests
8722 {
8723 "socks4://socks_proxy:1080",
8724 "https://www.example.org/socks4_ssl",
8725 "socks4/ssl/www.example.org:443",
8726 true,
8727 },
8728 {
8729 "socks5://socks_proxy:1080",
8730 "https://www.example.org/socks5_ssl",
8731 "socks5/ssl/www.example.org:443",
8732 true,
8733 },
[email protected]af3490e2010-10-16 21:02:298734
bncce36dca22015-04-21 22:11:238735 {
8736 "socks4://socks_proxy:1080",
8737 "http://host.with.alternate/direct",
8738 "socks4/ssl/host.with.alternate:443",
8739 true,
8740 },
[email protected]04e5be32009-06-26 20:00:318741 };
8742
bnc55ff9da2015-08-19 18:42:358743 session_deps_.use_alternative_services = true;
[email protected]2ff8b312010-04-26 22:20:548744
viettrungluue4a8b882014-10-16 06:17:388745 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038746 session_deps_.proxy_service =
8747 ProxyService::CreateFixed(tests[i].proxy_server);
mmenkee65e7af2015-10-13 17:16:428748 scoped_ptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438749 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028750
mmenkee65e7af2015-10-13 17:16:428751 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:318752
[email protected]e60e47a2010-07-14 03:37:188753 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138754 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348755 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138756 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348757 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028758
[email protected]831e4a32013-11-14 02:14:448759 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8760 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028761 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8762 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518763 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318764
[email protected]262eec82013-03-19 21:01:368765 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508766 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318767
[email protected]2d731a32010-04-29 01:04:068768 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:428769 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:188770 if (tests[i].ssl)
8771 EXPECT_EQ(tests[i].expected_group_name,
8772 ssl_conn_pool->last_group_name_received());
8773 else
8774 EXPECT_EQ(tests[i].expected_group_name,
8775 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318776 }
8777}
8778
[email protected]23e482282013-06-14 16:08:028779TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278780 HttpRequestInfo request;
8781 request.method = "GET";
bncce36dca22015-04-21 22:11:238782 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278783
rdsmith82957ad2015-09-16 19:42:038784 session_deps_.proxy_service =
8785 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:328786
[email protected]69719062010-01-05 20:09:218787 // This simulates failure resolving all hostnames; that means we will fail
8788 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078789 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328790
mmenkee65e7af2015-10-13 17:16:428791 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258792 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418793 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258794
[email protected]49639fa2011-12-20 23:22:418795 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258796
[email protected]49639fa2011-12-20 23:22:418797 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258798 EXPECT_EQ(ERR_IO_PENDING, rv);
8799
[email protected]9172a982009-06-06 00:30:258800 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018801 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258802}
8803
[email protected]685af592010-05-11 19:31:248804// Base test to make sure that when the load flags for a request specify to
8805// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028806void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078807 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278808 // Issue a request, asking to bypass the cache(s).
8809 HttpRequestInfo request;
8810 request.method = "GET";
8811 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238812 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278813
[email protected]a2c2fb92009-07-18 07:31:048814 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078815 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328816
mmenkee65e7af2015-10-13 17:16:428817 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:078818 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418819 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288820
bncce36dca22015-04-21 22:11:238821 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288822 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298823 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078824 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238825 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8826 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478827 EXPECT_EQ(ERR_IO_PENDING, rv);
8828 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288829 EXPECT_EQ(OK, rv);
8830
8831 // Verify that it was added to host cache, by doing a subsequent async lookup
8832 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078833 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238834 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8835 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328836 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288837
bncce36dca22015-04-21 22:11:238838 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288839 // we can tell if the next lookup hit the cache, or the "network".
8840 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238841 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288842
8843 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8844 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068845 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398846 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078847 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288848
[email protected]3b9cca42009-06-16 01:08:288849 // Run the request.
[email protected]49639fa2011-12-20 23:22:418850 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288851 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418852 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288853
8854 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238855 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288856 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8857}
8858
[email protected]685af592010-05-11 19:31:248859// There are multiple load flags that should trigger the host cache bypass.
8860// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028861TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248862 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8863}
8864
[email protected]23e482282013-06-14 16:08:028865TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248866 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8867}
8868
[email protected]23e482282013-06-14 16:08:028869TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248870 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8871}
8872
[email protected]0877e3d2009-10-17 22:29:578873// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028874TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578875 HttpRequestInfo request;
8876 request.method = "GET";
8877 request.url = GURL("http://www.foo.com/");
8878 request.load_flags = 0;
8879
8880 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068881 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578882 };
[email protected]31a2bfe2010-02-09 08:03:398883 StaticSocketDataProvider data(NULL, 0,
8884 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078885 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenkee65e7af2015-10-13 17:16:428886 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578887
[email protected]49639fa2011-12-20 23:22:418888 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578889
8890 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418891 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578892
[email protected]49639fa2011-12-20 23:22:418893 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578894 EXPECT_EQ(ERR_IO_PENDING, rv);
8895
8896 rv = callback.WaitForResult();
8897 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:598898
8899 IPEndPoint endpoint;
8900 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
8901 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:578902}
8903
zmo9528c9f42015-08-04 22:12:088904// Check that a connection closed after the start of the headers finishes ok.
8905TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578906 HttpRequestInfo request;
8907 request.method = "GET";
8908 request.url = GURL("http://www.foo.com/");
8909 request.load_flags = 0;
8910
8911 MockRead data_reads[] = {
8912 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068913 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578914 };
8915
[email protected]31a2bfe2010-02-09 08:03:398916 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078917 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenkee65e7af2015-10-13 17:16:428918 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578919
[email protected]49639fa2011-12-20 23:22:418920 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578921
8922 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418923 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578924
[email protected]49639fa2011-12-20 23:22:418925 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578926 EXPECT_EQ(ERR_IO_PENDING, rv);
8927
8928 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:088929 EXPECT_EQ(OK, rv);
8930
8931 const HttpResponseInfo* response = trans->GetResponseInfo();
8932 ASSERT_TRUE(response != NULL);
8933
8934 EXPECT_TRUE(response->headers.get() != NULL);
8935 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8936
8937 std::string response_data;
8938 rv = ReadTransaction(trans.get(), &response_data);
8939 EXPECT_EQ(OK, rv);
8940 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:598941
8942 IPEndPoint endpoint;
8943 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
8944 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:578945}
8946
8947// Make sure that a dropped connection while draining the body for auth
8948// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028949TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578950 HttpRequestInfo request;
8951 request.method = "GET";
bncce36dca22015-04-21 22:11:238952 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578953 request.load_flags = 0;
8954
8955 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238956 MockWrite(
8957 "GET / HTTP/1.1\r\n"
8958 "Host: www.example.org\r\n"
8959 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578960 };
8961
8962 MockRead data_reads1[] = {
8963 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8964 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8965 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8966 MockRead("Content-Length: 14\r\n\r\n"),
8967 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068968 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578969 };
8970
[email protected]31a2bfe2010-02-09 08:03:398971 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8972 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078973 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578974
8975 // After calling trans->RestartWithAuth(), this is the request we should
8976 // be issuing -- the final header line contains the credentials.
8977 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238978 MockWrite(
8979 "GET / HTTP/1.1\r\n"
8980 "Host: www.example.org\r\n"
8981 "Connection: keep-alive\r\n"
8982 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578983 };
8984
8985 // Lastly, the server responds with the actual content.
8986 MockRead data_reads2[] = {
8987 MockRead("HTTP/1.1 200 OK\r\n"),
8988 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8989 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068990 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578991 };
8992
[email protected]31a2bfe2010-02-09 08:03:398993 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8994 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078995 session_deps_.socket_factory->AddSocketDataProvider(&data2);
mmenkee65e7af2015-10-13 17:16:428996 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578997
[email protected]49639fa2011-12-20 23:22:418998 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578999
[email protected]262eec82013-03-19 21:01:369000 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509001 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509002
[email protected]49639fa2011-12-20 23:22:419003 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579004 EXPECT_EQ(ERR_IO_PENDING, rv);
9005
9006 rv = callback1.WaitForResult();
9007 EXPECT_EQ(OK, rv);
9008
9009 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509010 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049011 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579012
[email protected]49639fa2011-12-20 23:22:419013 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579014
[email protected]49639fa2011-12-20 23:22:419015 rv = trans->RestartWithAuth(
9016 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:579017 EXPECT_EQ(ERR_IO_PENDING, rv);
9018
9019 rv = callback2.WaitForResult();
9020 EXPECT_EQ(OK, rv);
9021
9022 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509023 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:579024 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9025 EXPECT_EQ(100, response->headers->GetContentLength());
9026}
9027
9028// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:029029TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039030 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579031
9032 HttpRequestInfo request;
9033 request.method = "GET";
bncce36dca22015-04-21 22:11:239034 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579035 request.load_flags = 0;
9036
9037 MockRead proxy_reads[] = {
9038 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069039 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579040 };
9041
[email protected]31a2bfe2010-02-09 08:03:399042 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069043 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579044
[email protected]bb88e1d32013-05-03 23:11:079045 session_deps_.socket_factory->AddSocketDataProvider(&data);
9046 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579047
[email protected]49639fa2011-12-20 23:22:419048 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579049
[email protected]bb88e1d32013-05-03 23:11:079050 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579051
mmenkee65e7af2015-10-13 17:16:429052 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579053 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419054 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579055
[email protected]49639fa2011-12-20 23:22:419056 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579057 EXPECT_EQ(ERR_IO_PENDING, rv);
9058
9059 rv = callback.WaitForResult();
9060 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
9061}
9062
[email protected]23e482282013-06-14 16:08:029063TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469064 HttpRequestInfo request;
9065 request.method = "GET";
bncce36dca22015-04-21 22:11:239066 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469067 request.load_flags = 0;
9068
mmenkee65e7af2015-10-13 17:16:429069 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:279070 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419071 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:279072
[email protected]e22e1362009-11-23 21:31:129073 MockRead data_reads[] = {
9074 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069075 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129076 };
[email protected]9492e4a2010-02-24 00:58:469077
9078 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079079 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469080
[email protected]49639fa2011-12-20 23:22:419081 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469082
[email protected]49639fa2011-12-20 23:22:419083 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:469084 EXPECT_EQ(ERR_IO_PENDING, rv);
9085
9086 EXPECT_EQ(OK, callback.WaitForResult());
9087
9088 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509089 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:469090
[email protected]90499482013-06-01 00:39:509091 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:469092 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9093
9094 std::string response_data;
9095 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:239096 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:129097}
9098
[email protected]23e482282013-06-14 16:08:029099TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159100 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529101 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:339102 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219103 UploadFileElementReader::ScopedOverridingContentLengthForTests
9104 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339105
[email protected]b2d26cfd2012-12-11 10:36:069106 ScopedVector<UploadElementReader> element_readers;
9107 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:459108 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
9109 temp_file_path, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:079110 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:279111
9112 HttpRequestInfo request;
9113 request.method = "POST";
bncce36dca22015-04-21 22:11:239114 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279115 request.upload_data_stream = &upload_data_stream;
9116 request.load_flags = 0;
9117
mmenkee65e7af2015-10-13 17:16:429118 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:279119 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419120 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:339121
9122 MockRead data_reads[] = {
9123 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9124 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069125 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339126 };
[email protected]31a2bfe2010-02-09 08:03:399127 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079128 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339129
[email protected]49639fa2011-12-20 23:22:419130 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339131
[email protected]49639fa2011-12-20 23:22:419132 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:339133 EXPECT_EQ(ERR_IO_PENDING, rv);
9134
9135 rv = callback.WaitForResult();
9136 EXPECT_EQ(OK, rv);
9137
9138 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509139 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:339140
[email protected]90499482013-06-01 00:39:509141 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:339142 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9143
9144 std::string response_data;
9145 rv = ReadTransaction(trans.get(), &response_data);
9146 EXPECT_EQ(OK, rv);
9147 EXPECT_EQ("hello world", response_data);
9148
[email protected]dd3aa792013-07-16 19:10:239149 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339150}
9151
[email protected]23e482282013-06-14 16:08:029152TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159153 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529154 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369155 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:309156 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:369157 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119158 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369159
[email protected]b2d26cfd2012-12-11 10:36:069160 ScopedVector<UploadElementReader> element_readers;
9161 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:459162 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
9163 temp_file, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:079164 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:279165
9166 HttpRequestInfo request;
9167 request.method = "POST";
bncce36dca22015-04-21 22:11:239168 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279169 request.upload_data_stream = &upload_data_stream;
9170 request.load_flags = 0;
9171
[email protected]999dd8c2013-11-12 06:45:549172 // If we try to upload an unreadable file, the transaction should fail.
mmenkee65e7af2015-10-13 17:16:429173 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:279174 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419175 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:369176
[email protected]999dd8c2013-11-12 06:45:549177 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079178 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369179
[email protected]49639fa2011-12-20 23:22:419180 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369181
[email protected]49639fa2011-12-20 23:22:419182 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:369183 EXPECT_EQ(ERR_IO_PENDING, rv);
9184
9185 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:549186 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:369187
[email protected]dd3aa792013-07-16 19:10:239188 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369189}
9190
[email protected]02cad5d2013-10-02 08:14:039191TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
9192 class FakeUploadElementReader : public UploadElementReader {
9193 public:
9194 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209195 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039196
9197 const CompletionCallback& callback() const { return callback_; }
9198
9199 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209200 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039201 callback_ = callback;
9202 return ERR_IO_PENDING;
9203 }
dchengb03027d2014-10-21 12:00:209204 uint64 GetContentLength() const override { return 0; }
9205 uint64 BytesRemaining() const override { return 0; }
9206 int Read(IOBuffer* buf,
9207 int buf_length,
9208 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039209 return ERR_FAILED;
9210 }
9211
9212 private:
9213 CompletionCallback callback_;
9214 };
9215
9216 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
9217 ScopedVector<UploadElementReader> element_readers;
9218 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:079219 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:039220
9221 HttpRequestInfo request;
9222 request.method = "POST";
bncce36dca22015-04-21 22:11:239223 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039224 request.upload_data_stream = &upload_data_stream;
9225 request.load_flags = 0;
9226
mmenkee65e7af2015-10-13 17:16:429227 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:039228 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419229 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039230
9231 StaticSocketDataProvider data;
9232 session_deps_.socket_factory->AddSocketDataProvider(&data);
9233
9234 TestCompletionCallback callback;
9235 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9236 EXPECT_EQ(ERR_IO_PENDING, rv);
9237 base::MessageLoop::current()->RunUntilIdle();
9238
9239 // Transaction is pending on request body initialization.
9240 ASSERT_FALSE(fake_reader->callback().is_null());
9241
9242 // Return Init()'s result after the transaction gets destroyed.
9243 trans.reset();
9244 fake_reader->callback().Run(OK); // Should not crash.
9245}
9246
[email protected]aeefc9e82010-02-19 16:18:279247// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:029248TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279249 HttpRequestInfo request;
9250 request.method = "GET";
bncce36dca22015-04-21 22:11:239251 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279252 request.load_flags = 0;
9253
9254 // First transaction will request a resource and receive a Basic challenge
9255 // with realm="first_realm".
9256 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239257 MockWrite(
9258 "GET / HTTP/1.1\r\n"
9259 "Host: www.example.org\r\n"
9260 "Connection: keep-alive\r\n"
9261 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279262 };
9263 MockRead data_reads1[] = {
9264 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9265 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9266 "\r\n"),
9267 };
9268
9269 // After calling trans->RestartWithAuth(), provide an Authentication header
9270 // for first_realm. The server will reject and provide a challenge with
9271 // second_realm.
9272 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239273 MockWrite(
9274 "GET / HTTP/1.1\r\n"
9275 "Host: www.example.org\r\n"
9276 "Connection: keep-alive\r\n"
9277 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9278 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279279 };
9280 MockRead data_reads2[] = {
9281 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9282 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9283 "\r\n"),
9284 };
9285
9286 // This again fails, and goes back to first_realm. Make sure that the
9287 // entry is removed from cache.
9288 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239289 MockWrite(
9290 "GET / HTTP/1.1\r\n"
9291 "Host: www.example.org\r\n"
9292 "Connection: keep-alive\r\n"
9293 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9294 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279295 };
9296 MockRead data_reads3[] = {
9297 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9298 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9299 "\r\n"),
9300 };
9301
9302 // Try one last time (with the correct password) and get the resource.
9303 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239304 MockWrite(
9305 "GET / HTTP/1.1\r\n"
9306 "Host: www.example.org\r\n"
9307 "Connection: keep-alive\r\n"
9308 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9309 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279310 };
9311 MockRead data_reads4[] = {
9312 MockRead("HTTP/1.1 200 OK\r\n"
9313 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509314 "Content-Length: 5\r\n"
9315 "\r\n"
9316 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279317 };
9318
9319 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9320 data_writes1, arraysize(data_writes1));
9321 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9322 data_writes2, arraysize(data_writes2));
9323 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9324 data_writes3, arraysize(data_writes3));
9325 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9326 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079327 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9328 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9329 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9330 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279331
[email protected]49639fa2011-12-20 23:22:419332 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279333
mmenkee65e7af2015-10-13 17:16:429334 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:509335 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419336 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509337
[email protected]aeefc9e82010-02-19 16:18:279338 // Issue the first request with Authorize headers. There should be a
9339 // password prompt for first_realm waiting to be filled in after the
9340 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419341 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:279342 EXPECT_EQ(ERR_IO_PENDING, rv);
9343 rv = callback1.WaitForResult();
9344 EXPECT_EQ(OK, rv);
9345 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509346 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049347 const AuthChallengeInfo* challenge = response->auth_challenge.get();
9348 ASSERT_FALSE(challenge == NULL);
9349 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239350 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049351 EXPECT_EQ("first_realm", challenge->realm);
9352 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279353
9354 // Issue the second request with an incorrect password. There should be a
9355 // password prompt for second_realm waiting to be filled in after the
9356 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419357 TestCompletionCallback callback2;
9358 rv = trans->RestartWithAuth(
9359 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:279360 EXPECT_EQ(ERR_IO_PENDING, rv);
9361 rv = callback2.WaitForResult();
9362 EXPECT_EQ(OK, rv);
9363 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509364 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049365 challenge = response->auth_challenge.get();
9366 ASSERT_FALSE(challenge == NULL);
9367 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239368 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049369 EXPECT_EQ("second_realm", challenge->realm);
9370 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279371
9372 // Issue the third request with another incorrect password. There should be
9373 // a password prompt for first_realm waiting to be filled in. If the password
9374 // prompt is not present, it indicates that the HttpAuthCacheEntry for
9375 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:419376 TestCompletionCallback callback3;
9377 rv = trans->RestartWithAuth(
9378 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:279379 EXPECT_EQ(ERR_IO_PENDING, rv);
9380 rv = callback3.WaitForResult();
9381 EXPECT_EQ(OK, rv);
9382 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509383 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049384 challenge = response->auth_challenge.get();
9385 ASSERT_FALSE(challenge == NULL);
9386 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239387 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049388 EXPECT_EQ("first_realm", challenge->realm);
9389 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279390
9391 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:419392 TestCompletionCallback callback4;
9393 rv = trans->RestartWithAuth(
9394 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:279395 EXPECT_EQ(ERR_IO_PENDING, rv);
9396 rv = callback4.WaitForResult();
9397 EXPECT_EQ(OK, rv);
9398 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509399 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:279400 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9401}
9402
bncc958faa2015-07-31 18:14:529403TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
9404 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359405 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529406
9407 std::string alternative_service_http_header =
9408 GetAlternativeServiceHttpHeader();
9409
9410 MockRead data_reads[] = {
9411 MockRead("HTTP/1.1 200 OK\r\n"),
9412 MockRead(alternative_service_http_header.c_str()),
9413 MockRead("\r\n"),
9414 MockRead("hello world"),
9415 MockRead(SYNCHRONOUS, OK),
9416 };
9417
9418 HttpRequestInfo request;
9419 request.method = "GET";
9420 request.url = GURL("http://www.example.org/");
9421 request.load_flags = 0;
9422
9423 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9424
9425 session_deps_.socket_factory->AddSocketDataProvider(&data);
9426
9427 TestCompletionCallback callback;
9428
mmenkee65e7af2015-10-13 17:16:429429 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529430 scoped_ptr<HttpTransaction> trans(
9431 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9432
9433 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9434 EXPECT_EQ(ERR_IO_PENDING, rv);
9435
9436 HostPortPair http_host_port_pair("www.example.org", 80);
9437 HttpServerProperties& http_server_properties =
9438 *session->http_server_properties();
9439 AlternativeServiceVector alternative_service_vector =
9440 http_server_properties.GetAlternativeServices(http_host_port_pair);
9441 EXPECT_TRUE(alternative_service_vector.empty());
9442
9443 EXPECT_EQ(OK, callback.WaitForResult());
9444
9445 const HttpResponseInfo* response = trans->GetResponseInfo();
9446 ASSERT_TRUE(response != NULL);
9447 ASSERT_TRUE(response->headers.get() != NULL);
9448 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9449 EXPECT_FALSE(response->was_fetched_via_spdy);
9450 EXPECT_FALSE(response->was_npn_negotiated);
9451
9452 std::string response_data;
9453 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9454 EXPECT_EQ("hello world", response_data);
9455
9456 alternative_service_vector =
9457 http_server_properties.GetAlternativeServices(http_host_port_pair);
9458 ASSERT_EQ(1u, alternative_service_vector.size());
9459 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9460 alternative_service_vector[0].protocol);
9461 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9462 EXPECT_EQ(443, alternative_service_vector[0].port);
9463}
9464
bnc4f575852015-10-14 18:35:089465TEST_P(HttpNetworkTransactionTest, ClearAlternativeServices) {
9466 session_deps_.next_protos = SpdyNextProtos();
9467 session_deps_.use_alternative_services = true;
9468
9469 // Set an alternative service for origin.
9470 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9471 HttpServerProperties& http_server_properties =
9472 *session->http_server_properties();
9473 HostPortPair http_host_port_pair("www.example.org", 80);
9474 AlternativeService alternative_service(QUIC, "", 80);
9475 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9476 http_server_properties.SetAlternativeService(
9477 http_host_port_pair, alternative_service, 1.0, expiration);
9478 AlternativeServiceVector alternative_service_vector =
9479 http_server_properties.GetAlternativeServices(http_host_port_pair);
9480 EXPECT_EQ(1u, alternative_service_vector.size());
9481
9482 // Send a clear header.
9483 MockRead data_reads[] = {
9484 MockRead("HTTP/1.1 200 OK\r\n"),
9485 MockRead("Alt-Svc: clear\r\n"),
9486 MockRead("\r\n"),
9487 MockRead("hello world"),
9488 MockRead(SYNCHRONOUS, OK),
9489 };
9490 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
9491 session_deps_.socket_factory->AddSocketDataProvider(&data);
9492
9493 HttpRequestInfo request;
9494 request.method = "GET";
9495 request.url = GURL("http://www.example.org/");
9496 request.load_flags = 0;
9497
9498 TestCompletionCallback callback;
9499
9500 scoped_ptr<HttpTransaction> trans(
9501 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9502
9503 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9504 EXPECT_EQ(OK, callback.GetResult(rv));
9505
9506 const HttpResponseInfo* response = trans->GetResponseInfo();
9507 ASSERT_TRUE(response != nullptr);
9508 ASSERT_TRUE(response->headers.get() != nullptr);
9509 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9510 EXPECT_FALSE(response->was_fetched_via_spdy);
9511 EXPECT_FALSE(response->was_npn_negotiated);
9512
9513 std::string response_data;
9514 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9515 EXPECT_EQ("hello world", response_data);
9516
9517 alternative_service_vector =
9518 http_server_properties.GetAlternativeServices(http_host_port_pair);
9519 EXPECT_TRUE(alternative_service_vector.empty());
9520}
9521
bnc54ec34b72015-08-26 19:34:569522// Alternative Service headers must be ignored when |use_alternative_services|
9523// is false.
9524TEST_P(HttpNetworkTransactionTest, DoNotHonorAlternativeServiceHeader) {
9525 session_deps_.next_protos = SpdyNextProtos();
9526 session_deps_.use_alternative_services = false;
9527
9528 std::string alternative_service_http_header =
9529 GetAlternativeServiceHttpHeader();
9530
9531 MockRead data_reads[] = {
9532 MockRead("HTTP/1.1 200 OK\r\n"),
9533 MockRead(alternative_service_http_header.c_str()),
9534 MockRead("\r\n"),
9535 MockRead("hello world"),
9536 MockRead(SYNCHRONOUS, OK),
9537 };
9538
9539 HttpRequestInfo request;
9540 request.method = "GET";
9541 request.url = GURL("http://www.example.org/");
9542 request.load_flags = 0;
9543
9544 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
9545
9546 session_deps_.socket_factory->AddSocketDataProvider(&data);
9547
9548 TestCompletionCallback callback;
9549
mmenkee65e7af2015-10-13 17:16:429550 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc54ec34b72015-08-26 19:34:569551 scoped_ptr<HttpTransaction> trans(
9552 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9553
9554 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9555 EXPECT_EQ(ERR_IO_PENDING, rv);
9556
9557 HostPortPair http_host_port_pair("www.example.org", 80);
9558 HttpServerProperties& http_server_properties =
9559 *session->http_server_properties();
9560 AlternativeServiceVector alternative_service_vector =
9561 http_server_properties.GetAlternativeServices(http_host_port_pair);
9562 EXPECT_TRUE(alternative_service_vector.empty());
9563
9564 EXPECT_EQ(OK, callback.WaitForResult());
9565
9566 const HttpResponseInfo* response = trans->GetResponseInfo();
9567 ASSERT_TRUE(response != nullptr);
9568 ASSERT_TRUE(response->headers.get() != nullptr);
9569 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9570 EXPECT_FALSE(response->was_fetched_via_spdy);
9571 EXPECT_FALSE(response->was_npn_negotiated);
9572
9573 std::string response_data;
9574 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9575 EXPECT_EQ("hello world", response_data);
9576
9577 alternative_service_vector =
9578 http_server_properties.GetAlternativeServices(http_host_port_pair);
9579 EXPECT_TRUE(alternative_service_vector.empty());
9580}
9581
bncc958faa2015-07-31 18:14:529582TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
9583 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359584 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529585
9586 MockRead data_reads[] = {
9587 MockRead("HTTP/1.1 200 OK\r\n"),
9588 MockRead("Alt-Svc: "),
9589 MockRead(GetAlternateProtocolFromParam()),
bnc44858c82015-10-16 11:57:219590 MockRead("=\"www.example.com:443\";p=\"1.0\","),
bncc958faa2015-07-31 18:14:529591 MockRead("quic=\":1234\"\r\n\r\n"),
9592 MockRead("hello world"),
9593 MockRead(SYNCHRONOUS, OK),
9594 };
9595
9596 HttpRequestInfo request;
9597 request.method = "GET";
9598 request.url = GURL("http://www.example.org/");
9599 request.load_flags = 0;
9600
9601 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9602
9603 session_deps_.socket_factory->AddSocketDataProvider(&data);
9604
9605 TestCompletionCallback callback;
9606
mmenkee65e7af2015-10-13 17:16:429607 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529608 scoped_ptr<HttpTransaction> trans(
9609 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9610
9611 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9612 EXPECT_EQ(ERR_IO_PENDING, rv);
9613
9614 HostPortPair http_host_port_pair("www.example.org", 80);
9615 HttpServerProperties& http_server_properties =
9616 *session->http_server_properties();
9617 AlternativeServiceVector alternative_service_vector =
9618 http_server_properties.GetAlternativeServices(http_host_port_pair);
9619 EXPECT_TRUE(alternative_service_vector.empty());
9620
9621 EXPECT_EQ(OK, callback.WaitForResult());
9622
9623 const HttpResponseInfo* response = trans->GetResponseInfo();
9624 ASSERT_TRUE(response != NULL);
9625 ASSERT_TRUE(response->headers.get() != NULL);
9626 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9627 EXPECT_FALSE(response->was_fetched_via_spdy);
9628 EXPECT_FALSE(response->was_npn_negotiated);
9629
9630 std::string response_data;
9631 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9632 EXPECT_EQ("hello world", response_data);
9633
9634 alternative_service_vector =
9635 http_server_properties.GetAlternativeServices(http_host_port_pair);
9636 ASSERT_EQ(2u, alternative_service_vector.size());
9637 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9638 alternative_service_vector[0].protocol);
9639 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9640 EXPECT_EQ(443, alternative_service_vector[0].port);
9641 EXPECT_EQ(QUIC, alternative_service_vector[1].protocol);
9642 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
9643 EXPECT_EQ(1234, alternative_service_vector[1].port);
9644}
9645
bnc54ec34b72015-08-26 19:34:569646// Alternate Protocol headers must be honored even if |use_alternative_services|
9647// is false.
[email protected]23e482282013-06-14 16:08:029648TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:239649 session_deps_.next_protos = SpdyNextProtos();
bnc54ec34b72015-08-26 19:34:569650 session_deps_.use_alternative_services = false;
[email protected]a2cb8122010-03-10 17:22:429651
[email protected]8a0fc822013-06-27 20:52:439652 std::string alternate_protocol_http_header =
9653 GetAlternateProtocolHttpHeader();
9654
[email protected]564b4912010-03-09 16:30:429655 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529656 MockRead("HTTP/1.1 200 OK\r\n"),
9657 MockRead(alternate_protocol_http_header.c_str()),
9658 MockRead("\r\n"),
9659 MockRead("hello world"),
9660 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:429661 };
9662
9663 HttpRequestInfo request;
9664 request.method = "GET";
bncce36dca22015-04-21 22:11:239665 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429666 request.load_flags = 0;
9667
9668 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9669
[email protected]bb88e1d32013-05-03 23:11:079670 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:429671
[email protected]49639fa2011-12-20 23:22:419672 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429673
mmenkee65e7af2015-10-13 17:16:429674 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369675 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509676 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:429677
[email protected]49639fa2011-12-20 23:22:419678 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429679 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:539680
bncce36dca22015-04-21 22:11:239681 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:559682 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:539683 *session->http_server_properties();
bncd9b132e2015-07-08 05:16:109684 AlternativeServiceVector alternative_service_vector =
9685 http_server_properties.GetAlternativeServices(http_host_port_pair);
9686 EXPECT_TRUE(alternative_service_vector.empty());
[email protected]564b4912010-03-09 16:30:429687
9688 EXPECT_EQ(OK, callback.WaitForResult());
9689
9690 const HttpResponseInfo* response = trans->GetResponseInfo();
9691 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509692 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429693 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539694 EXPECT_FALSE(response->was_fetched_via_spdy);
9695 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:429696
9697 std::string response_data;
9698 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9699 EXPECT_EQ("hello world", response_data);
9700
bncd9b132e2015-07-08 05:16:109701 alternative_service_vector =
9702 http_server_properties.GetAlternativeServices(http_host_port_pair);
9703 ASSERT_EQ(1u, alternative_service_vector.size());
9704 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc181b39a2015-03-17 21:36:479705 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
bncd9b132e2015-07-08 05:16:109706 alternative_service_vector[0].protocol);
[email protected]564b4912010-03-09 16:30:429707}
9708
rch89c6e102015-03-18 18:56:529709TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
9710 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359711 session_deps_.use_alternative_services = true;
rch89c6e102015-03-18 18:56:529712
9713 MockRead data_reads[] = {
9714 MockRead("HTTP/1.1 200 OK\r\n"),
9715 MockRead("Alternate-Protocol: \r\n\r\n"),
9716 MockRead("hello world"),
9717 MockRead(SYNCHRONOUS, OK),
9718 };
9719
9720 HttpRequestInfo request;
9721 request.method = "GET";
bncce36dca22015-04-21 22:11:239722 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:529723 request.load_flags = 0;
9724
9725 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9726
9727 session_deps_.socket_factory->AddSocketDataProvider(&data);
9728
9729 TestCompletionCallback callback;
9730
mmenkee65e7af2015-10-13 17:16:429731 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rch89c6e102015-03-18 18:56:529732
bncce36dca22015-04-21 22:11:239733 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:529734 HttpServerProperties& http_server_properties =
9735 *session->http_server_properties();
bnccacc0992015-03-20 20:22:229736 AlternativeService alternative_service(QUIC, "", 80);
bnc7dc7e1b42015-07-28 14:43:129737 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9738 http_server_properties.SetAlternativeService(
9739 http_host_port_pair, alternative_service, 1.0, expiration);
bnccacc0992015-03-20 20:22:229740
bncd9b132e2015-07-08 05:16:109741 AlternativeServiceVector alternative_service_vector =
9742 http_server_properties.GetAlternativeServices(http_host_port_pair);
9743 ASSERT_EQ(1u, alternative_service_vector.size());
9744 EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
rch89c6e102015-03-18 18:56:529745
9746 scoped_ptr<HttpTransaction> trans(
9747 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9748
9749 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9750 EXPECT_EQ(ERR_IO_PENDING, rv);
9751
9752 EXPECT_EQ(OK, callback.WaitForResult());
9753
9754 const HttpResponseInfo* response = trans->GetResponseInfo();
9755 ASSERT_TRUE(response != NULL);
9756 ASSERT_TRUE(response->headers.get() != NULL);
9757 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9758 EXPECT_FALSE(response->was_fetched_via_spdy);
9759 EXPECT_FALSE(response->was_npn_negotiated);
9760
9761 std::string response_data;
9762 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9763 EXPECT_EQ("hello world", response_data);
9764
bncd9b132e2015-07-08 05:16:109765 alternative_service_vector =
9766 http_server_properties.GetAlternativeServices(http_host_port_pair);
9767 EXPECT_TRUE(alternative_service_vector.empty());
rch89c6e102015-03-18 18:56:529768}
9769
bncc958faa2015-07-31 18:14:529770TEST_P(HttpNetworkTransactionTest, AltSvcOverwritesAlternateProtocol) {
9771 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359772 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529773
9774 std::string alternative_service_http_header =
9775 GetAlternativeServiceHttpHeader();
9776 std::string alternate_protocol_http_header = GetAlternateProtocolHttpHeader();
9777
9778 MockRead data_reads[] = {
9779 MockRead("HTTP/1.1 200 OK\r\n"),
9780 MockRead(alternative_service_http_header.c_str()),
9781 MockRead(alternate_protocol_http_header.c_str()),
9782 MockRead("\r\n"),
9783 MockRead("hello world"),
9784 MockRead(SYNCHRONOUS, OK),
9785 };
9786
9787 HttpRequestInfo request;
9788 request.method = "GET";
9789 request.url = GURL("http://www.example.org/");
9790 request.load_flags = 0;
9791
9792 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9793
9794 session_deps_.socket_factory->AddSocketDataProvider(&data);
9795
9796 TestCompletionCallback callback;
9797
mmenkee65e7af2015-10-13 17:16:429798 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529799 scoped_ptr<HttpTransaction> trans(
9800 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9801
9802 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9803 EXPECT_EQ(ERR_IO_PENDING, rv);
9804
9805 HostPortPair http_host_port_pair("www.example.org", 80);
9806 HttpServerProperties& http_server_properties =
9807 *session->http_server_properties();
9808 AlternativeServiceVector alternative_service_vector =
9809 http_server_properties.GetAlternativeServices(http_host_port_pair);
9810 EXPECT_TRUE(alternative_service_vector.empty());
9811
9812 EXPECT_EQ(OK, callback.WaitForResult());
9813
9814 const HttpResponseInfo* response = trans->GetResponseInfo();
9815 ASSERT_TRUE(response != NULL);
9816 ASSERT_TRUE(response->headers.get() != NULL);
9817 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9818 EXPECT_FALSE(response->was_fetched_via_spdy);
9819 EXPECT_FALSE(response->was_npn_negotiated);
9820
9821 std::string response_data;
9822 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9823 EXPECT_EQ("hello world", response_data);
9824
9825 alternative_service_vector =
9826 http_server_properties.GetAlternativeServices(http_host_port_pair);
9827 ASSERT_EQ(1u, alternative_service_vector.size());
9828 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9829 alternative_service_vector[0].protocol);
9830 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9831 EXPECT_EQ(443, alternative_service_vector[0].port);
9832}
9833
bnc54ec34b72015-08-26 19:34:569834// When |use_alternative_services| is false, do not observe alternative service
9835// entries that point to a different host.
9836TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
9837 session_deps_.use_alternative_services = false;
9838
9839 HttpRequestInfo request;
9840 request.method = "GET";
9841 request.url = GURL("http://www.example.org/");
9842 request.load_flags = 0;
9843
9844 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9845 StaticSocketDataProvider first_data;
9846 first_data.set_connect_data(mock_connect);
9847 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
9848
9849 MockRead data_reads[] = {
9850 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
9851 MockRead(ASYNC, OK),
9852 };
9853 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
9854 nullptr, 0);
9855 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
9856
mmenkee65e7af2015-10-13 17:16:429857 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc54ec34b72015-08-26 19:34:569858
9859 base::WeakPtr<HttpServerProperties> http_server_properties =
9860 session->http_server_properties();
9861 AlternativeService alternative_service(
9862 AlternateProtocolFromNextProto(GetParam()), "different.example.org", 80);
9863 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9864 http_server_properties->SetAlternativeService(
9865 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
9866
9867 scoped_ptr<HttpTransaction> trans(
9868 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9869 TestCompletionCallback callback;
9870
9871 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9872 // The connetion to origin was refused, and the alternative service should not
9873 // be used (even though mock data are there), therefore the request should
9874 // fail.
9875 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
9876}
9877
[email protected]23e482282013-06-14 16:08:029878TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239879 MarkBrokenAlternateProtocolAndFallback) {
bnc55ff9da2015-08-19 18:42:359880 session_deps_.use_alternative_services = true;
[email protected]564b4912010-03-09 16:30:429881
9882 HttpRequestInfo request;
9883 request.method = "GET";
bncce36dca22015-04-21 22:11:239884 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429885 request.load_flags = 0;
9886
[email protected]d973e99a2012-02-17 21:02:369887 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:429888 StaticSocketDataProvider first_data;
9889 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079890 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:429891
9892 MockRead data_reads[] = {
9893 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9894 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069895 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:429896 };
9897 StaticSocketDataProvider second_data(
9898 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079899 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:429900
mmenkee65e7af2015-10-13 17:16:429901 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:429902
[email protected]30d4c022013-07-18 22:58:169903 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539904 session->http_server_properties();
bnc8445b3002015-03-13 01:57:099905 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:119906 // Port must be < 1024, or the header will be ignored (since initial port was
9907 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:109908 const AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239909 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bncd9b132e2015-07-08 05:16:109910 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:129911 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9912 http_server_properties->SetAlternativeService(
9913 host_port_pair, alternative_service, 1.0, expiration);
[email protected]564b4912010-03-09 16:30:429914
[email protected]262eec82013-03-19 21:01:369915 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509916 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419917 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429918
[email protected]49639fa2011-12-20 23:22:419919 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429920 EXPECT_EQ(ERR_IO_PENDING, rv);
9921 EXPECT_EQ(OK, callback.WaitForResult());
9922
9923 const HttpResponseInfo* response = trans->GetResponseInfo();
9924 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509925 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429926 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9927
9928 std::string response_data;
9929 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9930 EXPECT_EQ("hello world", response_data);
9931
bncd9b132e2015-07-08 05:16:109932 const AlternativeServiceVector alternative_service_vector =
9933 http_server_properties->GetAlternativeServices(host_port_pair);
9934 ASSERT_EQ(1u, alternative_service_vector.size());
9935 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
9936 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
9937 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:429938}
9939
bnc55ff9da2015-08-19 18:42:359940// Ensure that we are not allowed to redirect traffic via an alternate protocol
9941// to an unrestricted (port >= 1024) when the original traffic was on a
9942// restricted port (port < 1024). Ensure that we can redirect in all other
9943// cases.
[email protected]23e482282013-06-14 16:08:029944TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239945 AlternateProtocolPortRestrictedBlocked) {
bnc55ff9da2015-08-19 18:42:359946 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119947
9948 HttpRequestInfo restricted_port_request;
9949 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239950 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119951 restricted_port_request.load_flags = 0;
9952
[email protected]d973e99a2012-02-17 21:02:369953 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119954 StaticSocketDataProvider first_data;
9955 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079956 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119957
9958 MockRead data_reads[] = {
9959 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9960 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069961 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119962 };
9963 StaticSocketDataProvider second_data(
9964 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079965 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119966
mmenkee65e7af2015-10-13 17:16:429967 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119968
[email protected]30d4c022013-07-18 22:58:169969 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539970 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119971 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229972 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239973 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229974 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129975 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229976 http_server_properties->SetAlternativeService(
9977 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129978 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119979
[email protected]262eec82013-03-19 21:01:369980 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509981 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419982 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119983
[email protected]49639fa2011-12-20 23:22:419984 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369985 &restricted_port_request,
9986 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119987 EXPECT_EQ(ERR_IO_PENDING, rv);
9988 // Invalid change to unrestricted port should fail.
9989 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:199990}
[email protected]3912662a32011-10-04 00:51:119991
bnc55ff9da2015-08-19 18:42:359992// Ensure that we are allowed to redirect traffic via an alternate protocol to
9993// an unrestricted (port >= 1024) when the original traffic was on a restricted
9994// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:029995TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:199996 AlternateProtocolPortRestrictedPermitted) {
bnc55ff9da2015-08-19 18:42:359997 session_deps_.use_alternative_services = true;
[email protected]bb88e1d32013-05-03 23:11:079998 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:199999
10000 HttpRequestInfo restricted_port_request;
10001 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310002 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910003 restricted_port_request.load_flags = 0;
10004
10005 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10006 StaticSocketDataProvider first_data;
10007 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710008 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910009
10010 MockRead data_reads[] = {
10011 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10012 MockRead("hello world"),
10013 MockRead(ASYNC, OK),
10014 };
10015 StaticSocketDataProvider second_data(
10016 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710017 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:1910018
mmenkee65e7af2015-10-13 17:16:4210019 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910020
[email protected]30d4c022013-07-18 22:58:1610021 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910022 session->http_server_properties();
10023 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210024 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:2310025 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:2210026 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210027 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210028 http_server_properties->SetAlternativeService(
10029 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:1210030 1.0, expiration);
[email protected]c54c6962013-02-01 04:53:1910031
[email protected]262eec82013-03-19 21:01:3610032 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010033 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:1910034 TestCompletionCallback callback;
10035
10036 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:3610037 &restricted_port_request,
10038 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:1910039 // Change to unrestricted port should succeed.
10040 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110041}
10042
bnc55ff9da2015-08-19 18:42:3510043// Ensure that we are not allowed to redirect traffic via an alternate protocol
10044// to an unrestricted (port >= 1024) when the original traffic was on a
10045// restricted port (port < 1024). Ensure that we can redirect in all other
10046// cases.
[email protected]23e482282013-06-14 16:08:0210047TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310048 AlternateProtocolPortRestrictedAllowed) {
bnc55ff9da2015-08-19 18:42:3510049 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:1110050
10051 HttpRequestInfo restricted_port_request;
10052 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310053 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110054 restricted_port_request.load_flags = 0;
10055
[email protected]d973e99a2012-02-17 21:02:3610056 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110057 StaticSocketDataProvider first_data;
10058 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710059 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110060
10061 MockRead data_reads[] = {
10062 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10063 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610064 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110065 };
10066 StaticSocketDataProvider second_data(
10067 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710068 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110069
mmenkee65e7af2015-10-13 17:16:4210070 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110071
[email protected]30d4c022013-07-18 22:58:1610072 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310073 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110074 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210075 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:2310076 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:2210077 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210078 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210079 http_server_properties->SetAlternativeService(
10080 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:1210081 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:1110082
[email protected]262eec82013-03-19 21:01:3610083 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010084 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110085 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110086
[email protected]49639fa2011-12-20 23:22:4110087 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610088 &restricted_port_request,
10089 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110090 EXPECT_EQ(ERR_IO_PENDING, rv);
10091 // Valid change to restricted port should pass.
10092 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110093}
10094
bnc55ff9da2015-08-19 18:42:3510095// Ensure that we are not allowed to redirect traffic via an alternate protocol
10096// to an unrestricted (port >= 1024) when the original traffic was on a
10097// restricted port (port < 1024). Ensure that we can redirect in all other
10098// cases.
[email protected]23e482282013-06-14 16:08:0210099TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310100 AlternateProtocolPortUnrestrictedAllowed1) {
bnc55ff9da2015-08-19 18:42:3510101 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:1110102
10103 HttpRequestInfo unrestricted_port_request;
10104 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310105 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110106 unrestricted_port_request.load_flags = 0;
10107
[email protected]d973e99a2012-02-17 21:02:3610108 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110109 StaticSocketDataProvider first_data;
10110 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710111 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110112
10113 MockRead data_reads[] = {
10114 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10115 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610116 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110117 };
10118 StaticSocketDataProvider second_data(
10119 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710120 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110121
mmenkee65e7af2015-10-13 17:16:4210122 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110123
[email protected]30d4c022013-07-18 22:58:1610124 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310125 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110126 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210127 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:2310128 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:2210129 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210130 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210131 http_server_properties->SetAlternativeService(
10132 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:1210133 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:1110134
[email protected]262eec82013-03-19 21:01:3610135 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010136 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110137 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110138
[email protected]49639fa2011-12-20 23:22:4110139 int rv = trans->Start(
10140 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110141 EXPECT_EQ(ERR_IO_PENDING, rv);
10142 // Valid change to restricted port should pass.
10143 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110144}
10145
bnc55ff9da2015-08-19 18:42:3510146// Ensure that we are not allowed to redirect traffic via an alternate protocol
10147// to an unrestricted (port >= 1024) when the original traffic was on a
10148// restricted port (port < 1024). Ensure that we can redirect in all other
10149// cases.
[email protected]23e482282013-06-14 16:08:0210150TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310151 AlternateProtocolPortUnrestrictedAllowed2) {
bnc55ff9da2015-08-19 18:42:3510152 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:1110153
10154 HttpRequestInfo unrestricted_port_request;
10155 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310156 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110157 unrestricted_port_request.load_flags = 0;
10158
[email protected]d973e99a2012-02-17 21:02:3610159 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110160 StaticSocketDataProvider first_data;
10161 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710162 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110163
10164 MockRead data_reads[] = {
10165 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10166 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610167 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110168 };
10169 StaticSocketDataProvider second_data(
10170 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710171 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110172
mmenkee65e7af2015-10-13 17:16:4210173 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110174
[email protected]30d4c022013-07-18 22:58:1610175 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310176 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210177 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:2210178 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:2310179 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:2210180 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210181 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210182 http_server_properties->SetAlternativeService(
10183 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:1210184 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:1110185
[email protected]262eec82013-03-19 21:01:3610186 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010187 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110188 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110189
[email protected]49639fa2011-12-20 23:22:4110190 int rv = trans->Start(
10191 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110192 EXPECT_EQ(ERR_IO_PENDING, rv);
10193 // Valid change to an unrestricted port should pass.
10194 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110195}
10196
bnc55ff9da2015-08-19 18:42:3510197// Ensure that we are not allowed to redirect traffic via an alternate protocol
10198// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10199// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:2310200TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bnc55ff9da2015-08-19 18:42:3510201 session_deps_.use_alternative_services = true;
[email protected]eb6234e2012-01-19 01:50:0210202
10203 HttpRequestInfo request;
10204 request.method = "GET";
bncce36dca22015-04-21 22:11:2310205 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210206 request.load_flags = 0;
10207
10208 // The alternate protocol request will error out before we attempt to connect,
10209 // so only the standard HTTP request will try to connect.
10210 MockRead data_reads[] = {
10211 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10212 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610213 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210214 };
10215 StaticSocketDataProvider data(
10216 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710217 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210218
mmenkee65e7af2015-10-13 17:16:4210219 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210220
[email protected]30d4c022013-07-18 22:58:1610221 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210222 session->http_server_properties();
10223 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:2210224 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:2310225 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:2210226 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210227 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210228 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:1210229 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
[email protected]eb6234e2012-01-19 01:50:0210230
[email protected]262eec82013-03-19 21:01:3610231 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010232 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:0210233 TestCompletionCallback callback;
10234
10235 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10236 EXPECT_EQ(ERR_IO_PENDING, rv);
10237 // The HTTP request should succeed.
10238 EXPECT_EQ(OK, callback.WaitForResult());
10239
[email protected]eb6234e2012-01-19 01:50:0210240 const HttpResponseInfo* response = trans->GetResponseInfo();
10241 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010242 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:0210243 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10244
10245 std::string response_data;
10246 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10247 EXPECT_EQ("hello world", response_data);
10248}
10249
[email protected]23e482282013-06-14 16:08:0210250TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:3510251 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310252 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:5410253
10254 HttpRequestInfo request;
10255 request.method = "GET";
bncce36dca22015-04-21 22:11:2310256 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410257 request.load_flags = 0;
10258
[email protected]8a0fc822013-06-27 20:52:4310259 std::string alternate_protocol_http_header =
10260 GetAlternateProtocolHttpHeader();
10261
[email protected]2ff8b312010-04-26 22:20:5410262 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210263 MockRead("HTTP/1.1 200 OK\r\n"),
10264 MockRead(alternate_protocol_http_header.c_str()),
10265 MockRead("\r\n"),
10266 MockRead("hello world"),
10267 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10268 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410269
10270 StaticSocketDataProvider first_transaction(
10271 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710272 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410273
[email protected]8ddf8322012-02-23 18:08:0610274 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210275 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310276 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10277 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710278 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410279
[email protected]cdf8f7e72013-05-23 10:56:4610280 scoped_ptr<SpdyFrame> req(
10281 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310282 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410283
[email protected]23e482282013-06-14 16:08:0210284 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10285 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410286 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310287 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410288 };
10289
rch8e6c6c42015-05-01 14:05:1310290 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10291 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710292 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410293
[email protected]d973e99a2012-02-17 21:02:3610294 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510295 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10296 NULL, 0, NULL, 0);
10297 hanging_non_alternate_protocol_socket.set_connect_data(
10298 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710299 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510300 &hanging_non_alternate_protocol_socket);
10301
[email protected]49639fa2011-12-20 23:22:4110302 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410303
mmenkee65e7af2015-10-13 17:16:4210304 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610305 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410307
[email protected]49639fa2011-12-20 23:22:4110308 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410309 EXPECT_EQ(ERR_IO_PENDING, rv);
10310 EXPECT_EQ(OK, callback.WaitForResult());
10311
10312 const HttpResponseInfo* response = trans->GetResponseInfo();
10313 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010314 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410315 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10316
10317 std::string response_data;
10318 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10319 EXPECT_EQ("hello world", response_data);
10320
[email protected]90499482013-06-01 00:39:5010321 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410322
[email protected]49639fa2011-12-20 23:22:4110323 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410324 EXPECT_EQ(ERR_IO_PENDING, rv);
10325 EXPECT_EQ(OK, callback.WaitForResult());
10326
10327 response = trans->GetResponseInfo();
10328 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010329 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410330 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310331 EXPECT_TRUE(response->was_fetched_via_spdy);
10332 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410333
10334 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10335 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410336}
10337
[email protected]23e482282013-06-14 16:08:0210338TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
bnc55ff9da2015-08-19 18:42:3510339 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310340 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:5510341
10342 HttpRequestInfo request;
10343 request.method = "GET";
bncce36dca22015-04-21 22:11:2310344 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510345 request.load_flags = 0;
10346
[email protected]8a0fc822013-06-27 20:52:4310347 std::string alternate_protocol_http_header =
10348 GetAlternateProtocolHttpHeader();
10349
[email protected]2d6728692011-03-12 01:39:5510350 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210351 MockRead("HTTP/1.1 200 OK\r\n"),
10352 MockRead(alternate_protocol_http_header.c_str()),
10353 MockRead("\r\n"),
10354 MockRead("hello world"),
10355 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10356 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510357 };
10358
10359 StaticSocketDataProvider first_transaction(
10360 data_reads, arraysize(data_reads), NULL, 0);
10361 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:0710362 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510363
[email protected]d973e99a2012-02-17 21:02:3610364 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510365 StaticSocketDataProvider hanging_socket(
10366 NULL, 0, NULL, 0);
10367 hanging_socket.set_connect_data(never_finishing_connect);
10368 // Socket 2 and 3 are the hanging Alternate-Protocol and
10369 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:0710370 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
10371 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:5510372
[email protected]8ddf8322012-02-23 18:08:0610373 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210374 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310375 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10376 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710377 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510378
[email protected]cdf8f7e72013-05-23 10:56:4610379 scoped_ptr<SpdyFrame> req1(
10380 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
10381 scoped_ptr<SpdyFrame> req2(
10382 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:5510383 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310384 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:5510385 };
[email protected]23e482282013-06-14 16:08:0210386 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10387 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
10388 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10389 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510390 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310391 CreateMockRead(*resp1, 2),
10392 CreateMockRead(*data1, 3),
10393 CreateMockRead(*resp2, 4),
10394 CreateMockRead(*data2, 5),
10395 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510396 };
10397
rch8e6c6c42015-05-01 14:05:1310398 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10399 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:5510400 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:0710401 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510402
10403 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:0710404 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:5510405
mmenkee65e7af2015-10-13 17:16:4210406 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110407 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010408 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510409
[email protected]49639fa2011-12-20 23:22:4110410 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510411 EXPECT_EQ(ERR_IO_PENDING, rv);
10412 EXPECT_EQ(OK, callback1.WaitForResult());
10413
10414 const HttpResponseInfo* response = trans1.GetResponseInfo();
10415 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010416 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510417 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10418
10419 std::string response_data;
10420 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10421 EXPECT_EQ("hello world", response_data);
10422
[email protected]49639fa2011-12-20 23:22:4110423 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5010424 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110425 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510426 EXPECT_EQ(ERR_IO_PENDING, rv);
10427
[email protected]49639fa2011-12-20 23:22:4110428 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5010429 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110430 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510431 EXPECT_EQ(ERR_IO_PENDING, rv);
10432
10433 EXPECT_EQ(OK, callback2.WaitForResult());
10434 EXPECT_EQ(OK, callback3.WaitForResult());
10435
10436 response = trans2.GetResponseInfo();
10437 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010438 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510439 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10440 EXPECT_TRUE(response->was_fetched_via_spdy);
10441 EXPECT_TRUE(response->was_npn_negotiated);
10442 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10443 EXPECT_EQ("hello!", response_data);
10444
10445 response = trans3.GetResponseInfo();
10446 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010447 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510448 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10449 EXPECT_TRUE(response->was_fetched_via_spdy);
10450 EXPECT_TRUE(response->was_npn_negotiated);
10451 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
10452 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5510453}
10454
[email protected]23e482282013-06-14 16:08:0210455TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:3510456 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310457 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:5510458
10459 HttpRequestInfo request;
10460 request.method = "GET";
bncce36dca22015-04-21 22:11:2310461 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510462 request.load_flags = 0;
10463
[email protected]8a0fc822013-06-27 20:52:4310464 std::string alternate_protocol_http_header =
10465 GetAlternateProtocolHttpHeader();
10466
[email protected]2d6728692011-03-12 01:39:5510467 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210468 MockRead("HTTP/1.1 200 OK\r\n"),
10469 MockRead(alternate_protocol_http_header.c_str()),
10470 MockRead("\r\n"),
10471 MockRead("hello world"),
10472 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10473 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510474 };
10475
10476 StaticSocketDataProvider first_transaction(
10477 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710478 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510479
[email protected]8ddf8322012-02-23 18:08:0610480 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210481 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710482 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510483
[email protected]d973e99a2012-02-17 21:02:3610484 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510485 StaticSocketDataProvider hanging_alternate_protocol_socket(
10486 NULL, 0, NULL, 0);
10487 hanging_alternate_protocol_socket.set_connect_data(
10488 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710489 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510490 &hanging_alternate_protocol_socket);
10491
10492 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:0710493 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510494
[email protected]49639fa2011-12-20 23:22:4110495 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5510496
mmenkee65e7af2015-10-13 17:16:4210497 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610498 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010499 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510500
[email protected]49639fa2011-12-20 23:22:4110501 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510502 EXPECT_EQ(ERR_IO_PENDING, rv);
10503 EXPECT_EQ(OK, callback.WaitForResult());
10504
10505 const HttpResponseInfo* response = trans->GetResponseInfo();
10506 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010507 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510508 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10509
10510 std::string response_data;
10511 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10512 EXPECT_EQ("hello world", response_data);
10513
[email protected]90499482013-06-01 00:39:5010514 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510515
[email protected]49639fa2011-12-20 23:22:4110516 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510517 EXPECT_EQ(ERR_IO_PENDING, rv);
10518 EXPECT_EQ(OK, callback.WaitForResult());
10519
10520 response = trans->GetResponseInfo();
10521 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010522 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510523 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10524 EXPECT_FALSE(response->was_fetched_via_spdy);
10525 EXPECT_FALSE(response->was_npn_negotiated);
10526
10527 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10528 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5510529}
10530
[email protected]631f1322010-04-30 17:59:1110531class CapturingProxyResolver : public ProxyResolver {
10532 public:
sammce90c9212015-05-27 23:43:3510533 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2010534 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1110535
dchengb03027d2014-10-21 12:00:2010536 int GetProxyForURL(const GURL& url,
10537 ProxyInfo* results,
10538 const CompletionCallback& callback,
10539 RequestHandle* request,
10540 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4010541 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
10542 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4210543 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1110544 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4210545 return OK;
[email protected]631f1322010-04-30 17:59:1110546 }
10547
dchengb03027d2014-10-21 12:00:2010548 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:1110549
dchengb03027d2014-10-21 12:00:2010550 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:1710551 NOTREACHED();
10552 return LOAD_STATE_IDLE;
10553 }
10554
[email protected]24476402010-07-20 20:55:1710555 const std::vector<GURL>& resolved() const { return resolved_; }
10556
10557 private:
[email protected]631f1322010-04-30 17:59:1110558 std::vector<GURL> resolved_;
10559
10560 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
10561};
10562
sammce64b2362015-04-29 03:50:2310563class CapturingProxyResolverFactory : public ProxyResolverFactory {
10564 public:
10565 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
10566 : ProxyResolverFactory(false), resolver_(resolver) {}
10567
10568 int CreateProxyResolver(
10569 const scoped_refptr<ProxyResolverScriptData>& pac_script,
10570 scoped_ptr<ProxyResolver>* resolver,
10571 const net::CompletionCallback& callback,
10572 scoped_ptr<Request>* request) override {
10573 resolver->reset(new ForwardingProxyResolver(resolver_));
10574 return OK;
10575 }
10576
10577 private:
10578 ProxyResolver* resolver_;
10579};
10580
[email protected]23e482282013-06-14 16:08:0210581TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310582 UseAlternateProtocolForTunneledNpnSpdy) {
bnc55ff9da2015-08-19 18:42:3510583 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310584 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:1110585
10586 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4210587 proxy_config.set_auto_detect(true);
10588 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1110589
sammc5dd160c2015-04-02 02:43:1310590 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710591 session_deps_.proxy_service.reset(new ProxyService(
csharrisonb7e3a082015-09-22 19:13:0410592 make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)),
sammc5dd160c2015-04-02 02:43:1310593 make_scoped_ptr(
sammce64b2362015-04-29 03:50:2310594 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:3810595 NULL));
vishal.b62985ca92015-04-17 08:45:5110596 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710597 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1110598
10599 HttpRequestInfo request;
10600 request.method = "GET";
bncce36dca22015-04-21 22:11:2310601 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:1110602 request.load_flags = 0;
10603
[email protected]8a0fc822013-06-27 20:52:4310604 std::string alternate_protocol_http_header =
10605 GetAlternateProtocolHttpHeader();
10606
[email protected]631f1322010-04-30 17:59:1110607 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210608 MockRead("HTTP/1.1 200 OK\r\n"),
10609 MockRead(alternate_protocol_http_header.c_str()),
10610 MockRead("\r\n"),
10611 MockRead("hello world"),
10612 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10613 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1110614 };
10615
10616 StaticSocketDataProvider first_transaction(
10617 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710618 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:1110619
[email protected]8ddf8322012-02-23 18:08:0610620 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210621 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310622 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10623 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710624 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:1110625
[email protected]cdf8f7e72013-05-23 10:56:4610626 scoped_ptr<SpdyFrame> req(
10627 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:1110628 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310629 MockWrite(ASYNC, 0,
10630 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10631 "Host: www.example.org\r\n"
10632 "Proxy-Connection: keep-alive\r\n\r\n"),
10633 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:1110634 };
10635
[email protected]d911f1b2010-05-05 22:39:4210636 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10637
[email protected]23e482282013-06-14 16:08:0210638 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10639 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1110640 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310641 MockRead(ASYNC, 1, kCONNECTResponse),
10642 CreateMockRead(*resp.get(), 3),
10643 CreateMockRead(*data.get(), 4),
10644 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1110645 };
10646
rch8e6c6c42015-05-01 14:05:1310647 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10648 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710649 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1110650
[email protected]d973e99a2012-02-17 21:02:3610651 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510652 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10653 NULL, 0, NULL, 0);
10654 hanging_non_alternate_protocol_socket.set_connect_data(
10655 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710656 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510657 &hanging_non_alternate_protocol_socket);
10658
[email protected]49639fa2011-12-20 23:22:4110659 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1110660
mmenkee65e7af2015-10-13 17:16:4210661 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610662 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010663 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110664
[email protected]49639fa2011-12-20 23:22:4110665 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110666 EXPECT_EQ(ERR_IO_PENDING, rv);
10667 EXPECT_EQ(OK, callback.WaitForResult());
10668
10669 const HttpResponseInfo* response = trans->GetResponseInfo();
10670 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010671 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110672 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310673 EXPECT_FALSE(response->was_fetched_via_spdy);
10674 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110675
10676 std::string response_data;
10677 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10678 EXPECT_EQ("hello world", response_data);
10679
[email protected]90499482013-06-01 00:39:5010680 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110681
[email protected]49639fa2011-12-20 23:22:4110682 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110683 EXPECT_EQ(ERR_IO_PENDING, rv);
10684 EXPECT_EQ(OK, callback.WaitForResult());
10685
10686 response = trans->GetResponseInfo();
10687 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010688 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110689 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310690 EXPECT_TRUE(response->was_fetched_via_spdy);
10691 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110692
10693 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10694 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1310695 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2310696 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310697 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2310698 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310699 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1110700
[email protected]029c83b62013-01-24 05:28:2010701 LoadTimingInfo load_timing_info;
10702 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10703 TestLoadTimingNotReusedWithPac(load_timing_info,
10704 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1110705}
[email protected]631f1322010-04-30 17:59:1110706
[email protected]23e482282013-06-14 16:08:0210707TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:5410708 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
bnc55ff9da2015-08-19 18:42:3510709 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310710 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:5410711
10712 HttpRequestInfo request;
10713 request.method = "GET";
bncce36dca22015-04-21 22:11:2310714 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410715 request.load_flags = 0;
10716
[email protected]8a0fc822013-06-27 20:52:4310717 std::string alternate_protocol_http_header =
10718 GetAlternateProtocolHttpHeader();
10719
[email protected]2ff8b312010-04-26 22:20:5410720 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210721 MockRead("HTTP/1.1 200 OK\r\n"),
10722 MockRead(alternate_protocol_http_header.c_str()),
10723 MockRead("\r\n"),
10724 MockRead("hello world"),
10725 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5410726 };
10727
10728 StaticSocketDataProvider first_transaction(
10729 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710730 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410731
[email protected]8ddf8322012-02-23 18:08:0610732 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210733 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310734 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10735 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710736 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410737
[email protected]cdf8f7e72013-05-23 10:56:4610738 scoped_ptr<SpdyFrame> req(
10739 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310740 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410741
[email protected]23e482282013-06-14 16:08:0210742 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10743 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410744 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310745 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410746 };
10747
rch8e6c6c42015-05-01 14:05:1310748 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10749 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710750 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410751
[email protected]83039bb2011-12-09 18:43:5510752 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410753
mmenkee65e7af2015-10-13 17:16:4210754 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5410755
[email protected]262eec82013-03-19 21:01:3610756 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010757 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410758
[email protected]49639fa2011-12-20 23:22:4110759 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410760 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110761 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410762
10763 const HttpResponseInfo* response = trans->GetResponseInfo();
10764 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010765 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410766 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10767
10768 std::string response_data;
10769 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10770 EXPECT_EQ("hello world", response_data);
10771
10772 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310773 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010774 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310775 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710776 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4210777 CreateSecureSpdySession(session.get(), key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3810778
[email protected]90499482013-06-01 00:39:5010779 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410780
[email protected]49639fa2011-12-20 23:22:4110781 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410782 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110783 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410784
10785 response = trans->GetResponseInfo();
10786 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010787 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410788 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310789 EXPECT_TRUE(response->was_fetched_via_spdy);
10790 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410791
10792 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10793 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4210794}
10795
[email protected]044de0642010-06-17 10:42:1510796// GenerateAuthToken is a mighty big test.
10797// It tests all permutation of GenerateAuthToken behavior:
10798// - Synchronous and Asynchronous completion.
10799// - OK or error on completion.
10800// - Direct connection, non-authenticating proxy, and authenticating proxy.
10801// - HTTP or HTTPS backend (to include proxy tunneling).
10802// - Non-authenticating and authenticating backend.
10803//
[email protected]fe3b7dc2012-02-03 19:52:0910804// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1510805// problems generating an auth token for an authenticating proxy, we don't
10806// need to test all permutations of the backend server).
10807//
10808// The test proceeds by going over each of the configuration cases, and
10809// potentially running up to three rounds in each of the tests. The TestConfig
10810// specifies both the configuration for the test as well as the expectations
10811// for the results.
[email protected]23e482282013-06-14 16:08:0210812TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5010813 static const char kServer[] = "http://www.example.com";
10814 static const char kSecureServer[] = "https://www.example.com";
10815 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1510816 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
10817
10818 enum AuthTiming {
10819 AUTH_NONE,
10820 AUTH_SYNC,
10821 AUTH_ASYNC,
10822 };
10823
10824 const MockWrite kGet(
10825 "GET / HTTP/1.1\r\n"
10826 "Host: www.example.com\r\n"
10827 "Connection: keep-alive\r\n\r\n");
10828 const MockWrite kGetProxy(
10829 "GET http://www.example.com/ HTTP/1.1\r\n"
10830 "Host: www.example.com\r\n"
10831 "Proxy-Connection: keep-alive\r\n\r\n");
10832 const MockWrite kGetAuth(
10833 "GET / HTTP/1.1\r\n"
10834 "Host: www.example.com\r\n"
10835 "Connection: keep-alive\r\n"
10836 "Authorization: auth_token\r\n\r\n");
10837 const MockWrite kGetProxyAuth(
10838 "GET http://www.example.com/ HTTP/1.1\r\n"
10839 "Host: www.example.com\r\n"
10840 "Proxy-Connection: keep-alive\r\n"
10841 "Proxy-Authorization: auth_token\r\n\r\n");
10842 const MockWrite kGetAuthThroughProxy(
10843 "GET http://www.example.com/ HTTP/1.1\r\n"
10844 "Host: www.example.com\r\n"
10845 "Proxy-Connection: keep-alive\r\n"
10846 "Authorization: auth_token\r\n\r\n");
10847 const MockWrite kGetAuthWithProxyAuth(
10848 "GET http://www.example.com/ HTTP/1.1\r\n"
10849 "Host: www.example.com\r\n"
10850 "Proxy-Connection: keep-alive\r\n"
10851 "Proxy-Authorization: auth_token\r\n"
10852 "Authorization: auth_token\r\n\r\n");
10853 const MockWrite kConnect(
10854 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10855 "Host: www.example.com\r\n"
10856 "Proxy-Connection: keep-alive\r\n\r\n");
10857 const MockWrite kConnectProxyAuth(
10858 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10859 "Host: www.example.com\r\n"
10860 "Proxy-Connection: keep-alive\r\n"
10861 "Proxy-Authorization: auth_token\r\n\r\n");
10862
10863 const MockRead kSuccess(
10864 "HTTP/1.1 200 OK\r\n"
10865 "Content-Type: text/html; charset=iso-8859-1\r\n"
10866 "Content-Length: 3\r\n\r\n"
10867 "Yes");
10868 const MockRead kFailure(
10869 "Should not be called.");
10870 const MockRead kServerChallenge(
10871 "HTTP/1.1 401 Unauthorized\r\n"
10872 "WWW-Authenticate: Mock realm=server\r\n"
10873 "Content-Type: text/html; charset=iso-8859-1\r\n"
10874 "Content-Length: 14\r\n\r\n"
10875 "Unauthorized\r\n");
10876 const MockRead kProxyChallenge(
10877 "HTTP/1.1 407 Unauthorized\r\n"
10878 "Proxy-Authenticate: Mock realm=proxy\r\n"
10879 "Proxy-Connection: close\r\n"
10880 "Content-Type: text/html; charset=iso-8859-1\r\n"
10881 "Content-Length: 14\r\n\r\n"
10882 "Unauthorized\r\n");
10883 const MockRead kProxyConnected(
10884 "HTTP/1.1 200 Connection Established\r\n\r\n");
10885
10886 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
10887 // no constructors, but the C++ compiler on Windows warns about
10888 // unspecified data in compound literals. So, moved to using constructors,
10889 // and TestRound's created with the default constructor should not be used.
10890 struct TestRound {
10891 TestRound()
10892 : expected_rv(ERR_UNEXPECTED),
10893 extra_write(NULL),
10894 extra_read(NULL) {
10895 }
10896 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10897 int expected_rv_arg)
10898 : write(write_arg),
10899 read(read_arg),
10900 expected_rv(expected_rv_arg),
10901 extra_write(NULL),
10902 extra_read(NULL) {
10903 }
10904 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10905 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0110906 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1510907 : write(write_arg),
10908 read(read_arg),
10909 expected_rv(expected_rv_arg),
10910 extra_write(extra_write_arg),
10911 extra_read(extra_read_arg) {
10912 }
10913 MockWrite write;
10914 MockRead read;
10915 int expected_rv;
10916 const MockWrite* extra_write;
10917 const MockRead* extra_read;
10918 };
10919
10920 static const int kNoSSL = 500;
10921
10922 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5110923 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1510924 AuthTiming proxy_auth_timing;
10925 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5110926 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1510927 AuthTiming server_auth_timing;
10928 int server_auth_rv;
10929 int num_auth_rounds;
10930 int first_ssl_round;
10931 TestRound rounds[3];
10932 } test_configs[] = {
10933 // Non-authenticating HTTP server with a direct connection.
10934 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10935 { TestRound(kGet, kSuccess, OK)}},
10936 // Authenticating HTTP server with a direct connection.
10937 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10938 { TestRound(kGet, kServerChallenge, OK),
10939 TestRound(kGetAuth, kSuccess, OK)}},
10940 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10941 { TestRound(kGet, kServerChallenge, OK),
10942 TestRound(kGetAuth, kFailure, kAuthErr)}},
10943 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10944 { TestRound(kGet, kServerChallenge, OK),
10945 TestRound(kGetAuth, kSuccess, OK)}},
10946 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10947 { TestRound(kGet, kServerChallenge, OK),
10948 TestRound(kGetAuth, kFailure, kAuthErr)}},
10949 // Non-authenticating HTTP server through a non-authenticating proxy.
10950 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10951 { TestRound(kGetProxy, kSuccess, OK)}},
10952 // Authenticating HTTP server through a non-authenticating proxy.
10953 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10954 { TestRound(kGetProxy, kServerChallenge, OK),
10955 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10956 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10957 { TestRound(kGetProxy, kServerChallenge, OK),
10958 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10959 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10960 { TestRound(kGetProxy, kServerChallenge, OK),
10961 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10962 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10963 { TestRound(kGetProxy, kServerChallenge, OK),
10964 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10965 // Non-authenticating HTTP server through an authenticating proxy.
10966 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10967 { TestRound(kGetProxy, kProxyChallenge, OK),
10968 TestRound(kGetProxyAuth, kSuccess, OK)}},
10969 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10970 { TestRound(kGetProxy, kProxyChallenge, OK),
10971 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10972 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10973 { TestRound(kGetProxy, kProxyChallenge, OK),
10974 TestRound(kGetProxyAuth, kSuccess, OK)}},
10975 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10976 { TestRound(kGetProxy, kProxyChallenge, OK),
10977 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10978 // Authenticating HTTP server through an authenticating proxy.
10979 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10980 { TestRound(kGetProxy, kProxyChallenge, OK),
10981 TestRound(kGetProxyAuth, kServerChallenge, OK),
10982 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10983 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10984 { TestRound(kGetProxy, kProxyChallenge, OK),
10985 TestRound(kGetProxyAuth, kServerChallenge, OK),
10986 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10987 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10988 { TestRound(kGetProxy, kProxyChallenge, OK),
10989 TestRound(kGetProxyAuth, kServerChallenge, OK),
10990 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10991 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10992 { TestRound(kGetProxy, kProxyChallenge, OK),
10993 TestRound(kGetProxyAuth, kServerChallenge, OK),
10994 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10995 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10996 { TestRound(kGetProxy, kProxyChallenge, OK),
10997 TestRound(kGetProxyAuth, kServerChallenge, OK),
10998 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10999 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11000 { TestRound(kGetProxy, kProxyChallenge, OK),
11001 TestRound(kGetProxyAuth, kServerChallenge, OK),
11002 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11003 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11004 { TestRound(kGetProxy, kProxyChallenge, OK),
11005 TestRound(kGetProxyAuth, kServerChallenge, OK),
11006 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11007 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11008 { TestRound(kGetProxy, kProxyChallenge, OK),
11009 TestRound(kGetProxyAuth, kServerChallenge, OK),
11010 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11011 // Non-authenticating HTTPS server with a direct connection.
11012 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11013 { TestRound(kGet, kSuccess, OK)}},
11014 // Authenticating HTTPS server with a direct connection.
11015 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11016 { TestRound(kGet, kServerChallenge, OK),
11017 TestRound(kGetAuth, kSuccess, OK)}},
11018 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11019 { TestRound(kGet, kServerChallenge, OK),
11020 TestRound(kGetAuth, kFailure, kAuthErr)}},
11021 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11022 { TestRound(kGet, kServerChallenge, OK),
11023 TestRound(kGetAuth, kSuccess, OK)}},
11024 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11025 { TestRound(kGet, kServerChallenge, OK),
11026 TestRound(kGetAuth, kFailure, kAuthErr)}},
11027 // Non-authenticating HTTPS server with a non-authenticating proxy.
11028 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11029 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11030 // Authenticating HTTPS server through a non-authenticating proxy.
11031 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11032 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11033 TestRound(kGetAuth, kSuccess, OK)}},
11034 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11035 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11036 TestRound(kGetAuth, kFailure, kAuthErr)}},
11037 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11038 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11039 TestRound(kGetAuth, kSuccess, OK)}},
11040 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11041 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11042 TestRound(kGetAuth, kFailure, kAuthErr)}},
11043 // Non-Authenticating HTTPS server through an authenticating proxy.
11044 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11045 { TestRound(kConnect, kProxyChallenge, OK),
11046 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11047 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11048 { TestRound(kConnect, kProxyChallenge, OK),
11049 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11050 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11051 { TestRound(kConnect, kProxyChallenge, OK),
11052 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11053 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11054 { TestRound(kConnect, kProxyChallenge, OK),
11055 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11056 // Authenticating HTTPS server through an authenticating proxy.
11057 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11058 { TestRound(kConnect, kProxyChallenge, OK),
11059 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11060 &kGet, &kServerChallenge),
11061 TestRound(kGetAuth, kSuccess, OK)}},
11062 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11063 { TestRound(kConnect, kProxyChallenge, OK),
11064 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11065 &kGet, &kServerChallenge),
11066 TestRound(kGetAuth, kFailure, kAuthErr)}},
11067 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11068 { TestRound(kConnect, kProxyChallenge, OK),
11069 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11070 &kGet, &kServerChallenge),
11071 TestRound(kGetAuth, kSuccess, OK)}},
11072 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11073 { TestRound(kConnect, kProxyChallenge, OK),
11074 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11075 &kGet, &kServerChallenge),
11076 TestRound(kGetAuth, kFailure, kAuthErr)}},
11077 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11078 { TestRound(kConnect, kProxyChallenge, OK),
11079 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11080 &kGet, &kServerChallenge),
11081 TestRound(kGetAuth, kSuccess, OK)}},
11082 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11083 { TestRound(kConnect, kProxyChallenge, OK),
11084 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11085 &kGet, &kServerChallenge),
11086 TestRound(kGetAuth, kFailure, kAuthErr)}},
11087 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11088 { TestRound(kConnect, kProxyChallenge, OK),
11089 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11090 &kGet, &kServerChallenge),
11091 TestRound(kGetAuth, kSuccess, OK)}},
11092 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11093 { TestRound(kConnect, kProxyChallenge, OK),
11094 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11095 &kGet, &kServerChallenge),
11096 TestRound(kGetAuth, kFailure, kAuthErr)}},
11097 };
11098
viettrungluue4a8b882014-10-16 06:17:3811099 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0811100 HttpAuthHandlerMock::Factory* auth_factory(
11101 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711102 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1511103 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2611104
11105 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1511106 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0811107 for (int n = 0; n < 2; n++) {
11108 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11109 std::string auth_challenge = "Mock realm=proxy";
11110 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2411111 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11112 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0811113 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
11114 origin, BoundNetLog());
11115 auth_handler->SetGenerateExpectation(
11116 test_config.proxy_auth_timing == AUTH_ASYNC,
11117 test_config.proxy_auth_rv);
11118 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11119 }
[email protected]044de0642010-06-17 10:42:1511120 }
11121 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0011122 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1511123 std::string auth_challenge = "Mock realm=server";
11124 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2411125 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11126 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1511127 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
11128 origin, BoundNetLog());
11129 auth_handler->SetGenerateExpectation(
11130 test_config.server_auth_timing == AUTH_ASYNC,
11131 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0811132 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1511133 }
11134 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0311135 session_deps_.proxy_service =
11136 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1511137 } else {
rdsmith82957ad2015-09-16 19:42:0311138 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1511139 }
11140
11141 HttpRequestInfo request;
11142 request.method = "GET";
11143 request.url = GURL(test_config.server_url);
11144 request.load_flags = 0;
11145
mmenkee65e7af2015-10-13 17:16:4211146 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4111147 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1511148
rchcb68dc62015-05-21 04:45:3611149 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
11150
11151 std::vector<std::vector<MockRead>> mock_reads(1);
11152 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1511153 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11154 const TestRound& read_write_round = test_config.rounds[round];
11155
11156 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3611157 mock_reads.back().push_back(read_write_round.read);
11158 mock_writes.back().push_back(read_write_round.write);
11159
11160 // kProxyChallenge uses Proxy-Connection: close which means that the
11161 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5411162 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3611163 mock_reads.push_back(std::vector<MockRead>());
11164 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1511165 }
11166
rchcb68dc62015-05-21 04:45:3611167 if (read_write_round.extra_read) {
11168 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1511169 }
rchcb68dc62015-05-21 04:45:3611170 if (read_write_round.extra_write) {
11171 mock_writes.back().push_back(*read_write_round.extra_write);
11172 }
[email protected]044de0642010-06-17 10:42:1511173
11174 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1511175 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0711176 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1511177 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3611178 }
[email protected]044de0642010-06-17 10:42:1511179
rchcb68dc62015-05-21 04:45:3611180 ScopedVector<StaticSocketDataProvider> data_providers;
11181 for (size_t i = 0; i < mock_reads.size(); ++i) {
11182 data_providers.push_back(new StaticSocketDataProvider(
11183 vector_as_array(&mock_reads[i]), mock_reads[i].size(),
11184 vector_as_array(&mock_writes[i]), mock_writes[i].size()));
11185 session_deps_.socket_factory->AddSocketDataProvider(
11186 data_providers.back());
11187 }
11188
11189 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11190 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1511191 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4111192 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1511193 int rv;
11194 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4111195 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511196 } else {
[email protected]49639fa2011-12-20 23:22:4111197 rv = trans.RestartWithAuth(
11198 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1511199 }
11200 if (rv == ERR_IO_PENDING)
11201 rv = callback.WaitForResult();
11202
11203 // Compare results with expected data.
11204 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5011205 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5511206 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1511207 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
11208 continue;
11209 }
11210 if (round + 1 < test_config.num_auth_rounds) {
11211 EXPECT_FALSE(response->auth_challenge.get() == NULL);
11212 } else {
11213 EXPECT_TRUE(response->auth_challenge.get() == NULL);
11214 }
11215 }
[email protected]e5ae96a2010-04-14 20:12:4511216 }
11217}
11218
[email protected]23e482282013-06-14 16:08:0211219TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1411220 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1411221 HttpAuthHandlerMock::Factory* auth_factory(
11222 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711223 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0311224 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0711225 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
11226 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1411227
11228 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11229 auth_handler->set_connection_based(true);
11230 std::string auth_challenge = "Mock realm=server";
11231 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2411232 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11233 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1411234 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
11235 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811236 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1411237
[email protected]c871bce92010-07-15 21:51:1411238 int rv = OK;
11239 const HttpResponseInfo* response = NULL;
11240 HttpRequestInfo request;
11241 request.method = "GET";
11242 request.url = origin;
11243 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2711244
mmenkee65e7af2015-10-13 17:16:4211245 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1011246
11247 // Use a TCP Socket Pool with only one connection per group. This is used
11248 // to validate that the TCP socket is not released to the pool between
11249 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4211250 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2811251 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1011252 50, // Max sockets for pool
11253 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0711254 session_deps_.host_resolver.get(),
11255 session_deps_.socket_factory.get(),
11256 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4411257 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
11258 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0211259 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5111260 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1011261
[email protected]262eec82013-03-19 21:01:3611262 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011263 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111264 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1411265
11266 const MockWrite kGet(
11267 "GET / HTTP/1.1\r\n"
11268 "Host: www.example.com\r\n"
11269 "Connection: keep-alive\r\n\r\n");
11270 const MockWrite kGetAuth(
11271 "GET / HTTP/1.1\r\n"
11272 "Host: www.example.com\r\n"
11273 "Connection: keep-alive\r\n"
11274 "Authorization: auth_token\r\n\r\n");
11275
11276 const MockRead kServerChallenge(
11277 "HTTP/1.1 401 Unauthorized\r\n"
11278 "WWW-Authenticate: Mock realm=server\r\n"
11279 "Content-Type: text/html; charset=iso-8859-1\r\n"
11280 "Content-Length: 14\r\n\r\n"
11281 "Unauthorized\r\n");
11282 const MockRead kSuccess(
11283 "HTTP/1.1 200 OK\r\n"
11284 "Content-Type: text/html; charset=iso-8859-1\r\n"
11285 "Content-Length: 3\r\n\r\n"
11286 "Yes");
11287
11288 MockWrite writes[] = {
11289 // First round
11290 kGet,
11291 // Second round
11292 kGetAuth,
11293 // Third round
11294 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3011295 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1011296 kGetAuth,
11297 // Competing request
11298 kGet,
[email protected]c871bce92010-07-15 21:51:1411299 };
11300 MockRead reads[] = {
11301 // First round
11302 kServerChallenge,
11303 // Second round
11304 kServerChallenge,
11305 // Third round
[email protected]eca50e122010-09-11 14:03:3011306 kServerChallenge,
11307 // Fourth round
[email protected]c871bce92010-07-15 21:51:1411308 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1011309 // Competing response
11310 kSuccess,
[email protected]c871bce92010-07-15 21:51:1411311 };
11312 StaticSocketDataProvider data_provider(reads, arraysize(reads),
11313 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0711314 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1411315
thestig9d3bb0c2015-01-24 00:49:5111316 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1011317
11318 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1411319 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111320 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1411321 if (rv == ERR_IO_PENDING)
11322 rv = callback.WaitForResult();
11323 EXPECT_EQ(OK, rv);
11324 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011325 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1411326 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811327 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411328
[email protected]7ef4cbbb2011-02-06 11:19:1011329 // In between rounds, another request comes in for the same domain.
11330 // It should not be able to grab the TCP socket that trans has already
11331 // claimed.
11332 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5011333 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111334 TestCompletionCallback callback_compete;
11335 rv = trans_compete->Start(
11336 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1011337 EXPECT_EQ(ERR_IO_PENDING, rv);
11338 // callback_compete.WaitForResult at this point would stall forever,
11339 // since the HttpNetworkTransaction does not release the request back to
11340 // the pool until after authentication completes.
11341
11342 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1411343 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111344 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411345 if (rv == ERR_IO_PENDING)
11346 rv = callback.WaitForResult();
11347 EXPECT_EQ(OK, rv);
11348 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011349 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1411350 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811351 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411352
[email protected]7ef4cbbb2011-02-06 11:19:1011353 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1411354 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111355 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411356 if (rv == ERR_IO_PENDING)
11357 rv = callback.WaitForResult();
11358 EXPECT_EQ(OK, rv);
11359 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011360 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1411361 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811362 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3011363
[email protected]7ef4cbbb2011-02-06 11:19:1011364 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3011365 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111366 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3011367 if (rv == ERR_IO_PENDING)
11368 rv = callback.WaitForResult();
11369 EXPECT_EQ(OK, rv);
11370 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011371 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3011372 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811373 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011374
11375 // Read the body since the fourth round was successful. This will also
11376 // release the socket back to the pool.
11377 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5011378 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011379 if (rv == ERR_IO_PENDING)
11380 rv = callback.WaitForResult();
11381 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011382 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011383 EXPECT_EQ(0, rv);
11384 // There are still 0 idle sockets, since the trans_compete transaction
11385 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2811386 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011387
11388 // The competing request can now finish. Wait for the headers and then
11389 // read the body.
11390 rv = callback_compete.WaitForResult();
11391 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5011392 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011393 if (rv == ERR_IO_PENDING)
11394 rv = callback.WaitForResult();
11395 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011396 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011397 EXPECT_EQ(0, rv);
11398
11399 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2811400 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411401}
11402
[email protected]65041fa2010-05-21 06:56:5311403// This tests the case that a request is issued via http instead of spdy after
11404// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0211405TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bnc55ff9da2015-08-19 18:42:3511406 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311407 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1611408 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2311409 session_deps_.next_protos = next_protos;
11410
[email protected]65041fa2010-05-21 06:56:5311411 HttpRequestInfo request;
11412 request.method = "GET";
bncce36dca22015-04-21 22:11:2311413 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5311414 request.load_flags = 0;
11415
11416 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2311417 MockWrite(
11418 "GET / HTTP/1.1\r\n"
11419 "Host: www.example.org\r\n"
11420 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5311421 };
11422
[email protected]8a0fc822013-06-27 20:52:4311423 std::string alternate_protocol_http_header =
11424 GetAlternateProtocolHttpHeader();
11425
[email protected]65041fa2010-05-21 06:56:5311426 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211427 MockRead("HTTP/1.1 200 OK\r\n"),
11428 MockRead(alternate_protocol_http_header.c_str()),
11429 MockRead("\r\n"),
11430 MockRead("hello world"),
11431 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5311432 };
11433
[email protected]8ddf8322012-02-23 18:08:0611434 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4811435 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5311436
[email protected]bb88e1d32013-05-03 23:11:0711437 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5311438
11439 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11440 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711441 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5311442
[email protected]49639fa2011-12-20 23:22:4111443 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5311444
mmenkee65e7af2015-10-13 17:16:4211445 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611446 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011447 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5311448
[email protected]49639fa2011-12-20 23:22:4111449 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5311450
11451 EXPECT_EQ(ERR_IO_PENDING, rv);
11452 EXPECT_EQ(OK, callback.WaitForResult());
11453
11454 const HttpResponseInfo* response = trans->GetResponseInfo();
11455 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011456 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5311457 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11458
11459 std::string response_data;
11460 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11461 EXPECT_EQ("hello world", response_data);
11462
11463 EXPECT_FALSE(response->was_fetched_via_spdy);
11464 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5311465}
[email protected]26ef6582010-06-24 02:30:4711466
bnc55ff9da2015-08-19 18:42:3511467// Simulate the SSL handshake completing with an NPN negotiation followed by an
11468// immediate server closing of the socket.
11469// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0211470TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bnc55ff9da2015-08-19 18:42:3511471 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311472 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4711473
11474 HttpRequestInfo request;
11475 request.method = "GET";
bncce36dca22015-04-21 22:11:2311476 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4711477 request.load_flags = 0;
11478
[email protected]8ddf8322012-02-23 18:08:0611479 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211480 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711481 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4711482
[email protected]cdf8f7e72013-05-23 10:56:4611483 scoped_ptr<SpdyFrame> req(
11484 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1311485 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4711486
11487 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611488 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4711489 };
11490
rch8e6c6c42015-05-01 14:05:1311491 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11492 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711493 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4711494
[email protected]49639fa2011-12-20 23:22:4111495 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4711496
mmenkee65e7af2015-10-13 17:16:4211497 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611498 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011499 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4711500
[email protected]49639fa2011-12-20 23:22:4111501 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4711502 EXPECT_EQ(ERR_IO_PENDING, rv);
11503 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4711504}
[email protected]65d34382010-07-01 18:12:2611505
[email protected]795cbf82013-07-22 09:37:2711506// A subclass of HttpAuthHandlerMock that records the request URL when
11507// it gets it. This is needed since the auth handler may get destroyed
11508// before we get a chance to query it.
11509class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
11510 public:
11511 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
11512
dchengb03027d2014-10-21 12:00:2011513 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2711514
11515 protected:
dchengb03027d2014-10-21 12:00:2011516 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
11517 const HttpRequestInfo* request,
11518 const CompletionCallback& callback,
11519 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2711520 *url_ = request->url;
11521 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
11522 credentials, request, callback, auth_token);
11523 }
11524
11525 private:
11526 GURL* url_;
11527};
11528
bnc55ff9da2015-08-19 18:42:3511529// This test ensures that the URL passed into the proxy is upgraded to https
11530// when doing an Alternate Protocol upgrade.
[email protected]23e482282013-06-14 16:08:0211531TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
bnc55ff9da2015-08-19 18:42:3511532 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311533 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3011534
rdsmith82957ad2015-09-16 19:42:0311535 session_deps_.proxy_service =
11536 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111537 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711538 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2711539 GURL request_url;
11540 {
11541 HttpAuthHandlerMock::Factory* auth_factory =
11542 new HttpAuthHandlerMock::Factory();
11543 UrlRecordingHttpAuthHandlerMock* auth_handler =
11544 new UrlRecordingHttpAuthHandlerMock(&request_url);
11545 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11546 auth_factory->set_do_init_from_challenge(true);
11547 session_deps_.http_auth_handler_factory.reset(auth_factory);
11548 }
[email protected]f45c1ee2010-08-03 00:54:3011549
11550 HttpRequestInfo request;
11551 request.method = "GET";
bncce36dca22015-04-21 22:11:2311552 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3011553 request.load_flags = 0;
11554
11555 // First round goes unauthenticated through the proxy.
11556 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2311557 MockWrite(
11558 "GET http://www.example.org/ HTTP/1.1\r\n"
11559 "Host: www.example.org\r\n"
11560 "Proxy-Connection: keep-alive\r\n"
11561 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011562 };
11563 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0611564 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3811565 MockRead("HTTP/1.1 200 OK\r\n"),
11566 MockRead("Alternate-Protocol: 443:"),
11567 MockRead(GetAlternateProtocolFromParam()),
11568 MockRead("\r\n"),
11569 MockRead("Proxy-Connection: close\r\n"),
11570 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011571 };
11572 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
11573 data_writes_1, arraysize(data_writes_1));
11574
bncce36dca22015-04-21 22:11:2311575 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3011576 // Alternate-Protocol announcement in the first round. It fails due
11577 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2311578 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5911579 // Proxy-Authorization headers. There is then a SPDY request round.
11580 //
[email protected]fe3b7dc2012-02-03 19:52:0911581 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
11582 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
11583 // does a Disconnect and Connect on the same socket, rather than trying
11584 // to obtain a new one.
11585 //
[email protected]394816e92010-08-03 07:38:5911586 // NOTE: Originally, the proxy response to the second CONNECT request
11587 // simply returned another 407 so the unit test could skip the SSL connection
11588 // establishment and SPDY framing issues. Alas, the
11589 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3011590 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5911591
[email protected]cdf8f7e72013-05-23 10:56:4611592 scoped_ptr<SpdyFrame> req(
11593 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0211594 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11595 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3011596
[email protected]394816e92010-08-03 07:38:5911597 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2311598 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311599 MockWrite(ASYNC, 0,
11600 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11601 "Host: www.example.org\r\n"
11602 "Proxy-Connection: keep-alive\r\n"
11603 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911604
bncce36dca22015-04-21 22:11:2311605 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311606 MockWrite(ASYNC, 2,
11607 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11608 "Host: www.example.org\r\n"
11609 "Proxy-Connection: keep-alive\r\n"
11610 "Proxy-Authorization: auth_token\r\n"
11611 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011612
bncce36dca22015-04-21 22:11:2311613 // SPDY request
rch8e6c6c42015-05-01 14:05:1311614 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3011615 };
[email protected]394816e92010-08-03 07:38:5911616 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1311617 // First connection attempt fails
mmenkee71e15332015-10-07 16:39:5411618 MockRead(ASYNC, 1,
11619 "HTTP/1.1 407 Unauthorized\r\n"
11620 "Proxy-Authenticate: Mock\r\n"
11621 "Content-Length: 0\r\n"
11622 "Proxy-Connection: keep-alive\r\n"
11623 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911624
rch8e6c6c42015-05-01 14:05:1311625 // Second connection attempt passes
mmenkee71e15332015-10-07 16:39:5411626 MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:5911627
rch8e6c6c42015-05-01 14:05:1311628 // SPDY response
mmenkee71e15332015-10-07 16:39:5411629 CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1311630 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5911631 };
rch8e6c6c42015-05-01 14:05:1311632 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
11633 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3011634
[email protected]8ddf8322012-02-23 18:08:0611635 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211636 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2311637 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
11638 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3011639
[email protected]d973e99a2012-02-17 21:02:3611640 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511641 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11642 NULL, 0, NULL, 0);
11643 hanging_non_alternate_protocol_socket.set_connect_data(
11644 never_finishing_connect);
11645
[email protected]bb88e1d32013-05-03 23:11:0711646 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
11647 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
11648 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11649 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511650 &hanging_non_alternate_protocol_socket);
mmenkee65e7af2015-10-13 17:16:4211651 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3011652
11653 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4111654 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3611655 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5011656 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111657 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011658 EXPECT_EQ(ERR_IO_PENDING, rv);
11659 EXPECT_EQ(OK, callback_1.WaitForResult());
11660
11661 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4111662 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3611663 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5011664 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111665 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011666 EXPECT_EQ(ERR_IO_PENDING, rv);
11667 EXPECT_EQ(OK, callback_2.WaitForResult());
11668 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011669 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3011670 ASSERT_FALSE(response->auth_challenge.get() == NULL);
11671
11672 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4111673 TestCompletionCallback callback_3;
11674 rv = trans_2->RestartWithAuth(
11675 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3011676 EXPECT_EQ(ERR_IO_PENDING, rv);
11677 EXPECT_EQ(OK, callback_3.WaitForResult());
11678
11679 // After all that work, these two lines (or actually, just the scheme) are
11680 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3011681 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2311682 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3011683
[email protected]029c83b62013-01-24 05:28:2011684 LoadTimingInfo load_timing_info;
11685 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
11686 TestLoadTimingNotReusedWithPac(load_timing_info,
11687 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3811688}
11689
11690// Test that if we cancel the transaction as the connection is completing, that
11691// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0211692TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3811693 // Setup everything about the connection to complete synchronously, so that
11694 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
11695 // for is the callback from the HttpStreamRequest.
11696 // Then cancel the transaction.
11697 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3611698 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3811699 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611700 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
11701 MockRead(SYNCHRONOUS, "hello world"),
11702 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3811703 };
11704
[email protected]8e6441ca2010-08-19 05:56:3811705 HttpRequestInfo request;
11706 request.method = "GET";
bncce36dca22015-04-21 22:11:2311707 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3811708 request.load_flags = 0;
11709
[email protected]bb88e1d32013-05-03 23:11:0711710 session_deps_.host_resolver->set_synchronous_mode(true);
mmenkee65e7af2015-10-13 17:16:4211711 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2711712 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111713 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2711714
[email protected]8e6441ca2010-08-19 05:56:3811715 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11716 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711717 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3811718
[email protected]49639fa2011-12-20 23:22:4111719 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3811720
vishal.b62985ca92015-04-17 08:45:5111721 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4111722 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3811723 EXPECT_EQ(ERR_IO_PENDING, rv);
11724 trans.reset(); // Cancel the transaction here.
11725
[email protected]2da659e2013-05-23 20:51:3411726 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3011727}
11728
[email protected]ecab6e052014-05-16 14:58:1211729// Test that if a transaction is cancelled after receiving the headers, the
11730// stream is drained properly and added back to the socket pool. The main
11731// purpose of this test is to make sure that an HttpStreamParser can be read
11732// from after the HttpNetworkTransaction and the objects it owns have been
11733// deleted.
11734// See http://crbug.com/368418
11735TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
11736 MockRead data_reads[] = {
11737 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
11738 MockRead(ASYNC, "Content-Length: 2\r\n"),
11739 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
11740 MockRead(ASYNC, "1"),
11741 // 2 async reads are necessary to trigger a ReadResponseBody call after the
11742 // HttpNetworkTransaction has been deleted.
11743 MockRead(ASYNC, "2"),
11744 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
11745 };
11746 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11747 session_deps_.socket_factory->AddSocketDataProvider(&data);
11748
mmenkee65e7af2015-10-13 17:16:4211749 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1211750
11751 {
11752 HttpRequestInfo request;
11753 request.method = "GET";
bncce36dca22015-04-21 22:11:2311754 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1211755 request.load_flags = 0;
11756
dcheng48459ac22014-08-26 00:46:4111757 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1211758 TestCompletionCallback callback;
11759
11760 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
11761 EXPECT_EQ(ERR_IO_PENDING, rv);
11762 callback.WaitForResult();
11763
11764 const HttpResponseInfo* response = trans.GetResponseInfo();
11765 ASSERT_TRUE(response != NULL);
11766 EXPECT_TRUE(response->headers.get() != NULL);
11767 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11768
11769 // The transaction and HttpRequestInfo are deleted.
11770 }
11771
11772 // Let the HttpResponseBodyDrainer drain the socket.
11773 base::MessageLoop::current()->RunUntilIdle();
11774
11775 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4111776 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1211777}
11778
[email protected]76a505b2010-08-25 06:23:0011779// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211780TEST_P(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0311781 session_deps_.proxy_service =
11782 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111783 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711784 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:4211785 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011786
[email protected]76a505b2010-08-25 06:23:0011787 HttpRequestInfo request;
11788 request.method = "GET";
bncce36dca22015-04-21 22:11:2311789 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011790
11791 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311792 MockWrite(
11793 "GET http://www.example.org/ HTTP/1.1\r\n"
11794 "Host: www.example.org\r\n"
11795 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011796 };
11797
11798 MockRead data_reads1[] = {
11799 MockRead("HTTP/1.1 200 OK\r\n"),
11800 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11801 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611802 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011803 };
11804
11805 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11806 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711807 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0011808
[email protected]49639fa2011-12-20 23:22:4111809 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011810
[email protected]262eec82013-03-19 21:01:3611811 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011812 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2711813 BeforeProxyHeadersSentHandler proxy_headers_handler;
11814 trans->SetBeforeProxyHeadersSentCallback(
11815 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
11816 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5011817
[email protected]49639fa2011-12-20 23:22:4111818 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011819 EXPECT_EQ(ERR_IO_PENDING, rv);
11820
11821 rv = callback1.WaitForResult();
11822 EXPECT_EQ(OK, rv);
11823
11824 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011825 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011826
11827 EXPECT_TRUE(response->headers->IsKeepAlive());
11828 EXPECT_EQ(200, response->headers->response_code());
11829 EXPECT_EQ(100, response->headers->GetContentLength());
11830 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511831 EXPECT_TRUE(
11832 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2711833 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
11834 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0011835 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2011836
11837 LoadTimingInfo load_timing_info;
11838 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11839 TestLoadTimingNotReusedWithPac(load_timing_info,
11840 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0011841}
11842
11843// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211844TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0311845 session_deps_.proxy_service =
11846 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111847 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711848 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:4211849 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011850
[email protected]76a505b2010-08-25 06:23:0011851 HttpRequestInfo request;
11852 request.method = "GET";
bncce36dca22015-04-21 22:11:2311853 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011854
11855 // Since we have proxy, should try to establish tunnel.
11856 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311857 MockWrite(
11858 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11859 "Host: www.example.org\r\n"
11860 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011861
bncce36dca22015-04-21 22:11:2311862 MockWrite(
11863 "GET / HTTP/1.1\r\n"
11864 "Host: www.example.org\r\n"
11865 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011866 };
11867
11868 MockRead data_reads1[] = {
11869 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
11870
11871 MockRead("HTTP/1.1 200 OK\r\n"),
11872 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11873 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611874 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011875 };
11876
11877 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11878 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711879 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611880 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711881 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011882
[email protected]49639fa2011-12-20 23:22:4111883 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011884
[email protected]262eec82013-03-19 21:01:3611885 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011886 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011887
[email protected]49639fa2011-12-20 23:22:4111888 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011889 EXPECT_EQ(ERR_IO_PENDING, rv);
11890
11891 rv = callback1.WaitForResult();
11892 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4611893 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011894 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011895 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011896 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011897 NetLog::PHASE_NONE);
11898 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011899 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011900 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11901 NetLog::PHASE_NONE);
11902
11903 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011904 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011905
11906 EXPECT_TRUE(response->headers->IsKeepAlive());
11907 EXPECT_EQ(200, response->headers->response_code());
11908 EXPECT_EQ(100, response->headers->GetContentLength());
11909 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
11910 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511911 EXPECT_TRUE(
11912 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2011913
11914 LoadTimingInfo load_timing_info;
11915 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11916 TestLoadTimingNotReusedWithPac(load_timing_info,
11917 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0011918}
11919
11920// Test a basic HTTPS GET request through a proxy, but the server hangs up
11921// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0211922TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0311923 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111924 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711925 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:4211926 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011927
[email protected]76a505b2010-08-25 06:23:0011928 HttpRequestInfo request;
11929 request.method = "GET";
bncce36dca22015-04-21 22:11:2311930 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011931
11932 // Since we have proxy, should try to establish tunnel.
11933 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311934 MockWrite(
11935 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11936 "Host: www.example.org\r\n"
11937 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011938
bncce36dca22015-04-21 22:11:2311939 MockWrite(
11940 "GET / HTTP/1.1\r\n"
11941 "Host: www.example.org\r\n"
11942 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011943 };
11944
11945 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0611946 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0011947 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611948 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0011949 };
11950
11951 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11952 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711953 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611954 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711955 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011956
[email protected]49639fa2011-12-20 23:22:4111957 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011958
[email protected]262eec82013-03-19 21:01:3611959 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011960 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011961
[email protected]49639fa2011-12-20 23:22:4111962 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011963 EXPECT_EQ(ERR_IO_PENDING, rv);
11964
11965 rv = callback1.WaitForResult();
11966 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4611967 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011968 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011969 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011970 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011971 NetLog::PHASE_NONE);
11972 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011973 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011974 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11975 NetLog::PHASE_NONE);
11976}
11977
[email protected]749eefa82010-09-13 22:14:0311978// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0211979TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4611980 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2311981 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1311982 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0311983
[email protected]23e482282013-06-14 16:08:0211984 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11985 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0311986 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311987 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0311988 };
11989
rch8e6c6c42015-05-01 14:05:1311990 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11991 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711992 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0311993
[email protected]8ddf8322012-02-23 18:08:0611994 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211995 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711996 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0311997
mmenkee65e7af2015-10-13 17:16:4211998 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0311999
12000 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2312001 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012002 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5312003 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2712004 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4212005 CreateInsecureSpdySession(session.get(), key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312006
12007 HttpRequestInfo request;
12008 request.method = "GET";
bncce36dca22015-04-21 22:11:2312009 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0312010 request.load_flags = 0;
12011
12012 // This is the important line that marks this as a preconnect.
12013 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
12014
[email protected]262eec82013-03-19 21:01:3612015 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012016 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0312017
[email protected]41d64e82013-07-03 22:44:2612018 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4112019 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312020 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112021 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0312022}
12023
[email protected]73b8dd222010-11-11 19:55:2412024// Given a net error, cause that error to be returned from the first Write()
12025// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0212026void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0712027 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2912028 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712029 request_info.url = GURL("https://www.example.com/");
12030 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912031 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712032
[email protected]8ddf8322012-02-23 18:08:0612033 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2912034 MockWrite data_writes[] = {
12035 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2412036 };
ttuttle859dc7a2015-04-23 19:42:2912037 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712038 session_deps_.socket_factory->AddSocketDataProvider(&data);
12039 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2412040
mmenkee65e7af2015-10-13 17:16:4212041 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3612042 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012043 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2412044
[email protected]49639fa2011-12-20 23:22:4112045 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912046 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12047 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2412048 rv = callback.WaitForResult();
12049 ASSERT_EQ(error, rv);
12050}
12051
[email protected]23e482282013-06-14 16:08:0212052TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2412053 // Just check a grab bag of cert errors.
12054 static const int kErrors[] = {
12055 ERR_CERT_COMMON_NAME_INVALID,
12056 ERR_CERT_AUTHORITY_INVALID,
12057 ERR_CERT_DATE_INVALID,
12058 };
12059 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0612060 CheckErrorIsPassedBack(kErrors[i], ASYNC);
12061 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2412062 }
12063}
12064
[email protected]bd0b6772011-01-11 19:59:3012065// Ensure that a client certificate is removed from the SSL client auth
12066// cache when:
12067// 1) No proxy is involved.
12068// 2) TLS False Start is disabled.
12069// 3) The initial TLS handshake requests a client certificate.
12070// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212071TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312072 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912073 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712074 request_info.url = GURL("https://www.example.com/");
12075 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912076 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712077
[email protected]bd0b6772011-01-11 19:59:3012078 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112079 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012080
12081 // [ssl_]data1 contains the data for the first SSL handshake. When a
12082 // CertificateRequest is received for the first time, the handshake will
12083 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2912084 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012085 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712086 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912087 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712088 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012089
12090 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
12091 // False Start is not being used, the result of the SSL handshake will be
12092 // returned as part of the SSLClientSocket::Connect() call. This test
12093 // matches the result of a server sending a handshake_failure alert,
12094 // rather than a Finished message, because it requires a client
12095 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2912096 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012097 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712098 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912099 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712100 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012101
12102 // [ssl_]data3 contains the data for the third SSL handshake. When a
12103 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212104 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
12105 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3012106 // of the HttpNetworkTransaction. Because this test failure is due to
12107 // requiring a client certificate, this fallback handshake should also
12108 // fail.
ttuttle859dc7a2015-04-23 19:42:2912109 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012110 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712111 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912112 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712113 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012114
[email protected]80c75f682012-05-26 16:22:1712115 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
12116 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212117 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
12118 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1712119 // of the HttpNetworkTransaction. Because this test failure is due to
12120 // requiring a client certificate, this fallback handshake should also
12121 // fail.
ttuttle859dc7a2015-04-23 19:42:2912122 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1712123 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712124 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912125 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712126 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712127
mmenkee65e7af2015-10-13 17:16:4212128 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3612129 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012130 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012131
[email protected]bd0b6772011-01-11 19:59:3012132 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4112133 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912134 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12135 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012136
12137 // Complete the SSL handshake, which should abort due to requiring a
12138 // client certificate.
12139 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912140 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012141
12142 // Indicate that no certificate should be supplied. From the perspective
12143 // of SSLClientCertCache, NULL is just as meaningful as a real
12144 // certificate, so this is the same as supply a
12145 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4112146 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912147 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012148
12149 // Ensure the certificate was added to the client auth cache before
12150 // allowing the connection to continue restarting.
12151 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4112152 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
12153 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3012154 ASSERT_EQ(NULL, client_cert.get());
12155
12156 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712157 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12158 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012159 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912160 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012161
12162 // Ensure that the client certificate is removed from the cache on a
12163 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112164 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
12165 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3012166}
12167
12168// Ensure that a client certificate is removed from the SSL client auth
12169// cache when:
12170// 1) No proxy is involved.
12171// 2) TLS False Start is enabled.
12172// 3) The initial TLS handshake requests a client certificate.
12173// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212174TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312175 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912176 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712177 request_info.url = GURL("https://www.example.com/");
12178 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912179 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712180
[email protected]bd0b6772011-01-11 19:59:3012181 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112182 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012183
12184 // When TLS False Start is used, SSLClientSocket::Connect() calls will
12185 // return successfully after reading up to the peer's Certificate message.
12186 // This is to allow the caller to call SSLClientSocket::Write(), which can
12187 // enqueue application data to be sent in the same packet as the
12188 // ChangeCipherSpec and Finished messages.
12189 // The actual handshake will be finished when SSLClientSocket::Read() is
12190 // called, which expects to process the peer's ChangeCipherSpec and
12191 // Finished messages. If there was an error negotiating with the peer,
12192 // such as due to the peer requiring a client certificate when none was
12193 // supplied, the alert sent by the peer won't be processed until Read() is
12194 // called.
12195
12196 // Like the non-False Start case, when a client certificate is requested by
12197 // the peer, the handshake is aborted during the Connect() call.
12198 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2912199 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012200 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712201 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912202 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712203 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012204
12205 // When a client certificate is supplied, Connect() will not be aborted
12206 // when the peer requests the certificate. Instead, the handshake will
12207 // artificially succeed, allowing the caller to write the HTTP request to
12208 // the socket. The handshake messages are not processed until Read() is
12209 // called, which then detects that the handshake was aborted, due to the
12210 // peer sending a handshake_failure because it requires a client
12211 // certificate.
ttuttle859dc7a2015-04-23 19:42:2912212 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012213 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712214 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912215 MockRead data2_reads[] = {
12216 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3012217 };
ttuttle859dc7a2015-04-23 19:42:2912218 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712219 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012220
12221 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1712222 // the data for the SSL handshake once the TLSv1.1 connection falls back to
12223 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912224 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012225 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712226 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912227 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712228 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012229
[email protected]80c75f682012-05-26 16:22:1712230 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
12231 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912232 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1712233 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712234 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912235 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712236 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712237
[email protected]7799de12013-05-30 05:52:5112238 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2912239 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5112240 ssl_data5.cert_request_info = cert_request.get();
12241 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2912242 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5112243 session_deps_.socket_factory->AddSocketDataProvider(&data5);
12244
mmenkee65e7af2015-10-13 17:16:4212245 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3612246 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012248
[email protected]bd0b6772011-01-11 19:59:3012249 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4112250 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912251 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12252 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012253
12254 // Complete the SSL handshake, which should abort due to requiring a
12255 // client certificate.
12256 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912257 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012258
12259 // Indicate that no certificate should be supplied. From the perspective
12260 // of SSLClientCertCache, NULL is just as meaningful as a real
12261 // certificate, so this is the same as supply a
12262 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4112263 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912264 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012265
12266 // Ensure the certificate was added to the client auth cache before
12267 // allowing the connection to continue restarting.
12268 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4112269 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
12270 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3012271 ASSERT_EQ(NULL, client_cert.get());
12272
[email protected]bd0b6772011-01-11 19:59:3012273 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712274 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12275 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012276 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912277 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012278
12279 // Ensure that the client certificate is removed from the cache on a
12280 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112281 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
12282 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3012283}
12284
[email protected]8c405132011-01-11 22:03:1812285// Ensure that a client certificate is removed from the SSL client auth
12286// cache when:
12287// 1) An HTTPS proxy is involved.
12288// 3) The HTTPS proxy requests a client certificate.
12289// 4) The client supplies an invalid/unacceptable certificate for the
12290// proxy.
12291// The test is repeated twice, first for connecting to an HTTPS endpoint,
12292// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0212293TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0312294 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5112295 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712296 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1812297
12298 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112299 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1812300
12301 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
12302 // [ssl_]data[1-3]. Rather than represending the endpoint
12303 // (www.example.com:443), they represent failures with the HTTPS proxy
12304 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2912305 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1812306 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712307 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912308 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712309 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1812310
ttuttle859dc7a2015-04-23 19:42:2912311 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812312 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712313 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912314 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712315 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1812316
[email protected]80c75f682012-05-26 16:22:1712317 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
12318#if 0
ttuttle859dc7a2015-04-23 19:42:2912319 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812320 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712321 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912322 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712323 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1712324#endif
[email protected]8c405132011-01-11 22:03:1812325
ttuttle859dc7a2015-04-23 19:42:2912326 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1812327 requests[0].url = GURL("https://www.example.com/");
12328 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912329 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812330
12331 requests[1].url = GURL("http://www.example.com/");
12332 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912333 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812334
12335 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0712336 session_deps_.socket_factory->ResetNextMockIndexes();
mmenkee65e7af2015-10-13 17:16:4212337 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1812338 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012339 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1812340
12341 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4112342 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912343 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
12344 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1812345
12346 // Complete the SSL handshake, which should abort due to requiring a
12347 // client certificate.
12348 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912349 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1812350
12351 // Indicate that no certificate should be supplied. From the perspective
12352 // of SSLClientCertCache, NULL is just as meaningful as a real
12353 // certificate, so this is the same as supply a
12354 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4112355 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912356 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1812357
12358 // Ensure the certificate was added to the client auth cache before
12359 // allowing the connection to continue restarting.
12360 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4112361 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
12362 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1812363 ASSERT_EQ(NULL, client_cert.get());
12364 // Ensure the certificate was NOT cached for the endpoint. This only
12365 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4112366 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
12367 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1812368
12369 // Restart the handshake. This will consume ssl_data2, which fails, and
12370 // then consume ssl_data3, which should also fail. The result code is
12371 // checked against what ssl_data3 should return.
12372 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912373 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1812374
12375 // Now that the new handshake has failed, ensure that the client
12376 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4112377 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
12378 HostPortPair("proxy", 70), &client_cert));
12379 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
12380 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1812381 }
12382}
12383
mmenke5c642132015-06-02 16:05:1312384TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bnc55ff9da2015-08-19 18:42:3512385 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2312386 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4612387
12388 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712389 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenkee65e7af2015-10-13 17:16:4212390 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612391 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12392 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612393
[email protected]8ddf8322012-02-23 18:08:0612394 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212395 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712396 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612397
[email protected]cdf8f7e72013-05-23 10:56:4612398 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2312399 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4612400 scoped_ptr<SpdyFrame> host2_req(
12401 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612402 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312403 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612404 };
[email protected]23e482282013-06-14 16:08:0212405 scoped_ptr<SpdyFrame> host1_resp(
12406 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12407 scoped_ptr<SpdyFrame> host1_resp_body(
12408 spdy_util_.ConstructSpdyBodyFrame(1, true));
12409 scoped_ptr<SpdyFrame> host2_resp(
12410 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12411 scoped_ptr<SpdyFrame> host2_resp_body(
12412 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612413 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312414 CreateMockRead(*host1_resp, 1),
12415 CreateMockRead(*host1_resp_body, 2),
12416 CreateMockRead(*host2_resp, 4),
12417 CreateMockRead(*host2_resp_body, 5),
12418 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612419 };
12420
[email protected]d2b5f092012-06-08 23:55:0212421 IPAddressNumber ip;
12422 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12423 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12424 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312425 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12426 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712427 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612428
[email protected]aa22b242011-11-16 18:58:2912429 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612430 HttpRequestInfo request1;
12431 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312432 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612433 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012434 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612435
[email protected]49639fa2011-12-20 23:22:4112436 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612437 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112438 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612439
12440 const HttpResponseInfo* response = trans1.GetResponseInfo();
12441 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012442 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612443 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12444
12445 std::string response_data;
12446 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12447 EXPECT_EQ("hello!", response_data);
12448
12449 // Preload www.gmail.com into HostCache.
12450 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1012451 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4612452 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012453 rv = session_deps_.host_resolver->Resolve(resolve_info,
12454 DEFAULT_PRIORITY,
12455 &ignored,
12456 callback.callback(),
12457 NULL,
12458 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712459 EXPECT_EQ(ERR_IO_PENDING, rv);
12460 rv = callback.WaitForResult();
12461 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612462
12463 HttpRequestInfo request2;
12464 request2.method = "GET";
12465 request2.url = GURL("https://www.gmail.com/");
12466 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012467 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612468
[email protected]49639fa2011-12-20 23:22:4112469 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612470 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112471 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612472
12473 response = trans2.GetResponseInfo();
12474 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012475 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612476 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12477 EXPECT_TRUE(response->was_fetched_via_spdy);
12478 EXPECT_TRUE(response->was_npn_negotiated);
12479 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12480 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612481}
12482
[email protected]23e482282013-06-14 16:08:0212483TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bnc55ff9da2015-08-19 18:42:3512484 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2312485 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0212486
12487 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712488 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenkee65e7af2015-10-13 17:16:4212489 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0212490 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12491 pool_peer.DisableDomainAuthenticationVerification();
12492
12493 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212494 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712495 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0212496
[email protected]cdf8f7e72013-05-23 10:56:4612497 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2312498 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4612499 scoped_ptr<SpdyFrame> host2_req(
12500 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0212501 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312502 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0212503 };
[email protected]23e482282013-06-14 16:08:0212504 scoped_ptr<SpdyFrame> host1_resp(
12505 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12506 scoped_ptr<SpdyFrame> host1_resp_body(
12507 spdy_util_.ConstructSpdyBodyFrame(1, true));
12508 scoped_ptr<SpdyFrame> host2_resp(
12509 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12510 scoped_ptr<SpdyFrame> host2_resp_body(
12511 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0212512 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312513 CreateMockRead(*host1_resp, 1),
12514 CreateMockRead(*host1_resp_body, 2),
12515 CreateMockRead(*host2_resp, 4),
12516 CreateMockRead(*host2_resp_body, 5),
12517 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0212518 };
12519
12520 IPAddressNumber ip;
12521 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12522 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12523 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312524 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12525 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712526 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0212527
12528 TestCompletionCallback callback;
12529 HttpRequestInfo request1;
12530 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312531 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0212532 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012533 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212534
12535 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
12536 EXPECT_EQ(ERR_IO_PENDING, rv);
12537 EXPECT_EQ(OK, callback.WaitForResult());
12538
12539 const HttpResponseInfo* response = trans1.GetResponseInfo();
12540 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012541 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0212542 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12543
12544 std::string response_data;
12545 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12546 EXPECT_EQ("hello!", response_data);
12547
12548 HttpRequestInfo request2;
12549 request2.method = "GET";
12550 request2.url = GURL("https://www.gmail.com/");
12551 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012552 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212553
12554 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
12555 EXPECT_EQ(ERR_IO_PENDING, rv);
12556 EXPECT_EQ(OK, callback.WaitForResult());
12557
12558 response = trans2.GetResponseInfo();
12559 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012560 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0212561 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12562 EXPECT_TRUE(response->was_fetched_via_spdy);
12563 EXPECT_TRUE(response->was_npn_negotiated);
12564 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12565 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0212566}
12567
ttuttle859dc7a2015-04-23 19:42:2912568class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4612569 public:
12570 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
12571 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2012572 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4612573
12574 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
12575
12576 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2012577 int Resolve(const RequestInfo& info,
12578 RequestPriority priority,
12579 AddressList* addresses,
12580 const CompletionCallback& callback,
12581 RequestHandle* out_req,
12582 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012583 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1012584 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4012585 }
12586
dchengb03027d2014-10-21 12:00:2012587 int ResolveFromCache(const RequestInfo& info,
12588 AddressList* addresses,
12589 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012590 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
12591 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0912592 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4612593 return rv;
12594 }
12595
dchengb03027d2014-10-21 12:00:2012596 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4612597 host_resolver_.CancelRequest(req);
12598 }
12599
[email protected]46da33be2011-07-19 21:58:0412600 MockCachingHostResolver* GetMockHostResolver() {
12601 return &host_resolver_;
12602 }
12603
[email protected]e3ceb682011-06-28 23:55:4612604 private:
12605 MockCachingHostResolver host_resolver_;
12606 const HostPortPair host_port_;
12607};
12608
mmenke5c642132015-06-02 16:05:1312609TEST_P(HttpNetworkTransactionTest,
12610 UseIPConnectionPoolingWithHostCacheExpiration) {
bnc55ff9da2015-08-19 18:42:3512611 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2312612 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4612613
12614 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4612615 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3412616 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0712617 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4612618 params.host_resolver = &host_resolver;
mmenkee65e7af2015-10-13 17:16:4212619 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612620 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12621 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612622
[email protected]8ddf8322012-02-23 18:08:0612623 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212624 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712625 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612626
[email protected]cdf8f7e72013-05-23 10:56:4612627 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2312628 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4612629 scoped_ptr<SpdyFrame> host2_req(
12630 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612631 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312632 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612633 };
[email protected]23e482282013-06-14 16:08:0212634 scoped_ptr<SpdyFrame> host1_resp(
12635 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12636 scoped_ptr<SpdyFrame> host1_resp_body(
12637 spdy_util_.ConstructSpdyBodyFrame(1, true));
12638 scoped_ptr<SpdyFrame> host2_resp(
12639 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12640 scoped_ptr<SpdyFrame> host2_resp_body(
12641 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612642 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312643 CreateMockRead(*host1_resp, 1),
12644 CreateMockRead(*host1_resp_body, 2),
12645 CreateMockRead(*host2_resp, 4),
12646 CreateMockRead(*host2_resp_body, 5),
12647 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612648 };
12649
[email protected]d2b5f092012-06-08 23:55:0212650 IPAddressNumber ip;
12651 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12652 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12653 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312654 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12655 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712656 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612657
[email protected]aa22b242011-11-16 18:58:2912658 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612659 HttpRequestInfo request1;
12660 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312661 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612662 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012663 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612664
[email protected]49639fa2011-12-20 23:22:4112665 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612666 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112667 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612668
12669 const HttpResponseInfo* response = trans1.GetResponseInfo();
12670 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012671 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612672 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12673
12674 std::string response_data;
12675 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12676 EXPECT_EQ("hello!", response_data);
12677
12678 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1012679 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4612680 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012681 rv = host_resolver.Resolve(resolve_info,
12682 DEFAULT_PRIORITY,
12683 &ignored,
12684 callback.callback(),
12685 NULL,
12686 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712687 EXPECT_EQ(ERR_IO_PENDING, rv);
12688 rv = callback.WaitForResult();
12689 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612690
12691 HttpRequestInfo request2;
12692 request2.method = "GET";
12693 request2.url = GURL("https://www.gmail.com/");
12694 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012695 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612696
[email protected]49639fa2011-12-20 23:22:4112697 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612698 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112699 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612700
12701 response = trans2.GetResponseInfo();
12702 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012703 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612704 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12705 EXPECT_TRUE(response->was_fetched_via_spdy);
12706 EXPECT_TRUE(response->was_npn_negotiated);
12707 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12708 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612709}
12710
[email protected]23e482282013-06-14 16:08:0212711TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2312712 const std::string https_url = "https://www.example.org:8080/";
12713 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412714
12715 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4612716 scoped_ptr<SpdyFrame> req1(
12717 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0412718
12719 MockWrite writes1[] = {
12720 CreateMockWrite(*req1, 0),
12721 };
12722
[email protected]23e482282013-06-14 16:08:0212723 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12724 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0412725 MockRead reads1[] = {
12726 CreateMockRead(*resp1, 1),
12727 CreateMockRead(*body1, 2),
12728 MockRead(ASYNC, ERR_IO_PENDING, 3)
12729 };
12730
rch8e6c6c42015-05-01 14:05:1312731 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
12732 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412733 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712734 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412735
12736 // HTTP GET for the HTTP URL
12737 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1312738 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3412739 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2312740 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3412741 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0412742 };
12743
12744 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1312745 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12746 MockRead(ASYNC, 2, "hello"),
12747 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0412748 };
12749
rch8e6c6c42015-05-01 14:05:1312750 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12751 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0412752
[email protected]8450d722012-07-02 19:14:0412753 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212754 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712755 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12756 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12757 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0412758
mmenkee65e7af2015-10-13 17:16:4212759 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412760
12761 // Start the first transaction to set up the SpdySession
12762 HttpRequestInfo request1;
12763 request1.method = "GET";
12764 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412765 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012766 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412767 TestCompletionCallback callback1;
12768 EXPECT_EQ(ERR_IO_PENDING,
12769 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412770 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412771
12772 EXPECT_EQ(OK, callback1.WaitForResult());
12773 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12774
12775 // Now, start the HTTP request
12776 HttpRequestInfo request2;
12777 request2.method = "GET";
12778 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412779 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012780 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412781 TestCompletionCallback callback2;
12782 EXPECT_EQ(ERR_IO_PENDING,
12783 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412784 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412785
12786 EXPECT_EQ(OK, callback2.WaitForResult());
12787 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12788}
12789
bnc1b0e36852015-04-28 15:32:5912790class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
12791 public:
12792 void Run(bool pooling, bool valid) {
12793 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
12794 443);
12795 HostPortPair alternative("www.example.org", 443);
12796
12797 base::FilePath certs_dir = GetTestCertsDirectory();
12798 scoped_refptr<X509Certificate> cert(
12799 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
12800 ASSERT_TRUE(cert.get());
12801 bool common_name_fallback_used;
12802 EXPECT_EQ(valid,
12803 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
12804 EXPECT_TRUE(
12805 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
12806 SSLSocketDataProvider ssl(ASYNC, OK);
12807 ssl.SetNextProto(GetParam());
12808 ssl.cert = cert;
12809 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12810
12811 // If pooling, then start a request to alternative first to create a
12812 // SpdySession.
12813 std::string url0 = "https://www.example.org:443";
12814 // Second request to origin, which has an alternative service, and could
12815 // open a connection to the alternative host or pool to the existing one.
12816 std::string url1("https://");
12817 url1.append(origin.host());
12818 url1.append(":443");
12819
12820 scoped_ptr<SpdyFrame> req0;
12821 scoped_ptr<SpdyFrame> req1;
12822 scoped_ptr<SpdyFrame> resp0;
12823 scoped_ptr<SpdyFrame> body0;
12824 scoped_ptr<SpdyFrame> resp1;
12825 scoped_ptr<SpdyFrame> body1;
12826 std::vector<MockWrite> writes;
12827 std::vector<MockRead> reads;
12828
12829 if (pooling) {
12830 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
12831 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
12832
12833 writes.push_back(CreateMockWrite(*req0, 0));
12834 writes.push_back(CreateMockWrite(*req1, 3));
12835
12836 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12837 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12838 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12839 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
12840
12841 reads.push_back(CreateMockRead(*resp0, 1));
12842 reads.push_back(CreateMockRead(*body0, 2));
12843 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
12844 reads.push_back(CreateMockRead(*resp1, 5));
12845 reads.push_back(CreateMockRead(*body1, 6));
12846 reads.push_back(MockRead(ASYNC, OK, 7));
12847 } else {
12848 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
12849
12850 writes.push_back(CreateMockWrite(*req1, 0));
12851
12852 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12853 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12854
12855 reads.push_back(CreateMockRead(*resp1, 1));
12856 reads.push_back(CreateMockRead(*body1, 2));
12857 reads.push_back(MockRead(ASYNC, OK, 3));
12858 }
12859
rch32320842015-05-16 15:57:0912860 SequencedSocketData data(vector_as_array(&reads), reads.size(),
12861 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5912862 session_deps_.socket_factory->AddSocketDataProvider(&data);
12863
12864 // Connection to the origin fails.
12865 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12866 StaticSocketDataProvider data_refused;
12867 data_refused.set_connect_data(mock_connect);
12868 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12869
bnc55ff9da2015-08-19 18:42:3512870 session_deps_.use_alternative_services = true;
mmenkee65e7af2015-10-13 17:16:4212871 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc1b0e36852015-04-28 15:32:5912872 base::WeakPtr<HttpServerProperties> http_server_properties =
12873 session->http_server_properties();
12874 AlternativeService alternative_service(
12875 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212876 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc1b0e36852015-04-28 15:32:5912877 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212878 1.0, expiration);
bnc1b0e36852015-04-28 15:32:5912879
12880 // First request to alternative.
12881 if (pooling) {
12882 scoped_ptr<HttpTransaction> trans0(
12883 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12884 HttpRequestInfo request0;
12885 request0.method = "GET";
12886 request0.url = GURL(url0);
12887 request0.load_flags = 0;
12888 TestCompletionCallback callback0;
12889
12890 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
12891 EXPECT_EQ(ERR_IO_PENDING, rv);
12892 rv = callback0.WaitForResult();
12893 EXPECT_EQ(OK, rv);
12894 }
12895
12896 // Second request to origin.
12897 scoped_ptr<HttpTransaction> trans1(
12898 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12899 HttpRequestInfo request1;
12900 request1.method = "GET";
12901 request1.url = GURL(url1);
12902 request1.load_flags = 0;
12903 TestCompletionCallback callback1;
12904
12905 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12906 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0912907 base::MessageLoop::current()->RunUntilIdle();
12908 if (data.IsReadPaused()) {
12909 data.CompleteRead();
12910 }
bnc1b0e36852015-04-28 15:32:5912911 rv = callback1.WaitForResult();
12912 if (valid) {
12913 EXPECT_EQ(OK, rv);
12914 } else {
12915 if (pooling) {
12916 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12917 } else {
12918 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
12919 }
12920 }
12921 }
12922};
12923
12924INSTANTIATE_TEST_CASE_P(NextProto,
12925 AltSvcCertificateVerificationTest,
12926 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:4312927 kProtoHTTP2));
bnc1b0e36852015-04-28 15:32:5912928
12929// The alternative service host must exhibit a certificate that is valid for the
12930// origin host. Test that this is enforced when pooling to an existing
12931// connection.
12932TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
12933 Run(true, true);
12934}
12935
12936TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
12937 Run(true, false);
12938}
12939
12940// The alternative service host must exhibit a certificate that is valid for the
12941// origin host. Test that this is enforced when opening a new connection.
12942TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
12943 Run(false, true);
12944}
12945
12946TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
12947 Run(false, false);
12948}
12949
bnc5452e2a2015-05-08 16:27:4212950// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
12951// with the alternative server. That connection should not be used.
12952TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
12953 HostPortPair origin("origin.example.org", 443);
12954 HostPortPair alternative("alternative.example.org", 443);
12955
12956 // Negotiate HTTP/1.1 with alternative.example.org.
12957 SSLSocketDataProvider ssl(ASYNC, OK);
12958 ssl.SetNextProto(kProtoHTTP11);
12959 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12960
12961 // No data should be read from the alternative, because HTTP/1.1 is
12962 // negotiated.
12963 StaticSocketDataProvider data;
12964 session_deps_.socket_factory->AddSocketDataProvider(&data);
12965
12966 // This test documents that an alternate Job should not be used if HTTP/1.1 is
12967 // negotiated. In order to test this, a failed connection to the origin is
12968 // mocked. This way the request relies on the alternate Job.
12969 StaticSocketDataProvider data_refused;
12970 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12971 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12972
12973 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512974 session_deps_.use_alternative_services = true;
mmenkee65e7af2015-10-13 17:16:4212975 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4212976 base::WeakPtr<HttpServerProperties> http_server_properties =
12977 session->http_server_properties();
12978 AlternativeService alternative_service(
12979 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212980 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212981 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212982 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212983
12984 scoped_ptr<HttpTransaction> trans(
12985 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12986 HttpRequestInfo request;
12987 request.method = "GET";
12988 request.url = GURL("https://origin.example.org:443");
12989 request.load_flags = 0;
12990 TestCompletionCallback callback;
12991
12992 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
12993 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
12994 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12995 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
12996}
12997
bnc40448a532015-05-11 19:13:1412998// A request to a server with an alternative service fires two Jobs: one to the
12999// origin, and an alternate one to the alternative server. If the former
13000// succeeds, the request should succeed, even if the latter fails because
13001// HTTP/1.1 is negotiated which is insufficient for alternative service.
13002TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
13003 HostPortPair origin("origin.example.org", 443);
13004 HostPortPair alternative("alternative.example.org", 443);
13005
13006 // Negotiate HTTP/1.1 with alternative.
13007 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
13008 alternative_ssl.SetNextProto(kProtoHTTP11);
13009 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13010
13011 // No data should be read from the alternative, because HTTP/1.1 is
13012 // negotiated.
13013 StaticSocketDataProvider data;
13014 session_deps_.socket_factory->AddSocketDataProvider(&data);
13015
13016 // Negotiate HTTP/1.1 with origin.
13017 SSLSocketDataProvider origin_ssl(ASYNC, OK);
13018 origin_ssl.SetNextProto(kProtoHTTP11);
13019 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13020
13021 MockWrite http_writes[] = {
13022 MockWrite(
13023 "GET / HTTP/1.1\r\n"
13024 "Host: origin.example.org\r\n"
13025 "Connection: keep-alive\r\n\r\n"),
13026 MockWrite(
13027 "GET /second HTTP/1.1\r\n"
13028 "Host: origin.example.org\r\n"
13029 "Connection: keep-alive\r\n\r\n"),
13030 };
13031
13032 MockRead http_reads[] = {
13033 MockRead("HTTP/1.1 200 OK\r\n"),
13034 MockRead("Content-Type: text/html\r\n"),
13035 MockRead("Content-Length: 6\r\n\r\n"),
13036 MockRead("foobar"),
13037 MockRead("HTTP/1.1 200 OK\r\n"),
13038 MockRead("Content-Type: text/html\r\n"),
13039 MockRead("Content-Length: 7\r\n\r\n"),
13040 MockRead("another"),
13041 };
13042 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13043 http_writes, arraysize(http_writes));
13044 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13045
13046 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3513047 session_deps_.use_alternative_services = true;
mmenkee65e7af2015-10-13 17:16:4213048 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc40448a532015-05-11 19:13:1413049 base::WeakPtr<HttpServerProperties> http_server_properties =
13050 session->http_server_properties();
13051 AlternativeService alternative_service(
13052 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213053 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc40448a532015-05-11 19:13:1413054 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1213055 1.0, expiration);
bnc40448a532015-05-11 19:13:1413056
13057 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13058 HttpRequestInfo request1;
13059 request1.method = "GET";
13060 request1.url = GURL("https://origin.example.org:443");
13061 request1.load_flags = 0;
13062 TestCompletionCallback callback1;
13063
13064 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
13065 rv = callback1.GetResult(rv);
13066 EXPECT_EQ(OK, rv);
13067
13068 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
13069 ASSERT_TRUE(response1 != nullptr);
13070 ASSERT_TRUE(response1->headers.get() != nullptr);
13071 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13072
13073 std::string response_data1;
13074 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
13075 EXPECT_EQ("foobar", response_data1);
13076
13077 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13078 // for alternative service.
13079 EXPECT_TRUE(
13080 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13081
13082 // Since |alternative_service| is broken, a second transaction to origin
13083 // should not start an alternate Job. It should pool to existing connection
13084 // to origin.
13085 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13086 HttpRequestInfo request2;
13087 request2.method = "GET";
13088 request2.url = GURL("https://origin.example.org:443/second");
13089 request2.load_flags = 0;
13090 TestCompletionCallback callback2;
13091
13092 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
13093 rv = callback2.GetResult(rv);
13094 EXPECT_EQ(OK, rv);
13095
13096 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
13097 ASSERT_TRUE(response2 != nullptr);
13098 ASSERT_TRUE(response2->headers.get() != nullptr);
13099 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13100
13101 std::string response_data2;
13102 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
13103 EXPECT_EQ("another", response_data2);
13104}
13105
bnc5452e2a2015-05-08 16:27:4213106// Alternative service requires HTTP/2 (or SPDY), but there is already a
13107// HTTP/1.1 socket open to the alternative server. That socket should not be
13108// used.
13109TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
13110 HostPortPair origin("origin.example.org", 443);
13111 HostPortPair alternative("alternative.example.org", 443);
13112 std::string origin_url = "https://origin.example.org:443";
13113 std::string alternative_url = "https://alternative.example.org:443";
13114
13115 // Negotiate HTTP/1.1 with alternative.example.org.
13116 SSLSocketDataProvider ssl(ASYNC, OK);
13117 ssl.SetNextProto(kProtoHTTP11);
13118 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13119
13120 // HTTP/1.1 data for |request1| and |request2|.
13121 MockWrite http_writes[] = {
13122 MockWrite(
13123 "GET / HTTP/1.1\r\n"
13124 "Host: alternative.example.org\r\n"
13125 "Connection: keep-alive\r\n\r\n"),
13126 MockWrite(
13127 "GET / HTTP/1.1\r\n"
13128 "Host: alternative.example.org\r\n"
13129 "Connection: keep-alive\r\n\r\n"),
13130 };
13131
13132 MockRead http_reads[] = {
13133 MockRead(
13134 "HTTP/1.1 200 OK\r\n"
13135 "Content-Type: text/html; charset=iso-8859-1\r\n"
13136 "Content-Length: 40\r\n\r\n"
13137 "first HTTP/1.1 response from alternative"),
13138 MockRead(
13139 "HTTP/1.1 200 OK\r\n"
13140 "Content-Type: text/html; charset=iso-8859-1\r\n"
13141 "Content-Length: 41\r\n\r\n"
13142 "second HTTP/1.1 response from alternative"),
13143 };
13144 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13145 http_writes, arraysize(http_writes));
13146 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13147
13148 // This test documents that an alternate Job should not pool to an already
13149 // existing HTTP/1.1 connection. In order to test this, a failed connection
13150 // to the origin is mocked. This way |request2| relies on the alternate Job.
13151 StaticSocketDataProvider data_refused;
13152 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13153 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13154
13155 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3513156 session_deps_.use_alternative_services = true;
mmenkee65e7af2015-10-13 17:16:4213157 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213158 base::WeakPtr<HttpServerProperties> http_server_properties =
13159 session->http_server_properties();
13160 AlternativeService alternative_service(
13161 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213162 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4213163 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1213164 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4213165
13166 // First transaction to alternative to open an HTTP/1.1 socket.
13167 scoped_ptr<HttpTransaction> trans1(
13168 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13169 HttpRequestInfo request1;
13170 request1.method = "GET";
13171 request1.url = GURL(alternative_url);
13172 request1.load_flags = 0;
13173 TestCompletionCallback callback1;
13174
13175 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13176 EXPECT_EQ(OK, callback1.GetResult(rv));
13177 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13178 ASSERT_TRUE(response1);
13179 ASSERT_TRUE(response1->headers.get());
13180 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13181 EXPECT_TRUE(response1->was_npn_negotiated);
13182 EXPECT_FALSE(response1->was_fetched_via_spdy);
13183 std::string response_data1;
13184 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
13185 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
13186
13187 // Request for origin.example.org, which has an alternative service. This
13188 // will start two Jobs: the alternative looks for connections to pool to,
13189 // finds one which is HTTP/1.1, and should ignore it, and should not try to
13190 // open other connections to alternative server. The Job to origin fails, so
13191 // this request fails.
13192 scoped_ptr<HttpTransaction> trans2(
13193 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13194 HttpRequestInfo request2;
13195 request2.method = "GET";
13196 request2.url = GURL(origin_url);
13197 request2.load_flags = 0;
13198 TestCompletionCallback callback2;
13199
13200 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
13201 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
13202
13203 // Another transaction to alternative. This is to test that the HTTP/1.1
13204 // socket is still open and in the pool.
13205 scoped_ptr<HttpTransaction> trans3(
13206 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13207 HttpRequestInfo request3;
13208 request3.method = "GET";
13209 request3.url = GURL(alternative_url);
13210 request3.load_flags = 0;
13211 TestCompletionCallback callback3;
13212
13213 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
13214 EXPECT_EQ(OK, callback3.GetResult(rv));
13215 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
13216 ASSERT_TRUE(response3);
13217 ASSERT_TRUE(response3->headers.get());
13218 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
13219 EXPECT_TRUE(response3->was_npn_negotiated);
13220 EXPECT_FALSE(response3->was_fetched_via_spdy);
13221 std::string response_data3;
13222 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
13223 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
13224}
13225
[email protected]23e482282013-06-14 16:08:0213226TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2313227 const std::string https_url = "https://www.example.org:8080/";
13228 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413229
13230 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2313231 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3413232 scoped_ptr<SpdyFrame> connect(
13233 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4613234 scoped_ptr<SpdyFrame> req1(
13235 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0213236 scoped_ptr<SpdyFrame> wrapped_req1(
13237 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3913238
13239 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2913240 SpdyHeaderBlock req2_block;
bnc7ecc1122015-09-28 13:22:4913241 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]745aa9c2014-06-27 02:21:2913242 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2313243 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2913244 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4913245 req2_block[spdy_util_.GetPathKey()] = "/";
[email protected]601e03f12014-04-06 16:26:3913246 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2913247 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0413248
13249 MockWrite writes1[] = {
13250 CreateMockWrite(*connect, 0),
13251 CreateMockWrite(*wrapped_req1, 2),
13252 CreateMockWrite(*req2, 5),
13253 };
13254
[email protected]23e482282013-06-14 16:08:0213255 scoped_ptr<SpdyFrame> conn_resp(
13256 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13257 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13258 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
13259 scoped_ptr<SpdyFrame> wrapped_resp1(
13260 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
13261 scoped_ptr<SpdyFrame> wrapped_body1(
13262 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
13263 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
13264 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0413265 MockRead reads1[] = {
13266 CreateMockRead(*conn_resp, 1),
13267 CreateMockRead(*wrapped_resp1, 3),
13268 CreateMockRead(*wrapped_body1, 4),
13269 CreateMockRead(*resp2, 6),
13270 CreateMockRead(*body2, 7),
13271 MockRead(ASYNC, ERR_IO_PENDING, 8)
13272 };
13273
[email protected]dd54bd82012-07-19 23:44:5713274 DeterministicSocketData data1(reads1, arraysize(reads1),
13275 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413276 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713277 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413278
rdsmith82957ad2015-09-16 19:42:0313279 session_deps_.proxy_service =
13280 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5113281 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713282 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0413283 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0213284 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0713285 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0413286 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0213287 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0713288 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
13289 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0413290
mmenkee65e7af2015-10-13 17:16:4213291 scoped_ptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0713292 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413293
13294 // Start the first transaction to set up the SpdySession
13295 HttpRequestInfo request1;
13296 request1.method = "GET";
13297 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413298 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013299 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413300 TestCompletionCallback callback1;
13301 EXPECT_EQ(ERR_IO_PENDING,
13302 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413303 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5713304 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0413305
13306 EXPECT_EQ(OK, callback1.WaitForResult());
13307 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13308
[email protected]f6c63db52013-02-02 00:35:2213309 LoadTimingInfo load_timing_info1;
13310 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
13311 TestLoadTimingNotReusedWithPac(load_timing_info1,
13312 CONNECT_TIMING_HAS_SSL_TIMES);
13313
[email protected]8450d722012-07-02 19:14:0413314 // Now, start the HTTP request
13315 HttpRequestInfo request2;
13316 request2.method = "GET";
13317 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413318 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013319 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413320 TestCompletionCallback callback2;
13321 EXPECT_EQ(ERR_IO_PENDING,
13322 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413323 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5713324 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0413325
13326 EXPECT_EQ(OK, callback2.WaitForResult());
13327 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2213328
13329 LoadTimingInfo load_timing_info2;
13330 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
13331 // The established SPDY sessions is considered reused by the HTTP request.
13332 TestLoadTimingReusedWithPac(load_timing_info2);
13333 // HTTP requests over a SPDY session should have a different connection
13334 // socket_log_id than requests over a tunnel.
13335 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0413336}
13337
[email protected]2d88e7d2012-07-19 17:55:1713338// Test that in the case where we have a SPDY session to a SPDY proxy
13339// that we do not pool other origins that resolve to the same IP when
13340// the certificate does not match the new origin.
13341// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0213342TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2313343 const std::string url1 = "http://www.example.org/";
13344 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1713345 const std::string ip_addr = "1.2.3.4";
13346
13347 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0213348 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2313349 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2913350 scoped_ptr<SpdyFrame> req1(
13351 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1713352
13353 MockWrite writes1[] = {
13354 CreateMockWrite(*req1, 0),
13355 };
13356
[email protected]23e482282013-06-14 16:08:0213357 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13358 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1713359 MockRead reads1[] = {
bncb9e20fc62015-08-17 17:19:3713360 CreateMockRead(*resp1, 1),
13361 CreateMockRead(*body1, 2),
13362 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1713363 };
13364
13365 scoped_ptr<DeterministicSocketData> data1(
13366 new DeterministicSocketData(reads1, arraysize(reads1),
13367 writes1, arraysize(writes1)));
13368 IPAddressNumber ip;
13369 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
13370 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13371 MockConnect connect_data1(ASYNC, OK, peer_addr);
13372 data1->set_connect_data(connect_data1);
13373
13374 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4613375 scoped_ptr<SpdyFrame> req2(
13376 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1713377
13378 MockWrite writes2[] = {
13379 CreateMockWrite(*req2, 0),
13380 };
13381
[email protected]23e482282013-06-14 16:08:0213382 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13383 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1713384 MockRead reads2[] = {
bncb9e20fc62015-08-17 17:19:3713385 CreateMockRead(*resp2, 1),
13386 CreateMockRead(*body2, 2),
13387 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1713388 };
13389
13390 scoped_ptr<DeterministicSocketData> data2(
13391 new DeterministicSocketData(reads2, arraysize(reads2),
13392 writes2, arraysize(writes2)));
13393 MockConnect connect_data2(ASYNC, OK);
13394 data2->set_connect_data(connect_data2);
13395
13396 // Set up a proxy config that sends HTTP requests to a proxy, and
13397 // all others direct.
13398 ProxyConfig proxy_config;
13399 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0713400 session_deps_.proxy_service.reset(new ProxyService(
csharrisonb7e3a082015-09-22 19:13:0413401 make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)), nullptr,
13402 NULL));
[email protected]2d88e7d2012-07-19 17:55:1713403
bncce36dca22015-04-21 22:11:2313404 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
13405 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1713406 // Load a valid cert. Note, that this does not need to
13407 // be valid for proxy because the MockSSLClientSocket does
13408 // not actually verify it. But SpdySession will use this
13409 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2313410 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
13411 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0713412 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
13413 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
13414 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1713415
13416 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0213417 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0713418 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
13419 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
13420 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1713421
[email protected]bb88e1d32013-05-03 23:11:0713422 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2313423 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0713424 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1713425
mmenkee65e7af2015-10-13 17:16:4213426 scoped_ptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0713427 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1713428
13429 // Start the first transaction to set up the SpdySession
13430 HttpRequestInfo request1;
13431 request1.method = "GET";
13432 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1713433 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013434 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713435 TestCompletionCallback callback1;
13436 ASSERT_EQ(ERR_IO_PENDING,
13437 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
13438 data1->RunFor(3);
13439
13440 ASSERT_TRUE(callback1.have_result());
13441 EXPECT_EQ(OK, callback1.WaitForResult());
13442 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13443
13444 // Now, start the HTTP request
13445 HttpRequestInfo request2;
13446 request2.method = "GET";
13447 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1713448 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013449 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713450 TestCompletionCallback callback2;
13451 EXPECT_EQ(ERR_IO_PENDING,
13452 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413453 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1713454 data2->RunFor(3);
13455
13456 ASSERT_TRUE(callback2.have_result());
13457 EXPECT_EQ(OK, callback2.WaitForResult());
13458 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13459}
13460
[email protected]85f97342013-04-17 06:12:2413461// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
13462// error) in SPDY session, removes the socket from pool and closes the SPDY
13463// session. Verify that new url's from the same HttpNetworkSession (and a new
13464// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0213465TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2313466 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2413467
13468 MockRead reads1[] = {
13469 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
13470 };
13471
mmenke11eb5152015-06-09 14:50:5013472 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2413473
[email protected]cdf8f7e72013-05-23 10:56:4613474 scoped_ptr<SpdyFrame> req2(
13475 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2413476 MockWrite writes2[] = {
13477 CreateMockWrite(*req2, 0),
13478 };
13479
[email protected]23e482282013-06-14 16:08:0213480 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13481 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2413482 MockRead reads2[] = {
13483 CreateMockRead(*resp2, 1),
13484 CreateMockRead(*body2, 2),
13485 MockRead(ASYNC, OK, 3) // EOF
13486 };
13487
mmenke11eb5152015-06-09 14:50:5013488 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13489 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2413490
[email protected]85f97342013-04-17 06:12:2413491 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0213492 ssl1.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5013493 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13494 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2413495
13496 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0213497 ssl2.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5013498 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13499 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2413500
mmenkee65e7af2015-10-13 17:16:4213501 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5013502 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2413503
13504 // Start the first transaction to set up the SpdySession and verify that
13505 // connection was closed.
13506 HttpRequestInfo request1;
13507 request1.method = "GET";
13508 request1.url = GURL(https_url);
13509 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013510 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413511 TestCompletionCallback callback1;
13512 EXPECT_EQ(ERR_IO_PENDING,
13513 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2413514 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
13515
13516 // Now, start the second request and make sure it succeeds.
13517 HttpRequestInfo request2;
13518 request2.method = "GET";
13519 request2.url = GURL(https_url);
13520 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013521 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413522 TestCompletionCallback callback2;
13523 EXPECT_EQ(ERR_IO_PENDING,
13524 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2413525
mmenke11eb5152015-06-09 14:50:5013526 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2413527 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13528}
13529
[email protected]23e482282013-06-14 16:08:0213530TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2313531 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0313532 ClientSocketPoolManager::set_max_sockets_per_group(
13533 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13534 ClientSocketPoolManager::set_max_sockets_per_pool(
13535 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13536
13537 // Use two different hosts with different IPs so they don't get pooled.
13538 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
13539 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
mmenkee65e7af2015-10-13 17:16:4213540 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0313541
13542 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0213543 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0313544 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0213545 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0313546 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13547 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13548
[email protected]cdf8f7e72013-05-23 10:56:4613549 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0313550 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
13551 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1313552 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0313553 };
[email protected]23e482282013-06-14 16:08:0213554 scoped_ptr<SpdyFrame> host1_resp(
13555 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13556 scoped_ptr<SpdyFrame> host1_resp_body(
13557 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313558 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1313559 CreateMockRead(*host1_resp, 1),
13560 CreateMockRead(*host1_resp_body, 2),
13561 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313562 };
13563
rch8e6c6c42015-05-01 14:05:1313564 scoped_ptr<SequencedSocketData> spdy1_data(
13565 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
13566 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0313567 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
13568
[email protected]cdf8f7e72013-05-23 10:56:4613569 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0313570 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
13571 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1313572 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0313573 };
[email protected]23e482282013-06-14 16:08:0213574 scoped_ptr<SpdyFrame> host2_resp(
13575 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13576 scoped_ptr<SpdyFrame> host2_resp_body(
13577 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313578 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1313579 CreateMockRead(*host2_resp, 1),
13580 CreateMockRead(*host2_resp_body, 2),
13581 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313582 };
13583
rch8e6c6c42015-05-01 14:05:1313584 scoped_ptr<SequencedSocketData> spdy2_data(
13585 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
13586 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0313587 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
13588
13589 MockWrite http_write[] = {
13590 MockWrite("GET / HTTP/1.1\r\n"
13591 "Host: www.a.com\r\n"
13592 "Connection: keep-alive\r\n\r\n"),
13593 };
13594
13595 MockRead http_read[] = {
13596 MockRead("HTTP/1.1 200 OK\r\n"),
13597 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13598 MockRead("Content-Length: 6\r\n\r\n"),
13599 MockRead("hello!"),
13600 };
13601 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
13602 http_write, arraysize(http_write));
13603 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13604
13605 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4013606 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5313607 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313608 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613609 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313610
13611 TestCompletionCallback callback;
13612 HttpRequestInfo request1;
13613 request1.method = "GET";
13614 request1.url = GURL("https://www.a.com/");
13615 request1.load_flags = 0;
13616 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5013617 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313618
13619 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
13620 EXPECT_EQ(ERR_IO_PENDING, rv);
13621 EXPECT_EQ(OK, callback.WaitForResult());
13622
13623 const HttpResponseInfo* response = trans->GetResponseInfo();
13624 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013625 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313626 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13627 EXPECT_TRUE(response->was_fetched_via_spdy);
13628 EXPECT_TRUE(response->was_npn_negotiated);
13629
13630 std::string response_data;
13631 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13632 EXPECT_EQ("hello!", response_data);
13633 trans.reset();
13634 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613635 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313636
13637 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4013638 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5313639 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313640 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613641 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313642 HttpRequestInfo request2;
13643 request2.method = "GET";
13644 request2.url = GURL("https://www.b.com/");
13645 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013646 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313647
13648 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
13649 EXPECT_EQ(ERR_IO_PENDING, rv);
13650 EXPECT_EQ(OK, callback.WaitForResult());
13651
13652 response = trans->GetResponseInfo();
13653 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013654 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313655 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13656 EXPECT_TRUE(response->was_fetched_via_spdy);
13657 EXPECT_TRUE(response->was_npn_negotiated);
13658 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13659 EXPECT_EQ("hello!", response_data);
13660 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613661 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313662 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613663 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313664
13665 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4013666 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5313667 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313668 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613669 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0313670 HttpRequestInfo request3;
13671 request3.method = "GET";
13672 request3.url = GURL("http://www.a.com/");
13673 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013674 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313675
13676 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
13677 EXPECT_EQ(ERR_IO_PENDING, rv);
13678 EXPECT_EQ(OK, callback.WaitForResult());
13679
13680 response = trans->GetResponseInfo();
13681 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013682 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313683 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13684 EXPECT_FALSE(response->was_fetched_via_spdy);
13685 EXPECT_FALSE(response->was_npn_negotiated);
13686 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13687 EXPECT_EQ("hello!", response_data);
13688 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613689 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313690 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613691 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313692}
13693
[email protected]79e1fd62013-06-20 06:50:0413694TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
13695 HttpRequestInfo request;
13696 request.method = "GET";
bncce36dca22015-04-21 22:11:2313697 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413698 request.load_flags = 0;
13699
mmenkee65e7af2015-10-13 17:16:4213700 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413701 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113702 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413703
ttuttled9dbc652015-09-29 20:00:5913704 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413705 StaticSocketDataProvider data;
13706 data.set_connect_data(mock_connect);
13707 session_deps_.socket_factory->AddSocketDataProvider(&data);
13708
13709 TestCompletionCallback callback;
13710
13711 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13712 EXPECT_EQ(ERR_IO_PENDING, rv);
13713
13714 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5913715 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0413716
[email protected]79e1fd62013-06-20 06:50:0413717 // We don't care whether this succeeds or fails, but it shouldn't crash.
13718 HttpRequestHeaders request_headers;
13719 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713720
13721 ConnectionAttempts attempts;
13722 trans->GetConnectionAttempts(&attempts);
13723 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5913724 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
13725
13726 IPEndPoint endpoint;
13727 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
13728 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413729}
13730
13731TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
13732 HttpRequestInfo request;
13733 request.method = "GET";
bncce36dca22015-04-21 22:11:2313734 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413735 request.load_flags = 0;
13736
mmenkee65e7af2015-10-13 17:16:4213737 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413738 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113739 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413740
ttuttled9dbc652015-09-29 20:00:5913741 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413742 StaticSocketDataProvider data;
13743 data.set_connect_data(mock_connect);
13744 session_deps_.socket_factory->AddSocketDataProvider(&data);
13745
13746 TestCompletionCallback callback;
13747
13748 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13749 EXPECT_EQ(ERR_IO_PENDING, rv);
13750
13751 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5913752 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0413753
[email protected]79e1fd62013-06-20 06:50:0413754 // We don't care whether this succeeds or fails, but it shouldn't crash.
13755 HttpRequestHeaders request_headers;
13756 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713757
13758 ConnectionAttempts attempts;
13759 trans->GetConnectionAttempts(&attempts);
13760 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5913761 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
13762
13763 IPEndPoint endpoint;
13764 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
13765 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413766}
13767
13768TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
13769 HttpRequestInfo request;
13770 request.method = "GET";
bncce36dca22015-04-21 22:11:2313771 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413772 request.load_flags = 0;
13773
mmenkee65e7af2015-10-13 17:16:4213774 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413775 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113776 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413777
13778 MockWrite data_writes[] = {
13779 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13780 };
13781 MockRead data_reads[] = {
13782 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13783 };
13784
13785 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13786 data_writes, arraysize(data_writes));
13787 session_deps_.socket_factory->AddSocketDataProvider(&data);
13788
13789 TestCompletionCallback callback;
13790
13791 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13792 EXPECT_EQ(ERR_IO_PENDING, rv);
13793
13794 rv = callback.WaitForResult();
13795 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13796
[email protected]79e1fd62013-06-20 06:50:0413797 HttpRequestHeaders request_headers;
13798 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13799 EXPECT_TRUE(request_headers.HasHeader("Host"));
13800}
13801
13802TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
13803 HttpRequestInfo request;
13804 request.method = "GET";
bncce36dca22015-04-21 22:11:2313805 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413806 request.load_flags = 0;
13807
mmenkee65e7af2015-10-13 17:16:4213808 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413809 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113810 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413811
13812 MockWrite data_writes[] = {
13813 MockWrite(ASYNC, ERR_CONNECTION_RESET),
13814 };
13815 MockRead data_reads[] = {
13816 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13817 };
13818
13819 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13820 data_writes, arraysize(data_writes));
13821 session_deps_.socket_factory->AddSocketDataProvider(&data);
13822
13823 TestCompletionCallback callback;
13824
13825 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13826 EXPECT_EQ(ERR_IO_PENDING, rv);
13827
13828 rv = callback.WaitForResult();
13829 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13830
[email protected]79e1fd62013-06-20 06:50:0413831 HttpRequestHeaders request_headers;
13832 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13833 EXPECT_TRUE(request_headers.HasHeader("Host"));
13834}
13835
13836TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
13837 HttpRequestInfo request;
13838 request.method = "GET";
bncce36dca22015-04-21 22:11:2313839 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413840 request.load_flags = 0;
13841
mmenkee65e7af2015-10-13 17:16:4213842 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413843 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113844 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413845
13846 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313847 MockWrite(
13848 "GET / HTTP/1.1\r\n"
13849 "Host: www.example.org\r\n"
13850 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413851 };
13852 MockRead data_reads[] = {
13853 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
13854 };
13855
13856 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13857 data_writes, arraysize(data_writes));
13858 session_deps_.socket_factory->AddSocketDataProvider(&data);
13859
13860 TestCompletionCallback callback;
13861
13862 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13863 EXPECT_EQ(ERR_IO_PENDING, rv);
13864
13865 rv = callback.WaitForResult();
13866 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13867
[email protected]79e1fd62013-06-20 06:50:0413868 HttpRequestHeaders request_headers;
13869 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13870 EXPECT_TRUE(request_headers.HasHeader("Host"));
13871}
13872
13873TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
13874 HttpRequestInfo request;
13875 request.method = "GET";
bncce36dca22015-04-21 22:11:2313876 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413877 request.load_flags = 0;
13878
mmenkee65e7af2015-10-13 17:16:4213879 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413880 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113881 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413882
13883 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313884 MockWrite(
13885 "GET / HTTP/1.1\r\n"
13886 "Host: www.example.org\r\n"
13887 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413888 };
13889 MockRead data_reads[] = {
13890 MockRead(ASYNC, ERR_CONNECTION_RESET),
13891 };
13892
13893 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13894 data_writes, arraysize(data_writes));
13895 session_deps_.socket_factory->AddSocketDataProvider(&data);
13896
13897 TestCompletionCallback callback;
13898
13899 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13900 EXPECT_EQ(ERR_IO_PENDING, rv);
13901
13902 rv = callback.WaitForResult();
13903 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13904
[email protected]79e1fd62013-06-20 06:50:0413905 HttpRequestHeaders request_headers;
13906 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13907 EXPECT_TRUE(request_headers.HasHeader("Host"));
13908}
13909
13910TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
13911 HttpRequestInfo request;
13912 request.method = "GET";
bncce36dca22015-04-21 22:11:2313913 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413914 request.load_flags = 0;
13915 request.extra_headers.SetHeader("X-Foo", "bar");
13916
mmenkee65e7af2015-10-13 17:16:4213917 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413918 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113919 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413920
13921 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313922 MockWrite(
13923 "GET / HTTP/1.1\r\n"
13924 "Host: www.example.org\r\n"
13925 "Connection: keep-alive\r\n"
13926 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413927 };
13928 MockRead data_reads[] = {
13929 MockRead("HTTP/1.1 200 OK\r\n"
13930 "Content-Length: 5\r\n\r\n"
13931 "hello"),
13932 MockRead(ASYNC, ERR_UNEXPECTED),
13933 };
13934
13935 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13936 data_writes, arraysize(data_writes));
13937 session_deps_.socket_factory->AddSocketDataProvider(&data);
13938
13939 TestCompletionCallback callback;
13940
13941 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13942 EXPECT_EQ(ERR_IO_PENDING, rv);
13943
13944 rv = callback.WaitForResult();
13945 EXPECT_EQ(OK, rv);
13946
13947 HttpRequestHeaders request_headers;
13948 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13949 std::string foo;
13950 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
13951 EXPECT_EQ("bar", foo);
13952}
13953
[email protected]bf828982013-08-14 18:01:4713954namespace {
13955
yhiranoa7e05bb2014-11-06 05:40:3913956// Fake HttpStream that simply records calls to SetPriority().
13957class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0313958 public base::SupportsWeakPtr<FakeStream> {
13959 public:
13960 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2013961 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0313962
13963 RequestPriority priority() const { return priority_; }
13964
dchengb03027d2014-10-21 12:00:2013965 int InitializeStream(const HttpRequestInfo* request_info,
13966 RequestPriority priority,
13967 const BoundNetLog& net_log,
13968 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313969 return ERR_IO_PENDING;
13970 }
13971
dchengb03027d2014-10-21 12:00:2013972 int SendRequest(const HttpRequestHeaders& request_headers,
13973 HttpResponseInfo* response,
13974 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313975 ADD_FAILURE();
13976 return ERR_UNEXPECTED;
13977 }
13978
dchengb03027d2014-10-21 12:00:2013979 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313980 ADD_FAILURE();
13981 return ERR_UNEXPECTED;
13982 }
13983
dchengb03027d2014-10-21 12:00:2013984 int ReadResponseBody(IOBuffer* buf,
13985 int buf_len,
13986 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313987 ADD_FAILURE();
13988 return ERR_UNEXPECTED;
13989 }
13990
dchengb03027d2014-10-21 12:00:2013991 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0313992
dchengb03027d2014-10-21 12:00:2013993 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0313994 ADD_FAILURE();
13995 return false;
13996 }
13997
dchengb03027d2014-10-21 12:00:2013998 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0313999 ADD_FAILURE();
14000 return false;
14001 }
14002
dchengb03027d2014-10-21 12:00:2014003 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314004
mmenkebd84c392015-09-02 14:12:3414005 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314006
sclittle4de1bab92015-09-22 21:28:2414007 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914008 ADD_FAILURE();
14009 return 0;
14010 }
14011
sclittlebe1ccf62015-09-02 19:40:3614012 int64_t GetTotalSentBytes() const override {
14013 ADD_FAILURE();
14014 return 0;
14015 }
14016
dchengb03027d2014-10-21 12:00:2014017 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314018 ADD_FAILURE();
14019 return false;
14020 }
14021
dchengb03027d2014-10-21 12:00:2014022 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14023
14024 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314025 ADD_FAILURE();
14026 }
14027
ttuttled9dbc652015-09-29 20:00:5914028 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14029
dchengb03027d2014-10-21 12:00:2014030 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314031
dchengb03027d2014-10-21 12:00:2014032 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314033
yhiranoa7e05bb2014-11-06 05:40:3914034 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
14035
14036 HttpStream* RenewStreamForAuth() override { return NULL; }
14037
[email protected]e86839fd2013-08-14 18:29:0314038 private:
14039 RequestPriority priority_;
14040
14041 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14042};
14043
14044// Fake HttpStreamRequest that simply records calls to SetPriority()
14045// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714046class FakeStreamRequest : public HttpStreamRequest,
14047 public base::SupportsWeakPtr<FakeStreamRequest> {
14048 public:
[email protected]e86839fd2013-08-14 18:29:0314049 FakeStreamRequest(RequestPriority priority,
14050 HttpStreamRequest::Delegate* delegate)
14051 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414052 delegate_(delegate),
14053 websocket_stream_create_helper_(NULL) {}
14054
14055 FakeStreamRequest(RequestPriority priority,
14056 HttpStreamRequest::Delegate* delegate,
14057 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14058 : priority_(priority),
14059 delegate_(delegate),
14060 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314061
dchengb03027d2014-10-21 12:00:2014062 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714063
14064 RequestPriority priority() const { return priority_; }
14065
[email protected]831e4a32013-11-14 02:14:4414066 const WebSocketHandshakeStreamBase::CreateHelper*
14067 websocket_stream_create_helper() const {
14068 return websocket_stream_create_helper_;
14069 }
14070
[email protected]e86839fd2013-08-14 18:29:0314071 // Create a new FakeStream and pass it to the request's
14072 // delegate. Returns a weak pointer to the FakeStream.
14073 base::WeakPtr<FakeStream> FinishStreamRequest() {
14074 FakeStream* fake_stream = new FakeStream(priority_);
14075 // Do this before calling OnStreamReady() as OnStreamReady() may
14076 // immediately delete |fake_stream|.
14077 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14078 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14079 return weak_stream;
14080 }
14081
dchengb03027d2014-10-21 12:00:2014082 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714083 ADD_FAILURE();
14084 return ERR_UNEXPECTED;
14085 }
14086
dchengb03027d2014-10-21 12:00:2014087 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714088 ADD_FAILURE();
14089 return LoadState();
14090 }
14091
dchengb03027d2014-10-21 12:00:2014092 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714093
dchengb03027d2014-10-21 12:00:2014094 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714095
dchengb03027d2014-10-21 12:00:2014096 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714097
dchengb03027d2014-10-21 12:00:2014098 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714099
ttuttle1f2d7e92015-04-28 16:17:4714100 const ConnectionAttempts& connection_attempts() const override {
14101 static ConnectionAttempts no_attempts;
14102 return no_attempts;
14103 }
14104
[email protected]bf828982013-08-14 18:01:4714105 private:
14106 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314107 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414108 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714109
14110 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14111};
14112
14113// Fake HttpStreamFactory that vends FakeStreamRequests.
14114class FakeStreamFactory : public HttpStreamFactory {
14115 public:
14116 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014117 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714118
14119 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14120 // RequestStream() (which may be NULL if it was destroyed already).
14121 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14122 return last_stream_request_;
14123 }
14124
dchengb03027d2014-10-21 12:00:2014125 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14126 RequestPriority priority,
14127 const SSLConfig& server_ssl_config,
14128 const SSLConfig& proxy_ssl_config,
14129 HttpStreamRequest::Delegate* delegate,
14130 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314131 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714132 last_stream_request_ = fake_request->AsWeakPtr();
14133 return fake_request;
14134 }
14135
dchengb03027d2014-10-21 12:00:2014136 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714137 const HttpRequestInfo& info,
14138 RequestPriority priority,
14139 const SSLConfig& server_ssl_config,
14140 const SSLConfig& proxy_ssl_config,
14141 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614142 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1314143 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414144 FakeStreamRequest* fake_request =
14145 new FakeStreamRequest(priority, delegate, create_helper);
14146 last_stream_request_ = fake_request->AsWeakPtr();
14147 return fake_request;
[email protected]bf828982013-08-14 18:01:4714148 }
14149
dchengb03027d2014-10-21 12:00:2014150 void PreconnectStreams(int num_streams,
14151 const HttpRequestInfo& info,
dchengb03027d2014-10-21 12:00:2014152 const SSLConfig& server_ssl_config,
14153 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4714154 ADD_FAILURE();
14155 }
14156
dchengb03027d2014-10-21 12:00:2014157 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714158 ADD_FAILURE();
14159 return NULL;
14160 }
14161
14162 private:
14163 base::WeakPtr<FakeStreamRequest> last_stream_request_;
14164
14165 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
14166};
14167
Adam Rice425cf122015-01-19 06:18:2414168// TODO(ricea): Maybe unify this with the one in
14169// url_request_http_job_unittest.cc ?
14170class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
14171 public:
14172 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
14173 bool using_proxy)
14174 : state_(connection.release(), using_proxy) {}
14175
14176 // Fake implementation of HttpStreamBase methods.
14177 // This ends up being quite "real" because this object has to really send data
14178 // on the mock socket. It might be easier to use the real implementation, but
14179 // the fact that the WebSocket code is not compiled on iOS makes that
14180 // difficult.
14181 int InitializeStream(const HttpRequestInfo* request_info,
14182 RequestPriority priority,
14183 const BoundNetLog& net_log,
14184 const CompletionCallback& callback) override {
14185 state_.Initialize(request_info, priority, net_log, callback);
14186 return OK;
14187 }
14188
14189 int SendRequest(const HttpRequestHeaders& request_headers,
14190 HttpResponseInfo* response,
14191 const CompletionCallback& callback) override {
14192 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
14193 response, callback);
14194 }
14195
14196 int ReadResponseHeaders(const CompletionCallback& callback) override {
14197 return parser()->ReadResponseHeaders(callback);
14198 }
14199
14200 int ReadResponseBody(IOBuffer* buf,
14201 int buf_len,
14202 const CompletionCallback& callback) override {
14203 NOTREACHED();
14204 return ERR_IO_PENDING;
14205 }
14206
14207 void Close(bool not_reusable) override {
14208 if (parser())
14209 parser()->Close(true);
14210 }
14211
14212 bool IsResponseBodyComplete() const override {
14213 NOTREACHED();
14214 return false;
14215 }
14216
Adam Rice425cf122015-01-19 06:18:2414217 bool IsConnectionReused() const override {
14218 NOTREACHED();
14219 return false;
14220 }
14221 void SetConnectionReused() override { NOTREACHED(); }
14222
mmenkebd84c392015-09-02 14:12:3414223 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2414224
sclittle4de1bab92015-09-22 21:28:2414225 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2414226 NOTREACHED();
14227 return 0;
14228 }
14229
sclittlebe1ccf62015-09-02 19:40:3614230 int64_t GetTotalSentBytes() const override {
14231 NOTREACHED();
14232 return 0;
14233 }
14234
Adam Rice425cf122015-01-19 06:18:2414235 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
14236 NOTREACHED();
14237 return false;
14238 }
14239
Adam Ricecb76ac62015-02-20 05:33:2514240 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2414241
14242 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
14243 NOTREACHED();
14244 }
14245
ttuttled9dbc652015-09-29 20:00:5914246 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14247
Adam Rice425cf122015-01-19 06:18:2414248 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
14249
14250 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
14251
14252 UploadProgress GetUploadProgress() const override {
14253 NOTREACHED();
14254 return UploadProgress();
14255 }
14256
14257 HttpStream* RenewStreamForAuth() override {
14258 NOTREACHED();
14259 return nullptr;
14260 }
14261
14262 // Fake implementation of WebSocketHandshakeStreamBase method(s)
14263 scoped_ptr<WebSocketStream> Upgrade() override {
14264 NOTREACHED();
14265 return scoped_ptr<WebSocketStream>();
14266 }
14267
14268 private:
14269 HttpStreamParser* parser() const { return state_.parser(); }
14270 HttpBasicState state_;
14271
14272 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
14273};
14274
[email protected]831e4a32013-11-14 02:14:4414275// TODO(yhirano): Split this class out into a net/websockets file, if it is
14276// worth doing.
14277class FakeWebSocketStreamCreateHelper :
14278 public WebSocketHandshakeStreamBase::CreateHelper {
14279 public:
dchengb03027d2014-10-21 12:00:2014280 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2114281 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1314282 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2414283 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
14284 using_proxy);
[email protected]831e4a32013-11-14 02:14:4414285 }
14286
dchengb03027d2014-10-21 12:00:2014287 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4414288 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1314289 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4414290 NOTREACHED();
14291 return NULL;
14292 };
14293
dchengb03027d2014-10-21 12:00:2014294 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4414295
14296 virtual scoped_ptr<WebSocketStream> Upgrade() {
14297 NOTREACHED();
14298 return scoped_ptr<WebSocketStream>();
14299 }
14300};
14301
[email protected]bf828982013-08-14 18:01:4714302} // namespace
14303
14304// Make sure that HttpNetworkTransaction passes on its priority to its
14305// stream request on start.
14306TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
mmenkee65e7af2015-10-13 17:16:4214307 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14308 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714309 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4414310 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714311
dcheng48459ac22014-08-26 00:46:4114312 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714313
14314 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
14315
14316 HttpRequestInfo request;
14317 TestCompletionCallback callback;
14318 EXPECT_EQ(ERR_IO_PENDING,
14319 trans.Start(&request, callback.callback(), BoundNetLog()));
14320
14321 base::WeakPtr<FakeStreamRequest> fake_request =
14322 fake_factory->last_stream_request();
14323 ASSERT_TRUE(fake_request != NULL);
14324 EXPECT_EQ(LOW, fake_request->priority());
14325}
14326
14327// Make sure that HttpNetworkTransaction passes on its priority
14328// updates to its stream request.
14329TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
mmenkee65e7af2015-10-13 17:16:4214330 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14331 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714332 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4414333 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714334
dcheng48459ac22014-08-26 00:46:4114335 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714336
14337 HttpRequestInfo request;
14338 TestCompletionCallback callback;
14339 EXPECT_EQ(ERR_IO_PENDING,
14340 trans.Start(&request, callback.callback(), BoundNetLog()));
14341
14342 base::WeakPtr<FakeStreamRequest> fake_request =
14343 fake_factory->last_stream_request();
14344 ASSERT_TRUE(fake_request != NULL);
14345 EXPECT_EQ(LOW, fake_request->priority());
14346
14347 trans.SetPriority(LOWEST);
14348 ASSERT_TRUE(fake_request != NULL);
14349 EXPECT_EQ(LOWEST, fake_request->priority());
14350}
14351
[email protected]e86839fd2013-08-14 18:29:0314352// Make sure that HttpNetworkTransaction passes on its priority
14353// updates to its stream.
14354TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
mmenkee65e7af2015-10-13 17:16:4214355 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14356 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0314357 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4414358 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0314359
dcheng48459ac22014-08-26 00:46:4114360 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0314361
14362 HttpRequestInfo request;
14363 TestCompletionCallback callback;
14364 EXPECT_EQ(ERR_IO_PENDING,
14365 trans.Start(&request, callback.callback(), BoundNetLog()));
14366
14367 base::WeakPtr<FakeStreamRequest> fake_request =
14368 fake_factory->last_stream_request();
14369 ASSERT_TRUE(fake_request != NULL);
14370 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
14371 ASSERT_TRUE(fake_stream != NULL);
14372 EXPECT_EQ(LOW, fake_stream->priority());
14373
14374 trans.SetPriority(LOWEST);
14375 EXPECT_EQ(LOWEST, fake_stream->priority());
14376}
14377
[email protected]831e4a32013-11-14 02:14:4414378TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
14379 // The same logic needs to be tested for both ws: and wss: schemes, but this
14380 // test is already parameterised on NextProto, so it uses a loop to verify
14381 // that the different schemes work.
bncce36dca22015-04-21 22:11:2314382 std::string test_cases[] = {"ws://www.example.org/",
14383 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4414384 for (size_t i = 0; i < arraysize(test_cases); ++i) {
mmenkee65e7af2015-10-13 17:16:4214385 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14386 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4414387 FakeStreamFactory* fake_factory = new FakeStreamFactory();
14388 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2314389 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4414390 scoped_ptr<HttpStreamFactory>(fake_factory));
14391
dcheng48459ac22014-08-26 00:46:4114392 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4414393 trans.SetWebSocketHandshakeStreamCreateHelper(
14394 &websocket_stream_create_helper);
14395
14396 HttpRequestInfo request;
14397 TestCompletionCallback callback;
14398 request.method = "GET";
14399 request.url = GURL(test_cases[i]);
14400
14401 EXPECT_EQ(ERR_IO_PENDING,
14402 trans.Start(&request, callback.callback(), BoundNetLog()));
14403
14404 base::WeakPtr<FakeStreamRequest> fake_request =
14405 fake_factory->last_stream_request();
14406 ASSERT_TRUE(fake_request != NULL);
14407 EXPECT_EQ(&websocket_stream_create_helper,
14408 fake_request->websocket_stream_create_helper());
14409 }
14410}
14411
[email protected]043b68c82013-08-22 23:41:5214412// Tests that when a used socket is returned to the SSL socket pool, it's closed
14413// if the transport socket pool is stalled on the global socket limit.
14414TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
14415 ClientSocketPoolManager::set_max_sockets_per_group(
14416 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14417 ClientSocketPoolManager::set_max_sockets_per_pool(
14418 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14419
14420 // Set up SSL request.
14421
14422 HttpRequestInfo ssl_request;
14423 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2314424 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214425
14426 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2314427 MockWrite(
14428 "GET / HTTP/1.1\r\n"
14429 "Host: www.example.org\r\n"
14430 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214431 };
14432 MockRead ssl_reads[] = {
14433 MockRead("HTTP/1.1 200 OK\r\n"),
14434 MockRead("Content-Length: 11\r\n\r\n"),
14435 MockRead("hello world"),
14436 MockRead(SYNCHRONOUS, OK),
14437 };
14438 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
14439 ssl_writes, arraysize(ssl_writes));
14440 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14441
14442 SSLSocketDataProvider ssl(ASYNC, OK);
14443 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14444
14445 // Set up HTTP request.
14446
14447 HttpRequestInfo http_request;
14448 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314449 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214450
14451 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314452 MockWrite(
14453 "GET / HTTP/1.1\r\n"
14454 "Host: www.example.org\r\n"
14455 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214456 };
14457 MockRead http_reads[] = {
14458 MockRead("HTTP/1.1 200 OK\r\n"),
14459 MockRead("Content-Length: 7\r\n\r\n"),
14460 MockRead("falafel"),
14461 MockRead(SYNCHRONOUS, OK),
14462 };
14463 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14464 http_writes, arraysize(http_writes));
14465 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14466
mmenkee65e7af2015-10-13 17:16:4214467 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5214468
14469 // Start the SSL request.
14470 TestCompletionCallback ssl_callback;
14471 scoped_ptr<HttpTransaction> ssl_trans(
14472 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14473 ASSERT_EQ(ERR_IO_PENDING,
14474 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
14475 BoundNetLog()));
14476
14477 // Start the HTTP request. Pool should stall.
14478 TestCompletionCallback http_callback;
14479 scoped_ptr<HttpTransaction> http_trans(
14480 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14481 ASSERT_EQ(ERR_IO_PENDING,
14482 http_trans->Start(&http_request, http_callback.callback(),
14483 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4114484 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214485
14486 // Wait for response from SSL request.
14487 ASSERT_EQ(OK, ssl_callback.WaitForResult());
14488 std::string response_data;
14489 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
14490 EXPECT_EQ("hello world", response_data);
14491
14492 // The SSL socket should automatically be closed, so the HTTP request can
14493 // start.
dcheng48459ac22014-08-26 00:46:4114494 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
14495 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214496
14497 // The HTTP request can now complete.
14498 ASSERT_EQ(OK, http_callback.WaitForResult());
14499 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
14500 EXPECT_EQ("falafel", response_data);
14501
dcheng48459ac22014-08-26 00:46:4114502 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214503}
14504
14505// Tests that when a SSL connection is established but there's no corresponding
14506// request that needs it, the new socket is closed if the transport socket pool
14507// is stalled on the global socket limit.
14508TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
14509 ClientSocketPoolManager::set_max_sockets_per_group(
14510 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14511 ClientSocketPoolManager::set_max_sockets_per_pool(
14512 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14513
14514 // Set up an ssl request.
14515
14516 HttpRequestInfo ssl_request;
14517 ssl_request.method = "GET";
14518 ssl_request.url = GURL("https://www.foopy.com/");
14519
14520 // No data will be sent on the SSL socket.
14521 StaticSocketDataProvider ssl_data;
14522 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14523
14524 SSLSocketDataProvider ssl(ASYNC, OK);
14525 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14526
14527 // Set up HTTP request.
14528
14529 HttpRequestInfo http_request;
14530 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314531 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214532
14533 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314534 MockWrite(
14535 "GET / HTTP/1.1\r\n"
14536 "Host: www.example.org\r\n"
14537 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214538 };
14539 MockRead http_reads[] = {
14540 MockRead("HTTP/1.1 200 OK\r\n"),
14541 MockRead("Content-Length: 7\r\n\r\n"),
14542 MockRead("falafel"),
14543 MockRead(SYNCHRONOUS, OK),
14544 };
14545 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14546 http_writes, arraysize(http_writes));
14547 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14548
mmenkee65e7af2015-10-13 17:16:4214549 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5214550
14551 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
14552 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2914553 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
14554 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5214555 session->ssl_config_service()->GetSSLConfig(&ssl_config);
mmenked1205bd2015-07-15 22:26:3514556 http_stream_factory->PreconnectStreams(1, ssl_request, ssl_config,
14557 ssl_config);
dcheng48459ac22014-08-26 00:46:4114558 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214559
14560 // Start the HTTP request. Pool should stall.
14561 TestCompletionCallback http_callback;
14562 scoped_ptr<HttpTransaction> http_trans(
14563 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14564 ASSERT_EQ(ERR_IO_PENDING,
14565 http_trans->Start(&http_request, http_callback.callback(),
14566 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4114567 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214568
14569 // The SSL connection will automatically be closed once the connection is
14570 // established, to let the HTTP request start.
14571 ASSERT_EQ(OK, http_callback.WaitForResult());
14572 std::string response_data;
14573 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
14574 EXPECT_EQ("falafel", response_data);
14575
dcheng48459ac22014-08-26 00:46:4114576 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214577}
14578
[email protected]02d74a02014-04-23 18:10:5414579TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
14580 ScopedVector<UploadElementReader> element_readers;
14581 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714582 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414583
14584 HttpRequestInfo request;
14585 request.method = "POST";
14586 request.url = GURL("http://www.foo.com/");
14587 request.upload_data_stream = &upload_data_stream;
14588 request.load_flags = 0;
14589
mmenkee65e7af2015-10-13 17:16:4214590 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414591 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114592 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414593 // Send headers successfully, but get an error while sending the body.
14594 MockWrite data_writes[] = {
14595 MockWrite("POST / HTTP/1.1\r\n"
14596 "Host: www.foo.com\r\n"
14597 "Connection: keep-alive\r\n"
14598 "Content-Length: 3\r\n\r\n"),
14599 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14600 };
14601
14602 MockRead data_reads[] = {
14603 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14604 MockRead("hello world"),
14605 MockRead(SYNCHRONOUS, OK),
14606 };
14607 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14608 arraysize(data_writes));
14609 session_deps_.socket_factory->AddSocketDataProvider(&data);
14610
14611 TestCompletionCallback callback;
14612
14613 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14614 EXPECT_EQ(ERR_IO_PENDING, rv);
14615
14616 rv = callback.WaitForResult();
14617 EXPECT_EQ(OK, rv);
14618
14619 const HttpResponseInfo* response = trans->GetResponseInfo();
14620 ASSERT_TRUE(response != NULL);
14621
14622 EXPECT_TRUE(response->headers.get() != NULL);
14623 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14624
14625 std::string response_data;
14626 rv = ReadTransaction(trans.get(), &response_data);
14627 EXPECT_EQ(OK, rv);
14628 EXPECT_EQ("hello world", response_data);
14629}
14630
14631// This test makes sure the retry logic doesn't trigger when reading an error
14632// response from a server that rejected a POST with a CONNECTION_RESET.
14633TEST_P(HttpNetworkTransactionTest,
14634 PostReadsErrorResponseAfterResetOnReusedSocket) {
mmenkee65e7af2015-10-13 17:16:4214635 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414636 MockWrite data_writes[] = {
14637 MockWrite("GET / HTTP/1.1\r\n"
14638 "Host: www.foo.com\r\n"
14639 "Connection: keep-alive\r\n\r\n"),
14640 MockWrite("POST / HTTP/1.1\r\n"
14641 "Host: www.foo.com\r\n"
14642 "Connection: keep-alive\r\n"
14643 "Content-Length: 3\r\n\r\n"),
14644 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14645 };
14646
14647 MockRead data_reads[] = {
14648 MockRead("HTTP/1.1 200 Peachy\r\n"
14649 "Content-Length: 14\r\n\r\n"),
14650 MockRead("first response"),
14651 MockRead("HTTP/1.1 400 Not OK\r\n"
14652 "Content-Length: 15\r\n\r\n"),
14653 MockRead("second response"),
14654 MockRead(SYNCHRONOUS, OK),
14655 };
14656 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14657 arraysize(data_writes));
14658 session_deps_.socket_factory->AddSocketDataProvider(&data);
14659
14660 TestCompletionCallback callback;
14661 HttpRequestInfo request1;
14662 request1.method = "GET";
14663 request1.url = GURL("http://www.foo.com/");
14664 request1.load_flags = 0;
14665
14666 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4114667 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414668 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
14669 EXPECT_EQ(ERR_IO_PENDING, rv);
14670
14671 rv = callback.WaitForResult();
14672 EXPECT_EQ(OK, rv);
14673
14674 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
14675 ASSERT_TRUE(response1 != NULL);
14676
14677 EXPECT_TRUE(response1->headers.get() != NULL);
14678 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
14679
14680 std::string response_data1;
14681 rv = ReadTransaction(trans1.get(), &response_data1);
14682 EXPECT_EQ(OK, rv);
14683 EXPECT_EQ("first response", response_data1);
14684 // Delete the transaction to release the socket back into the socket pool.
14685 trans1.reset();
14686
14687 ScopedVector<UploadElementReader> element_readers;
14688 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714689 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414690
14691 HttpRequestInfo request2;
14692 request2.method = "POST";
14693 request2.url = GURL("http://www.foo.com/");
14694 request2.upload_data_stream = &upload_data_stream;
14695 request2.load_flags = 0;
14696
14697 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4114698 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414699 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
14700 EXPECT_EQ(ERR_IO_PENDING, rv);
14701
14702 rv = callback.WaitForResult();
14703 EXPECT_EQ(OK, rv);
14704
14705 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
14706 ASSERT_TRUE(response2 != NULL);
14707
14708 EXPECT_TRUE(response2->headers.get() != NULL);
14709 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
14710
14711 std::string response_data2;
14712 rv = ReadTransaction(trans2.get(), &response_data2);
14713 EXPECT_EQ(OK, rv);
14714 EXPECT_EQ("second response", response_data2);
14715}
14716
14717TEST_P(HttpNetworkTransactionTest,
14718 PostReadsErrorResponseAfterResetPartialBodySent) {
14719 ScopedVector<UploadElementReader> element_readers;
14720 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714721 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414722
14723 HttpRequestInfo request;
14724 request.method = "POST";
14725 request.url = GURL("http://www.foo.com/");
14726 request.upload_data_stream = &upload_data_stream;
14727 request.load_flags = 0;
14728
mmenkee65e7af2015-10-13 17:16:4214729 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414730 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114731 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414732 // Send headers successfully, but get an error while sending the body.
14733 MockWrite data_writes[] = {
14734 MockWrite("POST / HTTP/1.1\r\n"
14735 "Host: www.foo.com\r\n"
14736 "Connection: keep-alive\r\n"
14737 "Content-Length: 3\r\n\r\n"
14738 "fo"),
14739 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14740 };
14741
14742 MockRead data_reads[] = {
14743 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14744 MockRead("hello world"),
14745 MockRead(SYNCHRONOUS, OK),
14746 };
14747 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14748 arraysize(data_writes));
14749 session_deps_.socket_factory->AddSocketDataProvider(&data);
14750
14751 TestCompletionCallback callback;
14752
14753 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14754 EXPECT_EQ(ERR_IO_PENDING, rv);
14755
14756 rv = callback.WaitForResult();
14757 EXPECT_EQ(OK, rv);
14758
14759 const HttpResponseInfo* response = trans->GetResponseInfo();
14760 ASSERT_TRUE(response != NULL);
14761
14762 EXPECT_TRUE(response->headers.get() != NULL);
14763 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14764
14765 std::string response_data;
14766 rv = ReadTransaction(trans.get(), &response_data);
14767 EXPECT_EQ(OK, rv);
14768 EXPECT_EQ("hello world", response_data);
14769}
14770
14771// This tests the more common case than the previous test, where headers and
14772// body are not merged into a single request.
14773TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
14774 ScopedVector<UploadElementReader> element_readers;
14775 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714776 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5414777
14778 HttpRequestInfo request;
14779 request.method = "POST";
14780 request.url = GURL("http://www.foo.com/");
14781 request.upload_data_stream = &upload_data_stream;
14782 request.load_flags = 0;
14783
mmenkee65e7af2015-10-13 17:16:4214784 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414785 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114786 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414787 // Send headers successfully, but get an error while sending the body.
14788 MockWrite data_writes[] = {
14789 MockWrite("POST / HTTP/1.1\r\n"
14790 "Host: www.foo.com\r\n"
14791 "Connection: keep-alive\r\n"
14792 "Transfer-Encoding: chunked\r\n\r\n"),
14793 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14794 };
14795
14796 MockRead data_reads[] = {
14797 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14798 MockRead("hello world"),
14799 MockRead(SYNCHRONOUS, OK),
14800 };
14801 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14802 arraysize(data_writes));
14803 session_deps_.socket_factory->AddSocketDataProvider(&data);
14804
14805 TestCompletionCallback callback;
14806
14807 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14808 EXPECT_EQ(ERR_IO_PENDING, rv);
14809 // Make sure the headers are sent before adding a chunk. This ensures that
14810 // they can't be merged with the body in a single send. Not currently
14811 // necessary since a chunked body is never merged with headers, but this makes
14812 // the test more future proof.
14813 base::RunLoop().RunUntilIdle();
14814
mmenkecbc2b712014-10-09 20:29:0714815 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5414816
14817 rv = callback.WaitForResult();
14818 EXPECT_EQ(OK, rv);
14819
14820 const HttpResponseInfo* response = trans->GetResponseInfo();
14821 ASSERT_TRUE(response != NULL);
14822
14823 EXPECT_TRUE(response->headers.get() != NULL);
14824 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14825
14826 std::string response_data;
14827 rv = ReadTransaction(trans.get(), &response_data);
14828 EXPECT_EQ(OK, rv);
14829 EXPECT_EQ("hello world", response_data);
14830}
14831
14832TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
14833 ScopedVector<UploadElementReader> element_readers;
14834 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714835 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414836
14837 HttpRequestInfo request;
14838 request.method = "POST";
14839 request.url = GURL("http://www.foo.com/");
14840 request.upload_data_stream = &upload_data_stream;
14841 request.load_flags = 0;
14842
mmenkee65e7af2015-10-13 17:16:4214843 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414844 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114845 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414846
14847 MockWrite data_writes[] = {
14848 MockWrite("POST / HTTP/1.1\r\n"
14849 "Host: www.foo.com\r\n"
14850 "Connection: keep-alive\r\n"
14851 "Content-Length: 3\r\n\r\n"),
14852 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14853 };
14854
14855 MockRead data_reads[] = {
14856 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14857 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14858 MockRead("hello world"),
14859 MockRead(SYNCHRONOUS, OK),
14860 };
14861 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14862 arraysize(data_writes));
14863 session_deps_.socket_factory->AddSocketDataProvider(&data);
14864
14865 TestCompletionCallback callback;
14866
14867 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14868 EXPECT_EQ(ERR_IO_PENDING, rv);
14869
14870 rv = callback.WaitForResult();
14871 EXPECT_EQ(OK, rv);
14872
14873 const HttpResponseInfo* response = trans->GetResponseInfo();
14874 ASSERT_TRUE(response != NULL);
14875
14876 EXPECT_TRUE(response->headers.get() != NULL);
14877 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14878
14879 std::string response_data;
14880 rv = ReadTransaction(trans.get(), &response_data);
14881 EXPECT_EQ(OK, rv);
14882 EXPECT_EQ("hello world", response_data);
14883}
14884
14885TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
14886 ScopedVector<UploadElementReader> element_readers;
14887 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714888 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414889
14890 HttpRequestInfo request;
14891 request.method = "POST";
14892 request.url = GURL("http://www.foo.com/");
14893 request.upload_data_stream = &upload_data_stream;
14894 request.load_flags = 0;
14895
mmenkee65e7af2015-10-13 17:16:4214896 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414897 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114898 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414899 // Send headers successfully, but get an error while sending the body.
14900 MockWrite data_writes[] = {
14901 MockWrite("POST / HTTP/1.1\r\n"
14902 "Host: www.foo.com\r\n"
14903 "Connection: keep-alive\r\n"
14904 "Content-Length: 3\r\n\r\n"),
14905 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14906 };
14907
14908 MockRead data_reads[] = {
14909 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
14910 MockRead("hello world"),
14911 MockRead(SYNCHRONOUS, OK),
14912 };
14913 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14914 arraysize(data_writes));
14915 session_deps_.socket_factory->AddSocketDataProvider(&data);
14916
14917 TestCompletionCallback callback;
14918
14919 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14920 EXPECT_EQ(ERR_IO_PENDING, rv);
14921
14922 rv = callback.WaitForResult();
14923 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414924}
14925
14926TEST_P(HttpNetworkTransactionTest,
14927 PostIgnoresNonErrorResponseAfterResetAnd100) {
14928 ScopedVector<UploadElementReader> element_readers;
14929 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714930 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414931
14932 HttpRequestInfo request;
14933 request.method = "POST";
14934 request.url = GURL("http://www.foo.com/");
14935 request.upload_data_stream = &upload_data_stream;
14936 request.load_flags = 0;
14937
mmenkee65e7af2015-10-13 17:16:4214938 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414939 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114940 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414941 // Send headers successfully, but get an error while sending the body.
14942 MockWrite data_writes[] = {
14943 MockWrite("POST / HTTP/1.1\r\n"
14944 "Host: www.foo.com\r\n"
14945 "Connection: keep-alive\r\n"
14946 "Content-Length: 3\r\n\r\n"),
14947 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14948 };
14949
14950 MockRead data_reads[] = {
14951 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14952 MockRead("HTTP/1.0 302 Redirect\r\n"),
14953 MockRead("Location: http://somewhere-else.com/\r\n"),
14954 MockRead("Content-Length: 0\r\n\r\n"),
14955 MockRead(SYNCHRONOUS, OK),
14956 };
14957 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14958 arraysize(data_writes));
14959 session_deps_.socket_factory->AddSocketDataProvider(&data);
14960
14961 TestCompletionCallback callback;
14962
14963 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14964 EXPECT_EQ(ERR_IO_PENDING, rv);
14965
14966 rv = callback.WaitForResult();
14967 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414968}
14969
14970TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
14971 ScopedVector<UploadElementReader> element_readers;
14972 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714973 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414974
14975 HttpRequestInfo request;
14976 request.method = "POST";
14977 request.url = GURL("http://www.foo.com/");
14978 request.upload_data_stream = &upload_data_stream;
14979 request.load_flags = 0;
14980
mmenkee65e7af2015-10-13 17:16:4214981 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414982 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114983 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414984 // Send headers successfully, but get an error while sending the body.
14985 MockWrite data_writes[] = {
14986 MockWrite("POST / HTTP/1.1\r\n"
14987 "Host: www.foo.com\r\n"
14988 "Connection: keep-alive\r\n"
14989 "Content-Length: 3\r\n\r\n"),
14990 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14991 };
14992
14993 MockRead data_reads[] = {
14994 MockRead("HTTP 0.9 rocks!"),
14995 MockRead(SYNCHRONOUS, OK),
14996 };
14997 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14998 arraysize(data_writes));
14999 session_deps_.socket_factory->AddSocketDataProvider(&data);
15000
15001 TestCompletionCallback callback;
15002
15003 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15004 EXPECT_EQ(ERR_IO_PENDING, rv);
15005
15006 rv = callback.WaitForResult();
15007 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415008}
15009
15010TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
15011 ScopedVector<UploadElementReader> element_readers;
15012 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0715013 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5415014
15015 HttpRequestInfo request;
15016 request.method = "POST";
15017 request.url = GURL("http://www.foo.com/");
15018 request.upload_data_stream = &upload_data_stream;
15019 request.load_flags = 0;
15020
mmenkee65e7af2015-10-13 17:16:4215021 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415022 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115023 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415024 // Send headers successfully, but get an error while sending the body.
15025 MockWrite data_writes[] = {
15026 MockWrite("POST / HTTP/1.1\r\n"
15027 "Host: www.foo.com\r\n"
15028 "Connection: keep-alive\r\n"
15029 "Content-Length: 3\r\n\r\n"),
15030 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15031 };
15032
15033 MockRead data_reads[] = {
15034 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15035 MockRead(SYNCHRONOUS, OK),
15036 };
15037 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15038 arraysize(data_writes));
15039 session_deps_.socket_factory->AddSocketDataProvider(&data);
15040
15041 TestCompletionCallback callback;
15042
15043 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15044 EXPECT_EQ(ERR_IO_PENDING, rv);
15045
15046 rv = callback.WaitForResult();
15047 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415048}
15049
Adam Rice425cf122015-01-19 06:18:2415050// Verify that proxy headers are not sent to the destination server when
15051// establishing a tunnel for a secure WebSocket connection.
15052TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
15053 HttpRequestInfo request;
15054 request.method = "GET";
bncce36dca22015-04-21 22:11:2315055 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415056 AddWebSocketHeaders(&request.extra_headers);
15057
15058 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315059 session_deps_.proxy_service =
15060 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415061
mmenkee65e7af2015-10-13 17:16:4215062 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415063
15064 // Since a proxy is configured, try to establish a tunnel.
15065 MockWrite data_writes[] = {
15066 MockWrite(
bncce36dca22015-04-21 22:11:2315067 "CONNECT www.example.org:443 HTTP/1.1\r\n"
15068 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415069 "Proxy-Connection: keep-alive\r\n\r\n"),
15070
15071 // After calling trans->RestartWithAuth(), this is the request we should
15072 // be issuing -- the final header line contains the credentials.
15073 MockWrite(
bncce36dca22015-04-21 22:11:2315074 "CONNECT www.example.org:443 HTTP/1.1\r\n"
15075 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415076 "Proxy-Connection: keep-alive\r\n"
15077 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15078
15079 MockWrite(
15080 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315081 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415082 "Connection: Upgrade\r\n"
15083 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315084 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415085 "Sec-WebSocket-Version: 13\r\n"
15086 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
15087 };
15088
15089 // The proxy responds to the connect with a 407, using a persistent
15090 // connection.
15091 MockRead data_reads[] = {
15092 // No credentials.
15093 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15094 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415095 MockRead("Content-Length: 0\r\n"),
15096 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415097
15098 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15099
15100 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15101 MockRead("Upgrade: websocket\r\n"),
15102 MockRead("Connection: Upgrade\r\n"),
15103 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15104 };
15105
15106 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15107 arraysize(data_writes));
15108 session_deps_.socket_factory->AddSocketDataProvider(&data);
15109 SSLSocketDataProvider ssl(ASYNC, OK);
15110 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15111
15112 scoped_ptr<HttpTransaction> trans(
15113 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15114 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15115 trans->SetWebSocketHandshakeStreamCreateHelper(
15116 &websocket_stream_create_helper);
15117
15118 {
15119 TestCompletionCallback callback;
15120
15121 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15122 EXPECT_EQ(ERR_IO_PENDING, rv);
15123
15124 rv = callback.WaitForResult();
15125 EXPECT_EQ(OK, rv);
15126 }
15127
15128 const HttpResponseInfo* response = trans->GetResponseInfo();
15129 ASSERT_TRUE(response);
15130 ASSERT_TRUE(response->headers.get());
15131 EXPECT_EQ(407, response->headers->response_code());
15132
15133 {
15134 TestCompletionCallback callback;
15135
15136 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15137 callback.callback());
15138 EXPECT_EQ(ERR_IO_PENDING, rv);
15139
15140 rv = callback.WaitForResult();
15141 EXPECT_EQ(OK, rv);
15142 }
15143
15144 response = trans->GetResponseInfo();
15145 ASSERT_TRUE(response);
15146 ASSERT_TRUE(response->headers.get());
15147
15148 EXPECT_EQ(101, response->headers->response_code());
15149
15150 trans.reset();
15151 session->CloseAllConnections();
15152}
15153
15154// Verify that proxy headers are not sent to the destination server when
15155// establishing a tunnel for an insecure WebSocket connection.
15156// This requires the authentication info to be injected into the auth cache
15157// due to crbug.com/395064
15158// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
15159TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
15160 HttpRequestInfo request;
15161 request.method = "GET";
bncce36dca22015-04-21 22:11:2315162 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415163 AddWebSocketHeaders(&request.extra_headers);
15164
15165 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315166 session_deps_.proxy_service =
15167 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415168
mmenkee65e7af2015-10-13 17:16:4215169 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415170
15171 MockWrite data_writes[] = {
15172 // Try to establish a tunnel for the WebSocket connection, with
15173 // credentials. Because WebSockets have a separate set of socket pools,
15174 // they cannot and will not use the same TCP/IP connection as the
15175 // preflight HTTP request.
15176 MockWrite(
bncce36dca22015-04-21 22:11:2315177 "CONNECT www.example.org:80 HTTP/1.1\r\n"
15178 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2415179 "Proxy-Connection: keep-alive\r\n"
15180 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15181
15182 MockWrite(
15183 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315184 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415185 "Connection: Upgrade\r\n"
15186 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315187 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415188 "Sec-WebSocket-Version: 13\r\n"
15189 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
15190 };
15191
15192 MockRead data_reads[] = {
15193 // HTTP CONNECT with credentials.
15194 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15195
15196 // WebSocket connection established inside tunnel.
15197 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15198 MockRead("Upgrade: websocket\r\n"),
15199 MockRead("Connection: Upgrade\r\n"),
15200 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15201 };
15202
15203 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15204 arraysize(data_writes));
15205 session_deps_.socket_factory->AddSocketDataProvider(&data);
15206
15207 session->http_auth_cache()->Add(
15208 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
15209 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
15210
15211 scoped_ptr<HttpTransaction> trans(
15212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15213 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15214 trans->SetWebSocketHandshakeStreamCreateHelper(
15215 &websocket_stream_create_helper);
15216
15217 TestCompletionCallback callback;
15218
15219 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15220 EXPECT_EQ(ERR_IO_PENDING, rv);
15221
15222 rv = callback.WaitForResult();
15223 EXPECT_EQ(OK, rv);
15224
15225 const HttpResponseInfo* response = trans->GetResponseInfo();
15226 ASSERT_TRUE(response);
15227 ASSERT_TRUE(response->headers.get());
15228
15229 EXPECT_EQ(101, response->headers->response_code());
15230
15231 trans.reset();
15232 session->CloseAllConnections();
15233}
15234
sclittlefb249892015-09-10 21:33:2215235TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
15236 ScopedVector<UploadElementReader> element_readers;
15237 element_readers.push_back(new UploadBytesElementReader("foo", 3));
15238 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
15239
15240 HttpRequestInfo request;
15241 request.method = "POST";
15242 request.url = GURL("http://www.foo.com/");
15243 request.upload_data_stream = &upload_data_stream;
15244
mmenkee65e7af2015-10-13 17:16:4215245 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2215246 scoped_ptr<HttpTransaction> trans(
15247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15248 MockWrite data_writes[] = {
15249 MockWrite("POST / HTTP/1.1\r\n"
15250 "Host: www.foo.com\r\n"
15251 "Connection: keep-alive\r\n"
15252 "Content-Length: 3\r\n\r\n"),
15253 MockWrite("foo"),
15254 };
15255
15256 MockRead data_reads[] = {
15257 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15258 MockRead(SYNCHRONOUS, OK),
15259 };
15260 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15261 arraysize(data_writes));
15262 session_deps_.socket_factory->AddSocketDataProvider(&data);
15263
15264 TestCompletionCallback callback;
15265
15266 EXPECT_EQ(ERR_IO_PENDING,
15267 trans->Start(&request, callback.callback(), BoundNetLog()));
15268 EXPECT_EQ(OK, callback.WaitForResult());
15269
15270 std::string response_data;
15271 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15272
15273 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15274 trans->GetTotalSentBytes());
15275 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15276 trans->GetTotalReceivedBytes());
15277}
15278
15279TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
15280 ScopedVector<UploadElementReader> element_readers;
15281 element_readers.push_back(new UploadBytesElementReader("foo", 3));
15282 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
15283
15284 HttpRequestInfo request;
15285 request.method = "POST";
15286 request.url = GURL("http://www.foo.com/");
15287 request.upload_data_stream = &upload_data_stream;
15288
mmenkee65e7af2015-10-13 17:16:4215289 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2215290 scoped_ptr<HttpTransaction> trans(
15291 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15292 MockWrite data_writes[] = {
15293 MockWrite("POST / HTTP/1.1\r\n"
15294 "Host: www.foo.com\r\n"
15295 "Connection: keep-alive\r\n"
15296 "Content-Length: 3\r\n\r\n"),
15297 MockWrite("foo"),
15298 };
15299
15300 MockRead data_reads[] = {
15301 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
15302 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15303 MockRead(SYNCHRONOUS, OK),
15304 };
15305 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15306 arraysize(data_writes));
15307 session_deps_.socket_factory->AddSocketDataProvider(&data);
15308
15309 TestCompletionCallback callback;
15310
15311 EXPECT_EQ(ERR_IO_PENDING,
15312 trans->Start(&request, callback.callback(), BoundNetLog()));
15313 EXPECT_EQ(OK, callback.WaitForResult());
15314
15315 std::string response_data;
15316 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15317
15318 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15319 trans->GetTotalSentBytes());
15320 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15321 trans->GetTotalReceivedBytes());
15322}
15323
15324TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
15325 ScopedVector<UploadElementReader> element_readers;
15326 element_readers.push_back(new UploadBytesElementReader("foo", 3));
15327 ChunkedUploadDataStream upload_data_stream(0);
15328
15329 HttpRequestInfo request;
15330 request.method = "POST";
15331 request.url = GURL("http://www.foo.com/");
15332 request.upload_data_stream = &upload_data_stream;
15333
mmenkee65e7af2015-10-13 17:16:4215334 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2215335 scoped_ptr<HttpTransaction> trans(
15336 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15337 // Send headers successfully, but get an error while sending the body.
15338 MockWrite data_writes[] = {
15339 MockWrite("POST / HTTP/1.1\r\n"
15340 "Host: www.foo.com\r\n"
15341 "Connection: keep-alive\r\n"
15342 "Transfer-Encoding: chunked\r\n\r\n"),
15343 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
15344 };
15345
15346 MockRead data_reads[] = {
15347 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15348 MockRead(SYNCHRONOUS, OK),
15349 };
15350 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15351 arraysize(data_writes));
15352 session_deps_.socket_factory->AddSocketDataProvider(&data);
15353
15354 TestCompletionCallback callback;
15355
15356 EXPECT_EQ(ERR_IO_PENDING,
15357 trans->Start(&request, callback.callback(), BoundNetLog()));
15358
15359 base::RunLoop().RunUntilIdle();
15360 upload_data_stream.AppendData("f", 1, false);
15361
15362 base::RunLoop().RunUntilIdle();
15363 upload_data_stream.AppendData("oo", 2, true);
15364
15365 EXPECT_EQ(OK, callback.WaitForResult());
15366
15367 std::string response_data;
15368 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15369
15370 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15371 trans->GetTotalSentBytes());
15372 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15373 trans->GetTotalReceivedBytes());
15374}
15375
[email protected]89ceba9a2009-03-21 03:46:0615376} // namespace net