blob: c2e5c72392c79533084739fa83fdcea0663166aa [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>
danakj1fd259a02016-04-16 03:17:0910
avibf0746c2015-12-09 19:53:1411#include <limits>
danakj1fd259a02016-04-16 03:17:0912#include <memory>
[email protected]5285d972011-10-18 18:56:3413#include <string>
dchengc7eeda422015-12-26 03:56:4814#include <utility>
[email protected]95d88ffe2010-02-04 21:25:3315#include <vector>
[email protected]77848d12008-11-14 00:00:2216
[email protected]68bf9152008-09-25 19:47:3017#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5218#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2919#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5720#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2421#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4622#include "base/macros.h"
danakj1fd259a02016-04-16 03:17:0923#include "base/memory/ptr_util.h"
[email protected]bf828982013-08-14 18:01:4724#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4925#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4726#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0527#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3328#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3529#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3530#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0731#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3332#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0733#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2534#include "net/base/load_timing_info.h"
35#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2436#include "net/base/net_errors.h"
tbansal28e68f82016-02-04 02:56:1537#include "net/base/proxy_delegate.h"
[email protected]ac790b42009-12-02 04:31:3138#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5239#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1540#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0641#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2142#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1143#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1644#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5345#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2446#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1247#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0048#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2949#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1950#include "net/http/http_auth_scheme.h"
Adam Rice425cf122015-01-19 06:18:2451#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5752#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5253#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5654#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2455#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1356#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5357#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5758#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3859#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2460#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1961#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0762#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0063#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5164#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4665#include "net/log/test_net_log_entry.h"
66#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1367#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5368#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0369#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1170#include "net/proxy/proxy_resolver.h"
tbansal28e68f82016-02-04 02:56:1571#include "net/proxy/proxy_server.h"
[email protected]631f1322010-04-30 17:59:1172#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4473#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1574#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0375#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4776#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0277#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0778#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4479#include "net/socket/socket_test_util.h"
80#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5481#include "net/spdy/spdy_framer.h"
82#include "net/spdy/spdy_session.h"
83#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0284#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1485#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5786#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0387#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5788#include "net/ssl/ssl_config_service_defaults.h"
89#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5490#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1191#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0192#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4393#include "net/test/test_data_directory.h"
[email protected]831e4a32013-11-14 02:14:4494#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:1895#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:5296#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1597#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2798#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5299
robpercival214763f2016-07-01 23:27:01100using net::test::IsError;
101using net::test::IsOk;
102
[email protected]ad65a3e2013-12-25 18:18:01103using base::ASCIIToUTF16;
104
initial.commit586acc5fe2008-07-26 22:42:52105//-----------------------------------------------------------------------------
106
ttuttle859dc7a2015-04-23 19:42:29107namespace net {
108
[email protected]13c8a092010-07-29 06:15:44109namespace {
110
[email protected]42cba2fb2013-03-29 19:58:57111const base::string16 kBar(ASCIIToUTF16("bar"));
112const base::string16 kBar2(ASCIIToUTF16("bar2"));
113const base::string16 kBar3(ASCIIToUTF16("bar3"));
114const base::string16 kBaz(ASCIIToUTF16("baz"));
115const base::string16 kFirst(ASCIIToUTF16("first"));
116const base::string16 kFoo(ASCIIToUTF16("foo"));
117const base::string16 kFoo2(ASCIIToUTF16("foo2"));
118const base::string16 kFoo3(ASCIIToUTF16("foo3"));
119const base::string16 kFou(ASCIIToUTF16("fou"));
120const base::string16 kSecond(ASCIIToUTF16("second"));
121const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
122const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44123
bnc2df4b522016-07-08 18:17:43124const char kAlternativeServiceHttpHeader[] =
125 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
126
ttuttle859dc7a2015-04-23 19:42:29127int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
128 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
129 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02130}
131
ttuttle859dc7a2015-04-23 19:42:29132int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
133 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
134 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02135}
136
ttuttle859dc7a2015-04-23 19:42:29137bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
138 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
139 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52140}
141
[email protected]f3da152d2012-06-02 01:00:57142// Takes in a Value created from a NetLogHttpResponseParameter, and returns
143// a JSONified list of headers as a single string. Uses single quotes instead
144// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27145bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57146 if (!params)
147 return false;
[email protected]ea5ef4c2013-06-13 22:50:27148 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57149 if (!params->GetList("headers", &header_list))
150 return false;
151 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34152 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28153 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57154 return true;
155}
156
[email protected]029c83b62013-01-24 05:28:20157// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
158// used.
ttuttle859dc7a2015-04-23 19:42:29159void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20160 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29161 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25162
[email protected]029c83b62013-01-24 05:28:20163 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
164 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
165
ttuttle859dc7a2015-04-23 19:42:29166 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20167 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25168
169 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25170
[email protected]3b23a222013-05-15 21:33:25171 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25172 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
173 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25174 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25175}
176
[email protected]029c83b62013-01-24 05:28:20177// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
178// used.
ttuttle859dc7a2015-04-23 19:42:29179void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25180 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20181 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29182 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20183
184 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
185 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
186
ttuttle859dc7a2015-04-23 19:42:29187 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
188 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20189 EXPECT_LE(load_timing_info.connect_timing.connect_end,
190 load_timing_info.send_start);
191
192 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20193
[email protected]3b23a222013-05-15 21:33:25194 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20195 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
196 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25197 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20198}
199
200// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
201// used.
ttuttle859dc7a2015-04-23 19:42:29202void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20203 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29204 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20205
ttuttle859dc7a2015-04-23 19:42:29206 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20207
208 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
209 EXPECT_LE(load_timing_info.proxy_resolve_start,
210 load_timing_info.proxy_resolve_end);
211 EXPECT_LE(load_timing_info.proxy_resolve_end,
212 load_timing_info.send_start);
213 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20214
[email protected]3b23a222013-05-15 21:33:25215 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20216 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
217 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25218 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20219}
220
221// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
222// used.
ttuttle859dc7a2015-04-23 19:42:29223void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20224 int connect_timing_flags) {
225 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29226 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20227
228 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
229 EXPECT_LE(load_timing_info.proxy_resolve_start,
230 load_timing_info.proxy_resolve_end);
231 EXPECT_LE(load_timing_info.proxy_resolve_end,
232 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29233 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
234 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20235 EXPECT_LE(load_timing_info.connect_timing.connect_end,
236 load_timing_info.send_start);
237
238 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20239
[email protected]3b23a222013-05-15 21:33:25240 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20241 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
242 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25243 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25244}
245
ttuttle859dc7a2015-04-23 19:42:29246void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24247 headers->SetHeader("Connection", "Upgrade");
248 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23249 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24250 headers->SetHeader("Sec-WebSocket-Version", "13");
251 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
252}
253
danakj1fd259a02016-04-16 03:17:09254std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42255 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34256 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14257}
258
[email protected]448d4ca52012-03-04 04:12:23259} // namespace
260
bncd16676a2016-07-20 16:23:01261class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03262 public:
bncd16676a2016-07-20 16:23:01263 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03264 // Important to restore the per-pool limit first, since the pool limit must
265 // always be greater than group limit, and the tests reduce both limits.
266 ClientSocketPoolManager::set_max_sockets_per_pool(
267 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
268 ClientSocketPoolManager::set_max_sockets_per_group(
269 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
270 }
271
[email protected]e3ceb682011-06-28 23:55:46272 protected:
[email protected]23e482282013-06-14 16:08:02273 HttpNetworkTransactionTest()
bncd16676a2016-07-20 16:23:01274 : old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03275 HttpNetworkSession::NORMAL_SOCKET_POOL)),
276 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
277 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bncb26024382016-06-29 02:39:45278 session_deps_.enable_http2_alternative_service_with_different_host = true;
[email protected]483fa202013-05-14 01:07:03279 }
[email protected]bb88e1d32013-05-03 23:11:07280
[email protected]e3ceb682011-06-28 23:55:46281 struct SimpleGetHelperResult {
282 int rv;
283 std::string status_line;
284 std::string response_data;
sclittlefb249892015-09-10 21:33:22285 int64_t total_received_bytes;
286 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25287 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47288 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59289 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46290 };
291
dcheng67be2b1f2014-10-27 21:47:29292 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50293 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55294 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54295 }
296
dcheng67be2b1f2014-10-27 21:47:29297 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50298 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55299 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09300 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55301 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09302 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50303 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55304 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09305 }
306
[email protected]202965992011-12-07 23:04:51307 // Either |write_failure| specifies a write failure or |read_failure|
308 // specifies a read failure when using a reused socket. In either case, the
309 // failure should cause the network transaction to resend the request, and the
310 // other argument should be NULL.
311 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
312 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52313
[email protected]a34f61ee2014-03-18 20:59:49314 // Either |write_failure| specifies a write failure or |read_failure|
315 // specifies a read failure when using a reused socket. In either case, the
316 // failure should cause the network transaction to resend the request, and the
317 // other argument should be NULL.
318 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10319 const MockRead* read_failure,
320 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49321
[email protected]5a60c8b2011-10-19 20:14:29322 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
323 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15324 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52325
[email protected]ff007e162009-05-23 09:13:15326 HttpRequestInfo request;
327 request.method = "GET";
bncce36dca22015-04-21 22:11:23328 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15329 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52330
vishal.b62985ca92015-04-17 08:45:51331 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07332 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09333 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16334 HttpNetworkTransaction trans(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());
bnc691fda62016-08-12 00:43:16343 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01344 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52345
[email protected]ff007e162009-05-23 09:13:15346 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16347 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.
bnc691fda62016-08-12 00:43:16352 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25353 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
bnc691fda62016-08-12 00:43:16358 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.
wezca1070932016-05-26 20:30:52361 if (!response || !response->headers) {
[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 =
bnc691fda62016-08-12 00:43:16371 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59372 EXPECT_EQ(got_endpoint,
373 out.remote_endpoint_after_start.address().size() > 0);
374
bnc691fda62016-08-12 00:43:16375 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01376 EXPECT_THAT(rv, IsOk());
[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(
mikecirone8b85c432016-09-08 19:11:00381 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
382 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39383 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00384 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
385 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15386
[email protected]f3da152d2012-06-02 01:00:57387 std::string line;
388 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
389 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
390
[email protected]79e1fd62013-06-20 06:50:04391 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16392 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04393 std::string value;
394 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23395 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04396 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
397 EXPECT_EQ("keep-alive", value);
398
399 std::string response_headers;
400 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23401 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04402 response_headers);
[email protected]3deb9a52010-11-11 00:24:40403
bnc691fda62016-08-12 00:43:16404 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22405 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16406 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22407
bnc691fda62016-08-12 00:43:16408 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47409 return out;
[email protected]ff007e162009-05-23 09:13:15410 }
initial.commit586acc5fe2008-07-26 22:42:52411
[email protected]5a60c8b2011-10-19 20:14:29412 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
413 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22414 MockWrite data_writes[] = {
415 MockWrite("GET / HTTP/1.1\r\n"
416 "Host: www.example.org\r\n"
417 "Connection: keep-alive\r\n\r\n"),
418 };
[email protected]5a60c8b2011-10-19 20:14:29419
sclittlefb249892015-09-10 21:33:22420 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
421 arraysize(data_writes));
422 StaticSocketDataProvider* data[] = {&reads};
423 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
424
425 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
426 out.total_sent_bytes);
427 return out;
[email protected]b8015c42013-12-24 15:18:19428 }
429
[email protected]ff007e162009-05-23 09:13:15430 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
431 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52432
[email protected]ff007e162009-05-23 09:13:15433 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07434
435 void BypassHostCacheOnRefreshHelper(int load_flags);
436
437 void CheckErrorIsPassedBack(int error, IoMode mode);
438
[email protected]4bd46222013-05-14 19:32:23439 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07440 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03441
442 // Original socket limits. Some tests set these. Safest to always restore
443 // them once each test has been run.
444 int old_max_group_sockets_;
445 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15446};
[email protected]231d5a32008-09-13 00:45:27447
[email protected]448d4ca52012-03-04 04:12:23448namespace {
449
ryansturm49a8cb12016-06-15 16:51:09450class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27451 public:
ryansturm49a8cb12016-06-15 16:51:09452 BeforeHeadersSentHandler()
453 : observed_before_headers_sent_with_proxy_(false),
454 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27455
ryansturm49a8cb12016-06-15 16:51:09456 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
457 HttpRequestHeaders* request_headers) {
458 observed_before_headers_sent_ = true;
459 if (!proxy_info.is_http() && !proxy_info.is_https() &&
460 !proxy_info.is_quic()) {
461 return;
462 }
463 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27464 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
465 }
466
ryansturm49a8cb12016-06-15 16:51:09467 bool observed_before_headers_sent_with_proxy() const {
468 return observed_before_headers_sent_with_proxy_;
469 }
470
471 bool observed_before_headers_sent() const {
472 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27473 }
474
475 std::string observed_proxy_server_uri() const {
476 return observed_proxy_server_uri_;
477 }
478
479 private:
ryansturm49a8cb12016-06-15 16:51:09480 bool observed_before_headers_sent_with_proxy_;
481 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27482 std::string observed_proxy_server_uri_;
483
ryansturm49a8cb12016-06-15 16:51:09484 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27485};
486
[email protected]15a5ccf82008-10-23 19:57:43487// Fill |str| with a long header list that consumes >= |size| bytes.
488void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51489 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19490 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
491 const int sizeof_row = strlen(row);
492 const int num_rows = static_cast<int>(
493 ceil(static_cast<float>(size) / sizeof_row));
494 const int sizeof_data = num_rows * sizeof_row;
495 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43496 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51497
[email protected]4ddaf2502008-10-23 18:26:19498 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43499 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19500}
501
thakis84dff942015-07-28 20:47:38502#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29503// Alternative functions that eliminate randomness and dependency on the local
504// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14505void MockGenerateRandom1(uint8_t* output, size_t n) {
506 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
507 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29508 static size_t current_byte = 0;
509 for (size_t i = 0; i < n; ++i) {
510 output[i] = bytes[current_byte++];
511 current_byte %= arraysize(bytes);
512 }
513}
514
avibf0746c2015-12-09 19:53:14515void MockGenerateRandom2(uint8_t* output, size_t n) {
516 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
517 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
518 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29519 static size_t current_byte = 0;
520 for (size_t i = 0; i < n; ++i) {
521 output[i] = bytes[current_byte++];
522 current_byte %= arraysize(bytes);
523 }
524}
525
[email protected]fe2bc6a2009-03-23 16:52:20526std::string MockGetHostName() {
527 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29528}
thakis84dff942015-07-28 20:47:38529#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29530
[email protected]e60e47a2010-07-14 03:37:18531template<typename ParentPool>
532class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31533 public:
[email protected]9e1bdd32011-02-03 21:48:34534 CaptureGroupNameSocketPool(HostResolver* host_resolver,
535 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18536
[email protected]d80a4322009-08-14 07:07:49537 const std::string last_group_name_received() const {
538 return last_group_name_;
539 }
540
dmichaeld6e570d2014-12-18 22:30:57541 int RequestSocket(const std::string& group_name,
542 const void* socket_params,
543 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15544 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57545 ClientSocketHandle* handle,
546 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20547 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31548 last_group_name_ = group_name;
549 return ERR_IO_PENDING;
550 }
dmichaeld6e570d2014-12-18 22:30:57551 void CancelRequest(const std::string& group_name,
552 ClientSocketHandle* handle) override {}
553 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09554 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57555 int id) override {}
556 void CloseIdleSockets() override {}
557 int IdleSocketCount() const override { return 0; }
558 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31559 return 0;
560 }
dmichaeld6e570d2014-12-18 22:30:57561 LoadState GetLoadState(const std::string& group_name,
562 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31563 return LOAD_STATE_IDLE;
564 }
dmichaeld6e570d2014-12-18 22:30:57565 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26566 return base::TimeDelta();
567 }
[email protected]d80a4322009-08-14 07:07:49568
569 private:
[email protected]04e5be32009-06-26 20:00:31570 std::string last_group_name_;
571};
572
[email protected]ab739042011-04-07 15:22:28573typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
574CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13575typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
576CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06577typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11578CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18579typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
580CaptureGroupNameSSLSocketPool;
581
rkaplowd90695c2015-03-25 22:12:41582template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18583CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34584 HostResolver* host_resolver,
585 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21586 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18587
hashimoto0d3e4fb2015-01-09 05:02:50588template <>
[email protected]2df19bb2010-08-25 20:13:46589CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21590 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34591 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41592 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50593}
[email protected]2df19bb2010-08-25 20:13:46594
[email protected]007b3f82013-04-09 08:46:45595template <>
[email protected]e60e47a2010-07-14 03:37:18596CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21597 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34598 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45599 : SSLClientSocketPool(0,
600 0,
[email protected]007b3f82013-04-09 08:46:45601 cert_verifier,
602 NULL,
603 NULL,
[email protected]284303b62013-11-28 15:11:54604 NULL,
eranm6571b2b2014-12-03 15:53:23605 NULL,
[email protected]007b3f82013-04-09 08:46:45606 std::string(),
607 NULL,
608 NULL,
609 NULL,
610 NULL,
611 NULL,
[email protected]8e458552014-08-05 00:02:15612 NULL) {
613}
[email protected]2227c692010-05-04 15:36:11614
[email protected]231d5a32008-09-13 00:45:27615//-----------------------------------------------------------------------------
616
[email protected]79cb5c12011-09-12 13:12:04617// Helper functions for validating that AuthChallengeInfo's are correctly
618// configured for common cases.
619bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
620 if (!auth_challenge)
621 return false;
622 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43623 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04624 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19625 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04626 return true;
627}
628
629bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
630 if (!auth_challenge)
631 return false;
632 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43633 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
634 EXPECT_EQ("MyRealm1", auth_challenge->realm);
635 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
636 return true;
637}
638
639bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
640 if (!auth_challenge)
641 return false;
642 EXPECT_TRUE(auth_challenge->is_proxy);
643 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04644 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19645 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04646 return true;
647}
648
649bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
650 if (!auth_challenge)
651 return false;
652 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43653 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04654 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19655 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04656 return true;
657}
658
thakis84dff942015-07-28 20:47:38659#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04660bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
661 if (!auth_challenge)
662 return false;
663 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43664 EXPECT_EQ("http://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04665 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19666 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04667 return true;
668}
thakis84dff942015-07-28 20:47:38669#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04670
[email protected]448d4ca52012-03-04 04:12:23671} // namespace
672
bncd16676a2016-07-20 16:23:01673TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09674 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16675 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27676}
677
bncd16676a2016-07-20 16:23:01678TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27679 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35680 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
681 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06682 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27683 };
[email protected]31a2bfe2010-02-09 08:03:39684 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
685 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01686 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27687 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
688 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22689 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
690 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47691 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59692
693 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27694}
695
696// Response with no status line.
bncd16676a2016-07-20 16:23:01697TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27698 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35699 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06700 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27701 };
[email protected]31a2bfe2010-02-09 08:03:39702 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
703 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41704 EXPECT_THAT(out.rv, IsOk());
705 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
706 EXPECT_EQ("hello world", out.response_data);
707 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
708 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27709}
710
mmenkea7da6da2016-09-01 21:56:52711// Response with no status line, and a weird port. Should fail by default.
712TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
713 MockRead data_reads[] = {
714 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
715 };
716
717 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
718 session_deps_.socket_factory->AddSocketDataProvider(&data);
719
720 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
721
722 std::unique_ptr<HttpTransaction> trans(
723 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
724
725 HttpRequestInfo request;
726 request.method = "GET";
727 request.url = GURL("http://www.example.com:2000/");
728 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20729 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52730 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
731}
732
733// Response with no status line, and a weird port. Option to allow weird ports
734// enabled.
735TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
736 MockRead data_reads[] = {
737 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
738 };
739
740 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
741 session_deps_.socket_factory->AddSocketDataProvider(&data);
742 session_deps_.http_09_on_non_default_ports_enabled = true;
743 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
744
745 std::unique_ptr<HttpTransaction> trans(
746 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
747
748 HttpRequestInfo request;
749 request.method = "GET";
750 request.url = GURL("http://www.example.com:2000/");
751 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20752 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52753 EXPECT_THAT(callback.GetResult(rv), IsOk());
754
755 const HttpResponseInfo* info = trans->GetResponseInfo();
756 ASSERT_TRUE(info->headers);
757 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
758
759 // Don't bother to read the body - that's verified elsewhere, important thing
760 // is that the option to allow HTTP/0.9 on non-default ports is respected.
761}
762
[email protected]231d5a32008-09-13 00:45:27763// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01764TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27765 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35766 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06767 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27768 };
[email protected]31a2bfe2010-02-09 08:03:39769 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
770 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01771 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27772 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
773 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22774 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
775 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27776}
777
778// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01779TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27780 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35781 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06782 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27783 };
[email protected]31a2bfe2010-02-09 08:03:39784 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
785 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01786 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27787 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
788 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22789 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
790 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27791}
792
793// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01794TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27795 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35796 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06797 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27798 };
[email protected]31a2bfe2010-02-09 08:03:39799 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
800 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41801 EXPECT_THAT(out.rv, IsOk());
802 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
803 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
804 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
805 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27806}
807
808// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01809TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27810 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35811 MockRead("\n"),
812 MockRead("\n"),
813 MockRead("Q"),
814 MockRead("J"),
815 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06816 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27817 };
[email protected]31a2bfe2010-02-09 08:03:39818 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
819 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01820 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27821 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
822 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22823 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
824 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27825}
826
827// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01828TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27829 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35830 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06831 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27832 };
[email protected]31a2bfe2010-02-09 08:03:39833 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
834 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41835 EXPECT_THAT(out.rv, IsOk());
836 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
837 EXPECT_EQ("HTT", out.response_data);
838 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
839 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52840}
841
[email protected]f9d44aa2008-09-23 23:57:17842// Simulate a 204 response, lacking a Content-Length header, sent over a
843// persistent connection. The response should still terminate since a 204
844// cannot have a response body.
bncd16676a2016-07-20 16:23:01845TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19846 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17847 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35848 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19849 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06850 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17851 };
[email protected]31a2bfe2010-02-09 08:03:39852 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
853 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01854 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17855 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
856 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22857 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
858 int64_t response_size = reads_size - strlen(junk);
859 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17860}
861
[email protected]0877e3d2009-10-17 22:29:57862// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01863TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19864 std::string final_chunk = "0\r\n\r\n";
865 std::string extra_data = "HTTP/1.1 200 OK\r\n";
866 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57867 MockRead data_reads[] = {
868 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
869 MockRead("5\r\nHello\r\n"),
870 MockRead("1\r\n"),
871 MockRead(" \r\n"),
872 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19873 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06874 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57875 };
[email protected]31a2bfe2010-02-09 08:03:39876 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
877 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01878 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:57879 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
880 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22881 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
882 int64_t response_size = reads_size - extra_data.size();
883 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57884}
885
[email protected]9fe44f52010-09-23 18:36:00886// Next tests deal with http://crbug.com/56344.
887
bncd16676a2016-07-20 16:23:01888TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00889 MultipleContentLengthHeadersNoTransferEncoding) {
890 MockRead data_reads[] = {
891 MockRead("HTTP/1.1 200 OK\r\n"),
892 MockRead("Content-Length: 10\r\n"),
893 MockRead("Content-Length: 5\r\n\r\n"),
894 };
895 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
896 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01897 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:00898}
899
bncd16676a2016-07-20 16:23:01900TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04901 DuplicateContentLengthHeadersNoTransferEncoding) {
902 MockRead data_reads[] = {
903 MockRead("HTTP/1.1 200 OK\r\n"),
904 MockRead("Content-Length: 5\r\n"),
905 MockRead("Content-Length: 5\r\n\r\n"),
906 MockRead("Hello"),
907 };
908 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
909 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01910 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:04911 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
912 EXPECT_EQ("Hello", out.response_data);
913}
914
bncd16676a2016-07-20 16:23:01915TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04916 ComplexContentLengthHeadersNoTransferEncoding) {
917 // More than 2 dupes.
918 {
919 MockRead data_reads[] = {
920 MockRead("HTTP/1.1 200 OK\r\n"),
921 MockRead("Content-Length: 5\r\n"),
922 MockRead("Content-Length: 5\r\n"),
923 MockRead("Content-Length: 5\r\n\r\n"),
924 MockRead("Hello"),
925 };
926 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
927 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01928 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:04929 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
930 EXPECT_EQ("Hello", out.response_data);
931 }
932 // HTTP/1.0
933 {
934 MockRead data_reads[] = {
935 MockRead("HTTP/1.0 200 OK\r\n"),
936 MockRead("Content-Length: 5\r\n"),
937 MockRead("Content-Length: 5\r\n"),
938 MockRead("Content-Length: 5\r\n\r\n"),
939 MockRead("Hello"),
940 };
941 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
942 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01943 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:04944 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
945 EXPECT_EQ("Hello", out.response_data);
946 }
947 // 2 dupes and one mismatched.
948 {
949 MockRead data_reads[] = {
950 MockRead("HTTP/1.1 200 OK\r\n"),
951 MockRead("Content-Length: 10\r\n"),
952 MockRead("Content-Length: 10\r\n"),
953 MockRead("Content-Length: 5\r\n\r\n"),
954 };
955 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
956 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01957 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:04958 }
959}
960
bncd16676a2016-07-20 16:23:01961TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00962 MultipleContentLengthHeadersTransferEncoding) {
963 MockRead data_reads[] = {
964 MockRead("HTTP/1.1 200 OK\r\n"),
965 MockRead("Content-Length: 666\r\n"),
966 MockRead("Content-Length: 1337\r\n"),
967 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
968 MockRead("5\r\nHello\r\n"),
969 MockRead("1\r\n"),
970 MockRead(" \r\n"),
971 MockRead("5\r\nworld\r\n"),
972 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06973 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00974 };
975 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
976 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01977 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:00978 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
979 EXPECT_EQ("Hello world", out.response_data);
980}
981
[email protected]1628fe92011-10-04 23:04:55982// Next tests deal with http://crbug.com/98895.
983
984// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:01985TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55986 MockRead data_reads[] = {
987 MockRead("HTTP/1.1 200 OK\r\n"),
988 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
989 MockRead("Content-Length: 5\r\n\r\n"),
990 MockRead("Hello"),
991 };
992 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
993 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01994 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:55995 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
996 EXPECT_EQ("Hello", out.response_data);
997}
998
[email protected]54a9c6e52012-03-21 20:10:59999// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011000TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551001 MockRead data_reads[] = {
1002 MockRead("HTTP/1.1 200 OK\r\n"),
1003 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1004 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1005 MockRead("Content-Length: 5\r\n\r\n"),
1006 MockRead("Hello"),
1007 };
1008 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1009 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011010 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591011 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1012 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551013}
1014
1015// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011016TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551017 MockRead data_reads[] = {
1018 MockRead("HTTP/1.1 200 OK\r\n"),
1019 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1020 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1021 MockRead("Content-Length: 5\r\n\r\n"),
1022 MockRead("Hello"),
1023 };
1024 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1025 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011026 EXPECT_THAT(out.rv,
1027 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551028}
1029
[email protected]54a9c6e52012-03-21 20:10:591030// Checks that two identical Location headers result in no error.
1031// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011032TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551033 MockRead data_reads[] = {
1034 MockRead("HTTP/1.1 302 Redirect\r\n"),
1035 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591036 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551037 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061038 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551039 };
1040
1041 HttpRequestInfo request;
1042 request.method = "GET";
1043 request.url = GURL("http://redirect.com/");
1044 request.load_flags = 0;
1045
danakj1fd259a02016-04-16 03:17:091046 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161047 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551048
1049 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071050 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551051
[email protected]49639fa2011-12-20 23:22:411052 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551053
tfarina42834112016-09-22 13:38:201054 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551056
robpercival214763f2016-07-01 23:27:011057 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551058
bnc691fda62016-08-12 00:43:161059 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521060 ASSERT_TRUE(response);
1061 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551062 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1063 std::string url;
1064 EXPECT_TRUE(response->headers->IsRedirect(&url));
1065 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:151066 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:551067}
1068
[email protected]1628fe92011-10-04 23:04:551069// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011070TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551071 MockRead data_reads[] = {
1072 MockRead("HTTP/1.1 302 Redirect\r\n"),
1073 MockRead("Location: http://good.com/\r\n"),
1074 MockRead("Location: http://evil.com/\r\n"),
1075 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061076 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551077 };
1078 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1079 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011080 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551081}
1082
[email protected]ef0faf2e72009-03-05 23:27:231083// Do a request using the HEAD method. Verify that we don't try to read the
1084// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011085TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421086 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231087 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231088 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231089 request.load_flags = 0;
1090
danakj1fd259a02016-04-16 03:17:091091 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161092 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091093 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161094 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091095 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1096 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271097
[email protected]ef0faf2e72009-03-05 23:27:231098 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131099 MockWrite("HEAD / HTTP/1.1\r\n"
1100 "Host: www.example.org\r\n"
1101 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231102 };
1103 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231104 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1105 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231106
mmenked39192ee2015-12-09 00:57:231107 // No response body because the test stops reading here.
1108 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231109 };
1110
[email protected]31a2bfe2010-02-09 08:03:391111 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1112 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071113 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231114
[email protected]49639fa2011-12-20 23:22:411115 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231116
tfarina42834112016-09-22 13:38:201117 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231119
1120 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011121 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231122
bnc691fda62016-08-12 00:43:161123 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521124 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231125
1126 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521127 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231128 EXPECT_EQ(1234, response->headers->GetContentLength());
1129 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151130 EXPECT_TRUE(response->proxy_server.IsEmpty());
ryansturm49a8cb12016-06-15 16:51:091131 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1132 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231133
1134 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101135 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231136 bool has_server_header = response->headers->EnumerateHeader(
1137 &iter, "Server", &server_header);
1138 EXPECT_TRUE(has_server_header);
1139 EXPECT_EQ("Blah", server_header);
1140
1141 // Reading should give EOF right away, since there is no message body
1142 // (despite non-zero content-length).
1143 std::string response_data;
bnc691fda62016-08-12 00:43:161144 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011145 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231146 EXPECT_EQ("", response_data);
1147}
1148
bncd16676a2016-07-20 16:23:011149TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091150 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521151
1152 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351153 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1154 MockRead("hello"),
1155 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1156 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061157 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521158 };
[email protected]31a2bfe2010-02-09 08:03:391159 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071160 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521161
[email protected]0b0bf032010-09-21 18:08:501162 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521163 "hello", "world"
1164 };
1165
1166 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421167 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521168 request.method = "GET";
bncce36dca22015-04-21 22:11:231169 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521170 request.load_flags = 0;
1171
bnc691fda62016-08-12 00:43:161172 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271173
[email protected]49639fa2011-12-20 23:22:411174 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521175
tfarina42834112016-09-22 13:38:201176 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011177 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521178
1179 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011180 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521181
bnc691fda62016-08-12 00:43:161182 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521183 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521184
wezca1070932016-05-26 20:30:521185 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251186 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151187 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521188
1189 std::string response_data;
bnc691fda62016-08-12 00:43:161190 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011191 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251192 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521193 }
1194}
1195
bncd16676a2016-07-20 16:23:011196TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091197 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221198 element_readers.push_back(
ricea2deef682016-09-09 08:04:071199 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221200 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271201
[email protected]1c773ea12009-04-28 19:58:421202 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521203 request.method = "POST";
1204 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271205 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521206 request.load_flags = 0;
1207
shivanishab9a143952016-09-19 17:23:411208 // Check the upload progress returned before initialization is correct.
1209 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1210 EXPECT_EQ(0u, progress.size());
1211 EXPECT_EQ(0u, progress.position());
1212
danakj1fd259a02016-04-16 03:17:091213 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161214 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271215
initial.commit586acc5fe2008-07-26 22:42:521216 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351217 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1218 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1219 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061220 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521221 };
[email protected]31a2bfe2010-02-09 08:03:391222 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071223 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521224
[email protected]49639fa2011-12-20 23:22:411225 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521226
tfarina42834112016-09-22 13:38:201227 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011228 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521229
1230 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011231 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521232
bnc691fda62016-08-12 00:43:161233 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521234 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521235
wezca1070932016-05-26 20:30:521236 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251237 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521238
1239 std::string response_data;
bnc691fda62016-08-12 00:43:161240 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011241 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251242 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521243}
1244
[email protected]3a2d3662009-03-27 03:49:141245// This test is almost the same as Ignores100 above, but the response contains
1246// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571247// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011248TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421249 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141250 request.method = "GET";
1251 request.url = GURL("http://www.foo.com/");
1252 request.load_flags = 0;
1253
danakj1fd259a02016-04-16 03:17:091254 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161255 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271256
[email protected]3a2d3662009-03-27 03:49:141257 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571258 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1259 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141260 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061261 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141262 };
[email protected]31a2bfe2010-02-09 08:03:391263 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071264 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141265
[email protected]49639fa2011-12-20 23:22:411266 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141267
tfarina42834112016-09-22 13:38:201268 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011269 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141270
1271 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011272 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141273
bnc691fda62016-08-12 00:43:161274 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521275 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141276
wezca1070932016-05-26 20:30:521277 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141278 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1279
1280 std::string response_data;
bnc691fda62016-08-12 00:43:161281 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011282 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141283 EXPECT_EQ("hello world", response_data);
1284}
1285
bncd16676a2016-07-20 16:23:011286TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081287 HttpRequestInfo request;
1288 request.method = "POST";
1289 request.url = GURL("http://www.foo.com/");
1290 request.load_flags = 0;
1291
danakj1fd259a02016-04-16 03:17:091292 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161293 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081294
1295 MockRead data_reads[] = {
1296 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1297 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381298 };
zmo9528c9f42015-08-04 22:12:081299 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1300 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381301
zmo9528c9f42015-08-04 22:12:081302 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381303
tfarina42834112016-09-22 13:38:201304 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381306
zmo9528c9f42015-08-04 22:12:081307 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011308 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381309
zmo9528c9f42015-08-04 22:12:081310 std::string response_data;
bnc691fda62016-08-12 00:43:161311 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011312 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081313 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381314}
1315
bncd16676a2016-07-20 16:23:011316TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381317 HttpRequestInfo request;
1318 request.method = "POST";
1319 request.url = GURL("http://www.foo.com/");
1320 request.load_flags = 0;
1321
danakj1fd259a02016-04-16 03:17:091322 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161323 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271324
[email protected]ee9410e72010-01-07 01:42:381325 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061326 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381327 };
[email protected]31a2bfe2010-02-09 08:03:391328 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071329 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381330
[email protected]49639fa2011-12-20 23:22:411331 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381332
tfarina42834112016-09-22 13:38:201333 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011334 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381335
1336 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011337 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381338}
1339
[email protected]23e482282013-06-14 16:08:021340void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511341 const MockWrite* write_failure,
1342 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421343 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521344 request.method = "GET";
1345 request.url = GURL("http://www.foo.com/");
1346 request.load_flags = 0;
1347
vishal.b62985ca92015-04-17 08:45:511348 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071349 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091350 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271351
[email protected]202965992011-12-07 23:04:511352 // Written data for successfully sending both requests.
1353 MockWrite data1_writes[] = {
1354 MockWrite("GET / HTTP/1.1\r\n"
1355 "Host: www.foo.com\r\n"
1356 "Connection: keep-alive\r\n\r\n"),
1357 MockWrite("GET / HTTP/1.1\r\n"
1358 "Host: www.foo.com\r\n"
1359 "Connection: keep-alive\r\n\r\n")
1360 };
1361
1362 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521363 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351364 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1365 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061366 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521367 };
[email protected]202965992011-12-07 23:04:511368
1369 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491370 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511371 data1_writes[1] = *write_failure;
1372 } else {
1373 ASSERT_TRUE(read_failure);
1374 data1_reads[2] = *read_failure;
1375 }
1376
1377 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1378 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071379 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521380
1381 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351382 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1383 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061384 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521385 };
[email protected]31a2bfe2010-02-09 08:03:391386 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071387 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521388
thestig9d3bb0c2015-01-24 00:49:511389 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521390 "hello", "world"
1391 };
1392
avibf0746c2015-12-09 19:53:141393 uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521394 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411395 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521396
bnc691fda62016-08-12 00:43:161397 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521398
tfarina42834112016-09-22 13:38:201399 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011400 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521401
1402 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011403 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521404
[email protected]58e32bb2013-01-21 18:23:251405 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161406 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251407 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1408 if (i == 0) {
1409 first_socket_log_id = load_timing_info.socket_log_id;
1410 } else {
1411 // The second request should be using a new socket.
1412 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1413 }
1414
bnc691fda62016-08-12 00:43:161415 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521416 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521417
wezca1070932016-05-26 20:30:521418 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251419 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521420
1421 std::string response_data;
bnc691fda62016-08-12 00:43:161422 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011423 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251424 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521425 }
1426}
[email protected]3d2a59b2008-09-26 19:44:251427
[email protected]a34f61ee2014-03-18 20:59:491428void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1429 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101430 const MockRead* read_failure,
1431 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491432 HttpRequestInfo request;
1433 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101434 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491435 request.load_flags = 0;
1436
vishal.b62985ca92015-04-17 08:45:511437 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491438 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091439 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491440
[email protected]09356c652014-03-25 15:36:101441 SSLSocketDataProvider ssl1(ASYNC, OK);
1442 SSLSocketDataProvider ssl2(ASYNC, OK);
1443 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361444 ssl1.next_proto = kProtoHTTP2;
1445 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101446 }
1447 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1448 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491449
[email protected]09356c652014-03-25 15:36:101450 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411451 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491452 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411453 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151454 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411455 SpdySerializedFrame spdy_data(
1456 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491457
[email protected]09356c652014-03-25 15:36:101458 // HTTP/1.1 versions of the request and response.
1459 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1460 "Host: www.foo.com\r\n"
1461 "Connection: keep-alive\r\n\r\n";
1462 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1463 const char kHttpData[] = "hello";
1464
1465 std::vector<MockRead> data1_reads;
1466 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491467 if (write_failure) {
1468 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101469 data1_writes.push_back(*write_failure);
1470 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491471 } else {
1472 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101473 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411474 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101475 } else {
1476 data1_writes.push_back(MockWrite(kHttpRequest));
1477 }
1478 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491479 }
1480
[email protected]09356c652014-03-25 15:36:101481 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1482 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491483 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1484
[email protected]09356c652014-03-25 15:36:101485 std::vector<MockRead> data2_reads;
1486 std::vector<MockWrite> data2_writes;
1487
1488 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411489 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101490
bncdf80d44fd2016-07-15 20:27:411491 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1492 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101493 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1494 } else {
1495 data2_writes.push_back(
1496 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1497
1498 data2_reads.push_back(
1499 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1500 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1501 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1502 }
rch8e6c6c42015-05-01 14:05:131503 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1504 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491505 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1506
1507 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591508 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491509 // Wait for the preconnect to complete.
1510 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1511 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101512 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491513
1514 // Make the request.
1515 TestCompletionCallback callback;
1516
bnc691fda62016-08-12 00:43:161517 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491518
tfarina42834112016-09-22 13:38:201519 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011520 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491521
1522 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011523 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491524
1525 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161526 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101527 TestLoadTimingNotReused(
1528 load_timing_info,
1529 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491530
bnc691fda62016-08-12 00:43:161531 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521532 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491533
wezca1070932016-05-26 20:30:521534 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021535 if (response->was_fetched_via_spdy) {
1536 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1537 } else {
1538 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1539 }
[email protected]a34f61ee2014-03-18 20:59:491540
1541 std::string response_data;
bnc691fda62016-08-12 00:43:161542 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011543 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101544 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491545}
1546
bncd16676a2016-07-20 16:23:011547TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061548 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511549 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1550}
1551
bncd16676a2016-07-20 16:23:011552TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061553 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511554 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251555}
1556
bncd16676a2016-07-20 16:23:011557TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061558 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511559 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251560}
1561
[email protected]d58ceea82014-06-04 10:55:541562// Make sure that on a 408 response (Request Timeout), the request is retried,
1563// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011564TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541565 MockRead read_failure(SYNCHRONOUS,
1566 "HTTP/1.1 408 Request Timeout\r\n"
1567 "Connection: Keep-Alive\r\n"
1568 "Content-Length: 6\r\n\r\n"
1569 "Pickle");
1570 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1571}
1572
bncd16676a2016-07-20 16:23:011573TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491574 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101575 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491576}
1577
bncd16676a2016-07-20 16:23:011578TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491579 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101580 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491581}
1582
bncd16676a2016-07-20 16:23:011583TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491584 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101585 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1586}
1587
bncd16676a2016-07-20 16:23:011588TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101589 MockRead read_failure(ASYNC, OK); // EOF
1590 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1591}
1592
[email protected]d58ceea82014-06-04 10:55:541593// Make sure that on a 408 response (Request Timeout), the request is retried,
1594// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011595TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541596 MockRead read_failure(SYNCHRONOUS,
1597 "HTTP/1.1 408 Request Timeout\r\n"
1598 "Connection: Keep-Alive\r\n"
1599 "Content-Length: 6\r\n\r\n"
1600 "Pickle");
1601 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1602 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1603}
1604
bncd16676a2016-07-20 16:23:011605TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101606 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1607 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1608}
1609
bncd16676a2016-07-20 16:23:011610TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101611 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1612 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1613}
1614
bncd16676a2016-07-20 16:23:011615TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101616 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1617 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1618}
1619
bncd16676a2016-07-20 16:23:011620TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101621 MockRead read_failure(ASYNC, OK); // EOF
1622 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491623}
1624
bncd16676a2016-07-20 16:23:011625TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421626 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251627 request.method = "GET";
bncce36dca22015-04-21 22:11:231628 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251629 request.load_flags = 0;
1630
danakj1fd259a02016-04-16 03:17:091631 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161632 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271633
[email protected]3d2a59b2008-09-26 19:44:251634 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061635 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351636 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1637 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061638 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251639 };
[email protected]31a2bfe2010-02-09 08:03:391640 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071641 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251642
[email protected]49639fa2011-12-20 23:22:411643 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251644
tfarina42834112016-09-22 13:38:201645 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011646 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251647
1648 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011649 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591650
1651 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161652 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591653 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251654}
1655
1656// What do various browsers do when the server closes a non-keepalive
1657// connection without sending any response header or body?
1658//
1659// IE7: error page
1660// Safari 3.1.2 (Windows): error page
1661// Firefox 3.0.1: blank page
1662// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421663// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1664// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011665TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251666 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061667 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351668 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1669 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061670 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251671 };
[email protected]31a2bfe2010-02-09 08:03:391672 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1673 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011674 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251675}
[email protected]1826a402014-01-08 15:40:481676
[email protected]7a5378b2012-11-04 03:25:171677// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1678// tests. There was a bug causing HttpNetworkTransaction to hang in the
1679// destructor in such situations.
1680// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011681TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171682 HttpRequestInfo request;
1683 request.method = "GET";
bncce36dca22015-04-21 22:11:231684 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171685 request.load_flags = 0;
1686
danakj1fd259a02016-04-16 03:17:091687 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161688 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501689 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171690
1691 MockRead data_reads[] = {
1692 MockRead("HTTP/1.0 200 OK\r\n"),
1693 MockRead("Connection: keep-alive\r\n"),
1694 MockRead("Content-Length: 100\r\n\r\n"),
1695 MockRead("hello"),
1696 MockRead(SYNCHRONOUS, 0),
1697 };
1698 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071699 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171700
1701 TestCompletionCallback callback;
1702
tfarina42834112016-09-22 13:38:201703 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011704 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171705
1706 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011707 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171708
1709 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501710 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171711 if (rv == ERR_IO_PENDING)
1712 rv = callback.WaitForResult();
1713 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501714 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011715 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171716
1717 trans.reset();
fdoray92e35a72016-06-10 15:54:551718 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171719 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1720}
1721
bncd16676a2016-07-20 16:23:011722TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171723 HttpRequestInfo request;
1724 request.method = "GET";
bncce36dca22015-04-21 22:11:231725 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171726 request.load_flags = 0;
1727
danakj1fd259a02016-04-16 03:17:091728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161729 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501730 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171731
1732 MockRead data_reads[] = {
1733 MockRead("HTTP/1.0 200 OK\r\n"),
1734 MockRead("Connection: keep-alive\r\n"),
1735 MockRead("Content-Length: 100\r\n\r\n"),
1736 MockRead(SYNCHRONOUS, 0),
1737 };
1738 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071739 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171740
1741 TestCompletionCallback callback;
1742
tfarina42834112016-09-22 13:38:201743 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011744 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171745
1746 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011747 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171748
1749 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501750 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171751 if (rv == ERR_IO_PENDING)
1752 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011753 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171754
1755 trans.reset();
fdoray92e35a72016-06-10 15:54:551756 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171757 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1758}
1759
[email protected]0b0bf032010-09-21 18:08:501760// Test that we correctly reuse a keep-alive connection after not explicitly
1761// reading the body.
bncd16676a2016-07-20 16:23:011762TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131763 HttpRequestInfo request;
1764 request.method = "GET";
1765 request.url = GURL("http://www.foo.com/");
1766 request.load_flags = 0;
1767
vishal.b62985ca92015-04-17 08:45:511768 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071769 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091770 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271771
mmenkecc2298e2015-12-07 18:20:181772 const char* request_data =
1773 "GET / HTTP/1.1\r\n"
1774 "Host: www.foo.com\r\n"
1775 "Connection: keep-alive\r\n\r\n";
1776 MockWrite data_writes[] = {
1777 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1778 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1779 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1780 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1781 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1782 };
1783
[email protected]0b0bf032010-09-21 18:08:501784 // Note that because all these reads happen in the same
1785 // StaticSocketDataProvider, it shows that the same socket is being reused for
1786 // all transactions.
mmenkecc2298e2015-12-07 18:20:181787 MockRead data_reads[] = {
1788 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1789 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1790 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1791 MockRead(ASYNC, 7,
1792 "HTTP/1.1 302 Found\r\n"
1793 "Content-Length: 0\r\n\r\n"),
1794 MockRead(ASYNC, 9,
1795 "HTTP/1.1 302 Found\r\n"
1796 "Content-Length: 5\r\n\r\n"
1797 "hello"),
1798 MockRead(ASYNC, 11,
1799 "HTTP/1.1 301 Moved Permanently\r\n"
1800 "Content-Length: 0\r\n\r\n"),
1801 MockRead(ASYNC, 13,
1802 "HTTP/1.1 301 Moved Permanently\r\n"
1803 "Content-Length: 5\r\n\r\n"
1804 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131805
mmenkecc2298e2015-12-07 18:20:181806 // In the next two rounds, IsConnectedAndIdle returns false, due to
1807 // the set_busy_before_sync_reads(true) call, while the
1808 // HttpNetworkTransaction is being shut down, but the socket is still
1809 // reuseable. See http://crbug.com/544255.
1810 MockRead(ASYNC, 15,
1811 "HTTP/1.1 200 Hunky-Dory\r\n"
1812 "Content-Length: 5\r\n\r\n"),
1813 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131814
mmenkecc2298e2015-12-07 18:20:181815 MockRead(ASYNC, 18,
1816 "HTTP/1.1 200 Hunky-Dory\r\n"
1817 "Content-Length: 5\r\n\r\n"
1818 "he"),
1819 MockRead(SYNCHRONOUS, 19, "llo"),
1820
1821 // The body of the final request is actually read.
1822 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1823 MockRead(ASYNC, 22, "hello"),
1824 };
1825 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1826 arraysize(data_writes));
1827 data.set_busy_before_sync_reads(true);
1828 session_deps_.socket_factory->AddSocketDataProvider(&data);
1829
1830 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501831 std::string response_lines[kNumUnreadBodies];
1832
avibf0746c2015-12-09 19:53:141833 uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181834 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411835 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131836
bnc691fda62016-08-12 00:43:161837 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501838 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131839
tfarina42834112016-09-22 13:38:201840 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011841 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:131842
[email protected]58e32bb2013-01-21 18:23:251843 LoadTimingInfo load_timing_info;
1844 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1845 if (i == 0) {
1846 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1847 first_socket_log_id = load_timing_info.socket_log_id;
1848 } else {
1849 TestLoadTimingReused(load_timing_info);
1850 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1851 }
1852
[email protected]fc31d6a42010-06-24 18:05:131853 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181854 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131855
mmenkecc2298e2015-12-07 18:20:181856 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501857 response_lines[i] = response->headers->GetStatusLine();
1858
mmenkecc2298e2015-12-07 18:20:181859 // Delete the transaction without reading the response bodies. Then spin
1860 // the message loop, so the response bodies are drained.
1861 trans.reset();
1862 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131863 }
[email protected]0b0bf032010-09-21 18:08:501864
1865 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181866 "HTTP/1.1 204 No Content",
1867 "HTTP/1.1 205 Reset Content",
1868 "HTTP/1.1 304 Not Modified",
1869 "HTTP/1.1 302 Found",
1870 "HTTP/1.1 302 Found",
1871 "HTTP/1.1 301 Moved Permanently",
1872 "HTTP/1.1 301 Moved Permanently",
1873 "HTTP/1.1 200 Hunky-Dory",
1874 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:501875 };
1876
mostynb91e0da982015-01-20 19:17:271877 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1878 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501879
1880 for (int i = 0; i < kNumUnreadBodies; ++i)
1881 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1882
[email protected]49639fa2011-12-20 23:22:411883 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161884 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:201885 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011886 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:161887 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181888 ASSERT_TRUE(response);
1889 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501890 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1891 std::string response_data;
bnc691fda62016-08-12 00:43:161892 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011893 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:501894 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131895}
1896
mmenke5f94fda2016-06-02 20:54:131897// Sockets that receive extra data after a response is complete should not be
1898// reused.
bncd16676a2016-07-20 16:23:011899TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:131900 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1901 MockWrite data_writes1[] = {
1902 MockWrite("HEAD / HTTP/1.1\r\n"
1903 "Host: www.borked.com\r\n"
1904 "Connection: keep-alive\r\n\r\n"),
1905 };
1906
1907 MockRead data_reads1[] = {
1908 MockRead("HTTP/1.1 200 OK\r\n"
1909 "Connection: keep-alive\r\n"
1910 "Content-Length: 22\r\n\r\n"
1911 "This server is borked."),
1912 };
1913
1914 MockWrite data_writes2[] = {
1915 MockWrite("GET /foo HTTP/1.1\r\n"
1916 "Host: www.borked.com\r\n"
1917 "Connection: keep-alive\r\n\r\n"),
1918 };
1919
1920 MockRead data_reads2[] = {
1921 MockRead("HTTP/1.1 200 OK\r\n"
1922 "Content-Length: 3\r\n\r\n"
1923 "foo"),
1924 };
1925 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1926 data_writes1, arraysize(data_writes1));
1927 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1928 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1929 data_writes2, arraysize(data_writes2));
1930 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1931
1932 TestCompletionCallback callback;
1933 HttpRequestInfo request1;
1934 request1.method = "HEAD";
1935 request1.url = GURL("http://www.borked.com/");
1936
bnc691fda62016-08-12 00:43:161937 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:131938 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:201939 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011940 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:131941
1942 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
1943 ASSERT_TRUE(response1);
1944 ASSERT_TRUE(response1->headers);
1945 EXPECT_EQ(200, response1->headers->response_code());
1946 EXPECT_TRUE(response1->headers->IsKeepAlive());
1947
1948 std::string response_data1;
robpercival214763f2016-07-01 23:27:011949 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:131950 EXPECT_EQ("", response_data1);
1951 // Deleting the transaction attempts to release the socket back into the
1952 // socket pool.
1953 trans1.reset();
1954
1955 HttpRequestInfo request2;
1956 request2.method = "GET";
1957 request2.url = GURL("http://www.borked.com/foo");
1958
bnc691fda62016-08-12 00:43:161959 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:131960 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:201961 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011962 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:131963
1964 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
1965 ASSERT_TRUE(response2);
1966 ASSERT_TRUE(response2->headers);
1967 EXPECT_EQ(200, response2->headers->response_code());
1968
1969 std::string response_data2;
robpercival214763f2016-07-01 23:27:011970 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:131971 EXPECT_EQ("foo", response_data2);
1972}
1973
bncd16676a2016-07-20 16:23:011974TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:131975 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1976 MockWrite data_writes1[] = {
1977 MockWrite("GET / HTTP/1.1\r\n"
1978 "Host: www.borked.com\r\n"
1979 "Connection: keep-alive\r\n\r\n"),
1980 };
1981
1982 MockRead data_reads1[] = {
1983 MockRead("HTTP/1.1 200 OK\r\n"
1984 "Connection: keep-alive\r\n"
1985 "Content-Length: 22\r\n\r\n"
1986 "This server is borked."
1987 "Bonus data!"),
1988 };
1989
1990 MockWrite data_writes2[] = {
1991 MockWrite("GET /foo HTTP/1.1\r\n"
1992 "Host: www.borked.com\r\n"
1993 "Connection: keep-alive\r\n\r\n"),
1994 };
1995
1996 MockRead data_reads2[] = {
1997 MockRead("HTTP/1.1 200 OK\r\n"
1998 "Content-Length: 3\r\n\r\n"
1999 "foo"),
2000 };
2001 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2002 data_writes1, arraysize(data_writes1));
2003 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2004 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2005 data_writes2, arraysize(data_writes2));
2006 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2007
2008 TestCompletionCallback callback;
2009 HttpRequestInfo request1;
2010 request1.method = "GET";
2011 request1.url = GURL("http://www.borked.com/");
2012
bnc691fda62016-08-12 00:43:162013 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132014 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202015 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012016 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132017
2018 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2019 ASSERT_TRUE(response1);
2020 ASSERT_TRUE(response1->headers);
2021 EXPECT_EQ(200, response1->headers->response_code());
2022 EXPECT_TRUE(response1->headers->IsKeepAlive());
2023
2024 std::string response_data1;
robpercival214763f2016-07-01 23:27:012025 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132026 EXPECT_EQ("This server is borked.", response_data1);
2027 // Deleting the transaction attempts to release the socket back into the
2028 // socket pool.
2029 trans1.reset();
2030
2031 HttpRequestInfo request2;
2032 request2.method = "GET";
2033 request2.url = GURL("http://www.borked.com/foo");
2034
bnc691fda62016-08-12 00:43:162035 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132036 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202037 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012038 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132039
2040 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2041 ASSERT_TRUE(response2);
2042 ASSERT_TRUE(response2->headers);
2043 EXPECT_EQ(200, response2->headers->response_code());
2044
2045 std::string response_data2;
robpercival214763f2016-07-01 23:27:012046 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132047 EXPECT_EQ("foo", response_data2);
2048}
2049
bncd16676a2016-07-20 16:23:012050TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132051 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2052 MockWrite data_writes1[] = {
2053 MockWrite("GET / HTTP/1.1\r\n"
2054 "Host: www.borked.com\r\n"
2055 "Connection: keep-alive\r\n\r\n"),
2056 };
2057
2058 MockRead data_reads1[] = {
2059 MockRead("HTTP/1.1 200 OK\r\n"
2060 "Connection: keep-alive\r\n"
2061 "Transfer-Encoding: chunked\r\n\r\n"),
2062 MockRead("16\r\nThis server is borked.\r\n"),
2063 MockRead("0\r\n\r\nBonus data!"),
2064 };
2065
2066 MockWrite data_writes2[] = {
2067 MockWrite("GET /foo HTTP/1.1\r\n"
2068 "Host: www.borked.com\r\n"
2069 "Connection: keep-alive\r\n\r\n"),
2070 };
2071
2072 MockRead data_reads2[] = {
2073 MockRead("HTTP/1.1 200 OK\r\n"
2074 "Content-Length: 3\r\n\r\n"
2075 "foo"),
2076 };
2077 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2078 data_writes1, arraysize(data_writes1));
2079 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2080 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2081 data_writes2, arraysize(data_writes2));
2082 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2083
2084 TestCompletionCallback callback;
2085 HttpRequestInfo request1;
2086 request1.method = "GET";
2087 request1.url = GURL("http://www.borked.com/");
2088
bnc691fda62016-08-12 00:43:162089 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132090 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202091 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012092 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132093
2094 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2095 ASSERT_TRUE(response1);
2096 ASSERT_TRUE(response1->headers);
2097 EXPECT_EQ(200, response1->headers->response_code());
2098 EXPECT_TRUE(response1->headers->IsKeepAlive());
2099
2100 std::string response_data1;
robpercival214763f2016-07-01 23:27:012101 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132102 EXPECT_EQ("This server is borked.", response_data1);
2103 // Deleting the transaction attempts to release the socket back into the
2104 // socket pool.
2105 trans1.reset();
2106
2107 HttpRequestInfo request2;
2108 request2.method = "GET";
2109 request2.url = GURL("http://www.borked.com/foo");
2110
bnc691fda62016-08-12 00:43:162111 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132112 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202113 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012114 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132115
2116 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2117 ASSERT_TRUE(response2);
2118 ASSERT_TRUE(response2->headers);
2119 EXPECT_EQ(200, response2->headers->response_code());
2120
2121 std::string response_data2;
robpercival214763f2016-07-01 23:27:012122 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132123 EXPECT_EQ("foo", response_data2);
2124}
2125
2126// This is a little different from the others - it tests the case that the
2127// HttpStreamParser doesn't know if there's extra data on a socket or not when
2128// the HttpNetworkTransaction is torn down, because the response body hasn't
2129// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012130TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132131 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2132 MockWrite data_writes1[] = {
2133 MockWrite("GET / HTTP/1.1\r\n"
2134 "Host: www.borked.com\r\n"
2135 "Connection: keep-alive\r\n\r\n"),
2136 };
2137
2138 MockRead data_reads1[] = {
2139 MockRead("HTTP/1.1 200 OK\r\n"
2140 "Connection: keep-alive\r\n"
2141 "Transfer-Encoding: chunked\r\n\r\n"),
2142 MockRead("16\r\nThis server is borked.\r\n"),
2143 MockRead("0\r\n\r\nBonus data!"),
2144 };
2145 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2146 data_writes1, arraysize(data_writes1));
2147 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2148
2149 TestCompletionCallback callback;
2150 HttpRequestInfo request1;
2151 request1.method = "GET";
2152 request1.url = GURL("http://www.borked.com/");
2153
bnc691fda62016-08-12 00:43:162154 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132155 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202156 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012157 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132158
2159 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2160 ASSERT_TRUE(response1);
2161 ASSERT_TRUE(response1->headers);
2162 EXPECT_EQ(200, response1->headers->response_code());
2163 EXPECT_TRUE(response1->headers->IsKeepAlive());
2164
2165 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2166 // response body.
2167 trans1.reset();
2168
2169 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2170 // socket can't be reused, rather than returning it to the socket pool.
2171 base::RunLoop().RunUntilIdle();
2172
2173 // There should be no idle sockets in the pool.
2174 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2175}
2176
[email protected]038e9a32008-10-08 22:40:162177// Test the request-challenge-retry sequence for basic auth.
2178// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012179TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422180 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162181 request.method = "GET";
bncce36dca22015-04-21 22:11:232182 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162183 request.load_flags = 0;
2184
vishal.b62985ca92015-04-17 08:45:512185 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072186 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092187 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162188 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272189
[email protected]f9ee6b52008-11-08 06:46:232190 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232191 MockWrite(
2192 "GET / HTTP/1.1\r\n"
2193 "Host: www.example.org\r\n"
2194 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232195 };
2196
[email protected]038e9a32008-10-08 22:40:162197 MockRead data_reads1[] = {
2198 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2199 // Give a couple authenticate options (only the middle one is actually
2200 // supported).
[email protected]22927ad2009-09-21 19:56:192201 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162202 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2203 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2204 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2205 // Large content-length -- won't matter, as connection will be reset.
2206 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062207 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162208 };
2209
2210 // After calling trans->RestartWithAuth(), this is the request we should
2211 // be issuing -- the final header line contains the credentials.
2212 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232213 MockWrite(
2214 "GET / HTTP/1.1\r\n"
2215 "Host: www.example.org\r\n"
2216 "Connection: keep-alive\r\n"
2217 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162218 };
2219
2220 // Lastly, the server responds with the actual content.
2221 MockRead data_reads2[] = {
2222 MockRead("HTTP/1.0 200 OK\r\n"),
2223 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2224 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062225 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162226 };
2227
[email protected]31a2bfe2010-02-09 08:03:392228 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2229 data_writes1, arraysize(data_writes1));
2230 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2231 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072232 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2233 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162234
[email protected]49639fa2011-12-20 23:22:412235 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162236
tfarina42834112016-09-22 13:38:202237 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012238 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162239
2240 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012241 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162242
[email protected]58e32bb2013-01-21 18:23:252243 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162244 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252245 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2246
sclittlefb249892015-09-10 21:33:222247 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162248 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222249 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162250 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192251
bnc691fda62016-08-12 00:43:162252 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522253 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042254 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162255
[email protected]49639fa2011-12-20 23:22:412256 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162257
bnc691fda62016-08-12 00:43:162258 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012259 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162260
2261 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012262 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162263
[email protected]58e32bb2013-01-21 18:23:252264 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162265 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252266 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2267 // The load timing after restart should have a new socket ID, and times after
2268 // those of the first load timing.
2269 EXPECT_LE(load_timing_info1.receive_headers_end,
2270 load_timing_info2.connect_timing.connect_start);
2271 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2272
sclittlefb249892015-09-10 21:33:222273 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162274 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222275 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162276 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192277
bnc691fda62016-08-12 00:43:162278 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522279 ASSERT_TRUE(response);
2280 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162281 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162282}
2283
ttuttled9dbc652015-09-29 20:00:592284// Test the request-challenge-retry sequence for basic auth.
2285// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012286TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592287 HttpRequestInfo request;
2288 request.method = "GET";
2289 request.url = GURL("http://www.example.org/");
2290 request.load_flags = 0;
2291
2292 TestNetLog log;
2293 MockHostResolver* resolver = new MockHostResolver();
2294 session_deps_.net_log = &log;
2295 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092296 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162297 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592298
2299 resolver->rules()->ClearRules();
2300 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2301
2302 MockWrite data_writes1[] = {
2303 MockWrite("GET / HTTP/1.1\r\n"
2304 "Host: www.example.org\r\n"
2305 "Connection: keep-alive\r\n\r\n"),
2306 };
2307
2308 MockRead data_reads1[] = {
2309 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2310 // Give a couple authenticate options (only the middle one is actually
2311 // supported).
2312 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2313 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2314 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2315 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2316 // Large content-length -- won't matter, as connection will be reset.
2317 MockRead("Content-Length: 10000\r\n\r\n"),
2318 MockRead(SYNCHRONOUS, ERR_FAILED),
2319 };
2320
2321 // After calling trans->RestartWithAuth(), this is the request we should
2322 // be issuing -- the final header line contains the credentials.
2323 MockWrite data_writes2[] = {
2324 MockWrite("GET / HTTP/1.1\r\n"
2325 "Host: www.example.org\r\n"
2326 "Connection: keep-alive\r\n"
2327 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2328 };
2329
2330 // Lastly, the server responds with the actual content.
2331 MockRead data_reads2[] = {
2332 MockRead("HTTP/1.0 200 OK\r\n"),
2333 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2334 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2335 };
2336
2337 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2338 data_writes1, arraysize(data_writes1));
2339 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2340 data_writes2, arraysize(data_writes2));
2341 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2342 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2343
2344 TestCompletionCallback callback1;
2345
bnc691fda62016-08-12 00:43:162346 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202347 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592348
2349 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162350 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592351 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2352
2353 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162354 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592355 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162356 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592357
bnc691fda62016-08-12 00:43:162358 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592359 ASSERT_TRUE(response);
2360 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2361
2362 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162363 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592364 ASSERT_FALSE(endpoint.address().empty());
2365 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2366
2367 resolver->rules()->ClearRules();
2368 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2369
2370 TestCompletionCallback callback2;
2371
bnc691fda62016-08-12 00:43:162372 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592373 AuthCredentials(kFoo, kBar), callback2.callback())));
2374
2375 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162376 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592377 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2378 // The load timing after restart should have a new socket ID, and times after
2379 // those of the first load timing.
2380 EXPECT_LE(load_timing_info1.receive_headers_end,
2381 load_timing_info2.connect_timing.connect_start);
2382 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2383
2384 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162385 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592386 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162387 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592388
bnc691fda62016-08-12 00:43:162389 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592390 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522391 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592392 EXPECT_EQ(100, response->headers->GetContentLength());
2393
bnc691fda62016-08-12 00:43:162394 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592395 ASSERT_FALSE(endpoint.address().empty());
2396 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2397}
2398
bncd16676a2016-07-20 16:23:012399TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462400 HttpRequestInfo request;
2401 request.method = "GET";
bncce36dca22015-04-21 22:11:232402 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292403 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462404
danakj1fd259a02016-04-16 03:17:092405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272407
[email protected]861fcd52009-08-26 02:33:462408 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232409 MockWrite(
2410 "GET / HTTP/1.1\r\n"
2411 "Host: www.example.org\r\n"
2412 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462413 };
2414
2415 MockRead data_reads[] = {
2416 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2417 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2418 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2419 // Large content-length -- won't matter, as connection will be reset.
2420 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062421 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462422 };
2423
[email protected]31a2bfe2010-02-09 08:03:392424 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2425 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072426 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412427 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462428
tfarina42834112016-09-22 13:38:202429 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012430 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462431
2432 rv = callback.WaitForResult();
2433 EXPECT_EQ(0, rv);
2434
sclittlefb249892015-09-10 21:33:222435 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162436 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222437 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162438 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192439
bnc691fda62016-08-12 00:43:162440 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522441 ASSERT_TRUE(response);
2442 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462443}
2444
[email protected]2d2697f92009-02-18 21:00:322445// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2446// connection.
bncd16676a2016-07-20 16:23:012447TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182448 // On the second pass, the body read of the auth challenge is synchronous, so
2449 // IsConnectedAndIdle returns false. The socket should still be drained and
2450 // reused. See http://crbug.com/544255.
2451 for (int i = 0; i < 2; ++i) {
2452 HttpRequestInfo request;
2453 request.method = "GET";
2454 request.url = GURL("http://www.example.org/");
2455 request.load_flags = 0;
[email protected]2d2697f92009-02-18 21:00:322456
mmenkecc2298e2015-12-07 18:20:182457 TestNetLog log;
2458 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092459 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272460
mmenkecc2298e2015-12-07 18:20:182461 MockWrite data_writes[] = {
2462 MockWrite(ASYNC, 0,
2463 "GET / HTTP/1.1\r\n"
2464 "Host: www.example.org\r\n"
2465 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322466
bnc691fda62016-08-12 00:43:162467 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182468 // be issuing -- the final header line contains the credentials.
2469 MockWrite(ASYNC, 6,
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"),
2474 };
[email protected]2d2697f92009-02-18 21:00:322475
mmenkecc2298e2015-12-07 18:20:182476 MockRead data_reads[] = {
2477 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2478 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2479 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2480 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2481 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322482
mmenkecc2298e2015-12-07 18:20:182483 // Lastly, the server responds with the actual content.
2484 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2485 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2486 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2487 MockRead(ASYNC, 10, "Hello"),
2488 };
[email protected]2d2697f92009-02-18 21:00:322489
mmenkecc2298e2015-12-07 18:20:182490 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2491 arraysize(data_writes));
2492 data.set_busy_before_sync_reads(true);
2493 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462494
mmenkecc2298e2015-12-07 18:20:182495 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322496
bnc691fda62016-08-12 00:43:162497 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202498 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012499 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322500
mmenkecc2298e2015-12-07 18:20:182501 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162502 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182503 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322504
bnc691fda62016-08-12 00:43:162505 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182506 ASSERT_TRUE(response);
2507 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322508
mmenkecc2298e2015-12-07 18:20:182509 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252510
bnc691fda62016-08-12 00:43:162511 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2512 callback2.callback());
robpercival214763f2016-07-01 23:27:012513 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322514
mmenkecc2298e2015-12-07 18:20:182515 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162516 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182517 TestLoadTimingReused(load_timing_info2);
2518 // The load timing after restart should have the same socket ID, and times
2519 // those of the first load timing.
2520 EXPECT_LE(load_timing_info1.receive_headers_end,
2521 load_timing_info2.send_start);
2522 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322523
bnc691fda62016-08-12 00:43:162524 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182525 ASSERT_TRUE(response);
2526 EXPECT_FALSE(response->auth_challenge);
2527 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322528
mmenkecc2298e2015-12-07 18:20:182529 std::string response_data;
bnc691fda62016-08-12 00:43:162530 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322531
mmenkecc2298e2015-12-07 18:20:182532 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162533 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182534 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162535 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182536 }
[email protected]2d2697f92009-02-18 21:00:322537}
2538
2539// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2540// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012541TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422542 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322543 request.method = "GET";
bncce36dca22015-04-21 22:11:232544 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322545 request.load_flags = 0;
2546
danakj1fd259a02016-04-16 03:17:092547 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272548
[email protected]2d2697f92009-02-18 21:00:322549 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162550 MockWrite("GET / HTTP/1.1\r\n"
2551 "Host: www.example.org\r\n"
2552 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322553
bnc691fda62016-08-12 00:43:162554 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232555 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162556 MockWrite("GET / HTTP/1.1\r\n"
2557 "Host: www.example.org\r\n"
2558 "Connection: keep-alive\r\n"
2559 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322560 };
2561
[email protected]2d2697f92009-02-18 21:00:322562 MockRead data_reads1[] = {
2563 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2564 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312565 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322566
2567 // Lastly, the server responds with the actual content.
2568 MockRead("HTTP/1.1 200 OK\r\n"),
2569 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502570 MockRead("Content-Length: 5\r\n\r\n"),
2571 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322572 };
2573
[email protected]2d0a4f92011-05-05 16:38:462574 // An incorrect reconnect would cause this to be read.
2575 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062576 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462577 };
2578
[email protected]31a2bfe2010-02-09 08:03:392579 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2580 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462581 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2582 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072583 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2584 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322585
[email protected]49639fa2011-12-20 23:22:412586 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322587
bnc691fda62016-08-12 00:43:162588 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202589 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012590 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322591
2592 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012593 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322594
bnc691fda62016-08-12 00:43:162595 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522596 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042597 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322598
[email protected]49639fa2011-12-20 23:22:412599 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322600
bnc691fda62016-08-12 00:43:162601 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012602 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322603
2604 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012605 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322606
bnc691fda62016-08-12 00:43:162607 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522608 ASSERT_TRUE(response);
2609 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502610 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322611}
2612
2613// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2614// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012615TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422616 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322617 request.method = "GET";
bncce36dca22015-04-21 22:11:232618 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322619 request.load_flags = 0;
2620
danakj1fd259a02016-04-16 03:17:092621 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272622
[email protected]2d2697f92009-02-18 21:00:322623 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162624 MockWrite("GET / HTTP/1.1\r\n"
2625 "Host: www.example.org\r\n"
2626 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322627
bnc691fda62016-08-12 00:43:162628 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232629 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162630 MockWrite("GET / HTTP/1.1\r\n"
2631 "Host: www.example.org\r\n"
2632 "Connection: keep-alive\r\n"
2633 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322634 };
2635
2636 // Respond with 5 kb of response body.
2637 std::string large_body_string("Unauthorized");
2638 large_body_string.append(5 * 1024, ' ');
2639 large_body_string.append("\r\n");
2640
2641 MockRead data_reads1[] = {
2642 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2643 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2644 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2645 // 5134 = 12 + 5 * 1024 + 2
2646 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062647 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322648
2649 // Lastly, the server responds with the actual content.
2650 MockRead("HTTP/1.1 200 OK\r\n"),
2651 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502652 MockRead("Content-Length: 5\r\n\r\n"),
2653 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322654 };
2655
[email protected]2d0a4f92011-05-05 16:38:462656 // An incorrect reconnect would cause this to be read.
2657 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062658 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462659 };
2660
[email protected]31a2bfe2010-02-09 08:03:392661 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2662 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462663 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2664 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072665 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2666 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322667
[email protected]49639fa2011-12-20 23:22:412668 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322669
bnc691fda62016-08-12 00:43:162670 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202671 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322673
2674 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012675 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322676
bnc691fda62016-08-12 00:43:162677 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522678 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042679 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322680
[email protected]49639fa2011-12-20 23:22:412681 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322682
bnc691fda62016-08-12 00:43:162683 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012684 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322685
2686 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012687 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322688
bnc691fda62016-08-12 00:43:162689 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522690 ASSERT_TRUE(response);
2691 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502692 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322693}
2694
2695// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312696// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012697TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312698 HttpRequestInfo request;
2699 request.method = "GET";
bncce36dca22015-04-21 22:11:232700 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312701 request.load_flags = 0;
2702
danakj1fd259a02016-04-16 03:17:092703 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272704
[email protected]11203f012009-11-12 23:02:312705 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232706 MockWrite(
2707 "GET / HTTP/1.1\r\n"
2708 "Host: www.example.org\r\n"
2709 "Connection: keep-alive\r\n\r\n"),
2710 // This simulates the seemingly successful write to a closed connection
2711 // if the bug is not fixed.
2712 MockWrite(
2713 "GET / HTTP/1.1\r\n"
2714 "Host: www.example.org\r\n"
2715 "Connection: keep-alive\r\n"
2716 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312717 };
2718
2719 MockRead data_reads1[] = {
2720 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2721 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2722 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2723 MockRead("Content-Length: 14\r\n\r\n"),
2724 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062725 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312726 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062727 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312728 };
2729
bnc691fda62016-08-12 00:43:162730 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312731 // be issuing -- the final header line contains the credentials.
2732 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232733 MockWrite(
2734 "GET / HTTP/1.1\r\n"
2735 "Host: www.example.org\r\n"
2736 "Connection: keep-alive\r\n"
2737 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312738 };
2739
2740 // Lastly, the server responds with the actual content.
2741 MockRead data_reads2[] = {
2742 MockRead("HTTP/1.1 200 OK\r\n"),
2743 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502744 MockRead("Content-Length: 5\r\n\r\n"),
2745 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312746 };
2747
[email protected]31a2bfe2010-02-09 08:03:392748 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2749 data_writes1, arraysize(data_writes1));
2750 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2751 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072752 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2753 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312754
[email protected]49639fa2011-12-20 23:22:412755 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312756
bnc691fda62016-08-12 00:43:162757 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202758 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012759 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312760
2761 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012762 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312763
bnc691fda62016-08-12 00:43:162764 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522765 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042766 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312767
[email protected]49639fa2011-12-20 23:22:412768 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312769
bnc691fda62016-08-12 00:43:162770 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012771 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312772
2773 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012774 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312775
bnc691fda62016-08-12 00:43:162776 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522777 ASSERT_TRUE(response);
2778 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502779 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312780}
2781
[email protected]394816e92010-08-03 07:38:592782// Test the request-challenge-retry sequence for basic auth, over a connection
2783// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012784TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:012785 HttpRequestInfo request;
2786 request.method = "GET";
bncce36dca22015-04-21 22:11:232787 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012788 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292789 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012790
2791 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032792 session_deps_.proxy_service =
2793 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512794 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012795 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012797
2798 // Since we have proxy, should try to establish tunnel.
2799 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542800 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172801 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542802 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012803 };
2804
mmenkee71e15332015-10-07 16:39:542805 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012806 // connection.
2807 MockRead data_reads1[] = {
2808 // No credentials.
2809 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2810 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542811 };
ttuttle34f63b52015-03-05 04:33:012812
mmenkee71e15332015-10-07 16:39:542813 // Since the first connection couldn't be reused, need to establish another
2814 // once given credentials.
2815 MockWrite data_writes2[] = {
2816 // After calling trans->RestartWithAuth(), this is the request we should
2817 // be issuing -- the final header line contains the credentials.
2818 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172819 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542820 "Proxy-Connection: keep-alive\r\n"
2821 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2822
2823 MockWrite("GET / HTTP/1.1\r\n"
2824 "Host: www.example.org\r\n"
2825 "Connection: keep-alive\r\n\r\n"),
2826 };
2827
2828 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012829 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2830
2831 MockRead("HTTP/1.1 200 OK\r\n"),
2832 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2833 MockRead("Content-Length: 5\r\n\r\n"),
2834 MockRead(SYNCHRONOUS, "hello"),
2835 };
2836
2837 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2838 data_writes1, arraysize(data_writes1));
2839 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542840 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2841 data_writes2, arraysize(data_writes2));
2842 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012843 SSLSocketDataProvider ssl(ASYNC, OK);
2844 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2845
2846 TestCompletionCallback callback1;
2847
bnc691fda62016-08-12 00:43:162848 std::unique_ptr<HttpNetworkTransaction> trans(
ttuttle34f63b52015-03-05 04:33:012849 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2850
2851 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:012852 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012853
2854 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012855 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:462856 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012857 log.GetEntries(&entries);
2858 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002859 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2860 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012861 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002862 entries, pos,
2863 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2864 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012865
2866 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522867 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012868 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522869 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:012870 EXPECT_EQ(407, response->headers->response_code());
2871 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2872 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2873
2874 LoadTimingInfo load_timing_info;
2875 // CONNECT requests and responses are handled at the connect job level, so
2876 // the transaction does not yet have a connection.
2877 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2878
2879 TestCompletionCallback callback2;
2880
2881 rv =
2882 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012884
2885 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012886 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:012887
2888 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522889 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012890
2891 EXPECT_TRUE(response->headers->IsKeepAlive());
2892 EXPECT_EQ(200, response->headers->response_code());
2893 EXPECT_EQ(5, response->headers->GetContentLength());
2894 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2895
2896 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:522897 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:012898
2899 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2900 TestLoadTimingNotReusedWithPac(load_timing_info,
2901 CONNECT_TIMING_HAS_SSL_TIMES);
2902
2903 trans.reset();
2904 session->CloseAllConnections();
2905}
2906
2907// Test the request-challenge-retry sequence for basic auth, over a connection
2908// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012909TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592910 HttpRequestInfo request;
2911 request.method = "GET";
bncce36dca22015-04-21 22:11:232912 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592913 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292914 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592915
[email protected]cb9bf6ca2011-01-28 13:15:272916 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032917 session_deps_.proxy_service =
2918 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512919 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072920 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092921 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272922
[email protected]394816e92010-08-03 07:38:592923 // Since we have proxy, should try to establish tunnel.
2924 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542925 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172926 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542927 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:112928 };
2929
mmenkee71e15332015-10-07 16:39:542930 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:082931 // connection.
2932 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:542933 // No credentials.
2934 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2935 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2936 MockRead("Proxy-Connection: close\r\n\r\n"),
2937 };
mmenkee0b5c882015-08-26 20:29:112938
mmenkee71e15332015-10-07 16:39:542939 MockWrite data_writes2[] = {
2940 // After calling trans->RestartWithAuth(), this is the request we should
2941 // be issuing -- the final header line contains the credentials.
2942 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172943 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542944 "Proxy-Connection: keep-alive\r\n"
2945 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:082946
mmenkee71e15332015-10-07 16:39:542947 MockWrite("GET / HTTP/1.1\r\n"
2948 "Host: www.example.org\r\n"
2949 "Connection: keep-alive\r\n\r\n"),
2950 };
2951
2952 MockRead data_reads2[] = {
2953 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2954
2955 MockRead("HTTP/1.1 200 OK\r\n"),
2956 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2957 MockRead("Content-Length: 5\r\n\r\n"),
2958 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592959 };
2960
2961 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2962 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072963 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542964 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2965 data_writes2, arraysize(data_writes2));
2966 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:062967 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072968 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592969
[email protected]49639fa2011-12-20 23:22:412970 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592971
bnc691fda62016-08-12 00:43:162972 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:502973 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502974
[email protected]49639fa2011-12-20 23:22:412975 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:012976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:592977
2978 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012979 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:462980 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402981 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592982 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002983 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2984 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:592985 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402986 entries, pos,
mikecirone8b85c432016-09-08 19:11:002987 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2988 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:592989
2990 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522991 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012992 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522993 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:592994 EXPECT_EQ(407, response->headers->response_code());
2995 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042996 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592997
[email protected]029c83b62013-01-24 05:28:202998 LoadTimingInfo load_timing_info;
2999 // CONNECT requests and responses are handled at the connect job level, so
3000 // the transaction does not yet have a connection.
3001 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3002
[email protected]49639fa2011-12-20 23:22:413003 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593004
[email protected]49639fa2011-12-20 23:22:413005 rv = trans->RestartWithAuth(
3006 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593008
3009 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013010 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593011
3012 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523013 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593014
3015 EXPECT_TRUE(response->headers->IsKeepAlive());
3016 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503017 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593018 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3019
3020 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523021 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503022
[email protected]029c83b62013-01-24 05:28:203023 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3024 TestLoadTimingNotReusedWithPac(load_timing_info,
3025 CONNECT_TIMING_HAS_SSL_TIMES);
3026
[email protected]0b0bf032010-09-21 18:08:503027 trans.reset();
[email protected]102e27c2011-02-23 01:01:313028 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593029}
3030
[email protected]11203f012009-11-12 23:02:313031// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013032// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013033TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233034 // On the second pass, the body read of the auth challenge is synchronous, so
3035 // IsConnectedAndIdle returns false. The socket should still be drained and
3036 // reused. See http://crbug.com/544255.
3037 for (int i = 0; i < 2; ++i) {
3038 HttpRequestInfo request;
3039 request.method = "GET";
3040 request.url = GURL("https://www.example.org/");
3041 // Ensure that proxy authentication is attempted even
3042 // when the no authentication data flag is set.
3043 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013044
mmenked39192ee2015-12-09 00:57:233045 // Configure against proxy server "myproxy:70".
3046 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3047 BoundTestNetLog log;
3048 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093049 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013050
bnc691fda62016-08-12 00:43:163051 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013052
mmenked39192ee2015-12-09 00:57:233053 // Since we have proxy, should try to establish tunnel.
3054 MockWrite data_writes1[] = {
3055 MockWrite(ASYNC, 0,
3056 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3057 "Host: www.example.org:443\r\n"
3058 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013059
bnc691fda62016-08-12 00:43:163060 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233061 // be issuing -- the final header line contains the credentials.
3062 MockWrite(ASYNC, 3,
3063 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3064 "Host: www.example.org:443\r\n"
3065 "Proxy-Connection: keep-alive\r\n"
3066 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3067 };
ttuttle34f63b52015-03-05 04:33:013068
mmenked39192ee2015-12-09 00:57:233069 // The proxy responds to the connect with a 407, using a persistent
3070 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3071 MockRead data_reads1[] = {
3072 // No credentials.
3073 MockRead(ASYNC, 1,
3074 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3075 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3076 "Proxy-Connection: keep-alive\r\n"
3077 "Content-Length: 10\r\n\r\n"),
3078 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013079
mmenked39192ee2015-12-09 00:57:233080 // Wrong credentials (wrong password).
3081 MockRead(ASYNC, 4,
3082 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3083 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3084 "Proxy-Connection: keep-alive\r\n"
3085 "Content-Length: 10\r\n\r\n"),
3086 // No response body because the test stops reading here.
3087 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3088 };
ttuttle34f63b52015-03-05 04:33:013089
mmenked39192ee2015-12-09 00:57:233090 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3091 arraysize(data_writes1));
3092 data1.set_busy_before_sync_reads(true);
3093 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013094
mmenked39192ee2015-12-09 00:57:233095 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013096
bnc691fda62016-08-12 00:43:163097 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013098 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013099
mmenked39192ee2015-12-09 00:57:233100 TestNetLogEntry::List entries;
3101 log.GetEntries(&entries);
3102 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003103 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3104 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233105 ExpectLogContainsSomewhere(
3106 entries, pos,
mikecirone8b85c432016-09-08 19:11:003107 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3108 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013109
bnc691fda62016-08-12 00:43:163110 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233111 ASSERT_TRUE(response);
3112 ASSERT_TRUE(response->headers);
3113 EXPECT_TRUE(response->headers->IsKeepAlive());
3114 EXPECT_EQ(407, response->headers->response_code());
3115 EXPECT_EQ(10, response->headers->GetContentLength());
3116 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3117 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013118
mmenked39192ee2015-12-09 00:57:233119 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013120
mmenked39192ee2015-12-09 00:57:233121 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163122 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3123 callback2.callback());
robpercival214763f2016-07-01 23:27:013124 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013125
bnc691fda62016-08-12 00:43:163126 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233127 ASSERT_TRUE(response);
3128 ASSERT_TRUE(response->headers);
3129 EXPECT_TRUE(response->headers->IsKeepAlive());
3130 EXPECT_EQ(407, response->headers->response_code());
3131 EXPECT_EQ(10, response->headers->GetContentLength());
3132 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3133 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013134
mmenked39192ee2015-12-09 00:57:233135 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3136 // out of scope.
3137 session->CloseAllConnections();
3138 }
ttuttle34f63b52015-03-05 04:33:013139}
3140
3141// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3142// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013143TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233144 // On the second pass, the body read of the auth challenge is synchronous, so
3145 // IsConnectedAndIdle returns false. The socket should still be drained and
3146 // reused. See http://crbug.com/544255.
3147 for (int i = 0; i < 2; ++i) {
3148 HttpRequestInfo request;
3149 request.method = "GET";
3150 request.url = GURL("https://www.example.org/");
3151 // Ensure that proxy authentication is attempted even
3152 // when the no authentication data flag is set.
3153 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3154
3155 // Configure against proxy server "myproxy:70".
3156 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3157 BoundTestNetLog log;
3158 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093159 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233160
bnc691fda62016-08-12 00:43:163161 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233162
3163 // Since we have proxy, should try to establish tunnel.
3164 MockWrite data_writes1[] = {
3165 MockWrite(ASYNC, 0,
3166 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3167 "Host: www.example.org:443\r\n"
3168 "Proxy-Connection: keep-alive\r\n\r\n"),
3169
bnc691fda62016-08-12 00:43:163170 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233171 // be issuing -- the final header line contains the credentials.
3172 MockWrite(ASYNC, 3,
3173 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3174 "Host: www.example.org:443\r\n"
3175 "Proxy-Connection: keep-alive\r\n"
3176 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3177 };
3178
3179 // The proxy responds to the connect with a 407, using a persistent
3180 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3181 MockRead data_reads1[] = {
3182 // No credentials.
3183 MockRead(ASYNC, 1,
3184 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3185 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3186 "Content-Length: 10\r\n\r\n"),
3187 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3188
3189 // Wrong credentials (wrong password).
3190 MockRead(ASYNC, 4,
3191 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3192 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3193 "Content-Length: 10\r\n\r\n"),
3194 // No response body because the test stops reading here.
3195 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3196 };
3197
3198 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3199 arraysize(data_writes1));
3200 data1.set_busy_before_sync_reads(true);
3201 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3202
3203 TestCompletionCallback callback1;
3204
bnc691fda62016-08-12 00:43:163205 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013206 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233207
3208 TestNetLogEntry::List entries;
3209 log.GetEntries(&entries);
3210 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003211 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3212 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233213 ExpectLogContainsSomewhere(
3214 entries, pos,
mikecirone8b85c432016-09-08 19:11:003215 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3216 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233217
bnc691fda62016-08-12 00:43:163218 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233219 ASSERT_TRUE(response);
3220 ASSERT_TRUE(response->headers);
3221 EXPECT_TRUE(response->headers->IsKeepAlive());
3222 EXPECT_EQ(407, response->headers->response_code());
3223 EXPECT_EQ(10, response->headers->GetContentLength());
3224 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3225 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3226
3227 TestCompletionCallback callback2;
3228
3229 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163230 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3231 callback2.callback());
robpercival214763f2016-07-01 23:27:013232 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233233
bnc691fda62016-08-12 00:43:163234 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233235 ASSERT_TRUE(response);
3236 ASSERT_TRUE(response->headers);
3237 EXPECT_TRUE(response->headers->IsKeepAlive());
3238 EXPECT_EQ(407, response->headers->response_code());
3239 EXPECT_EQ(10, response->headers->GetContentLength());
3240 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3241 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3242
3243 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3244 // out of scope.
3245 session->CloseAllConnections();
3246 }
3247}
3248
3249// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3250// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3251// the case the server sends extra data on the original socket, so it can't be
3252// reused.
bncd16676a2016-07-20 16:23:013253TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273254 HttpRequestInfo request;
3255 request.method = "GET";
bncce36dca22015-04-21 22:11:233256 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273257 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293258 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273259
[email protected]2d2697f92009-02-18 21:00:323260 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233261 session_deps_.proxy_service =
3262 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513263 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073264 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093265 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323266
[email protected]2d2697f92009-02-18 21:00:323267 // Since we have proxy, should try to establish tunnel.
3268 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233269 MockWrite(ASYNC, 0,
3270 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173271 "Host: www.example.org:443\r\n"
3272 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233273 };
[email protected]2d2697f92009-02-18 21:00:323274
mmenked39192ee2015-12-09 00:57:233275 // The proxy responds to the connect with a 407, using a persistent, but sends
3276 // extra data, so the socket cannot be reused.
3277 MockRead data_reads1[] = {
3278 // No credentials.
3279 MockRead(ASYNC, 1,
3280 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3281 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3282 "Content-Length: 10\r\n\r\n"),
3283 MockRead(SYNCHRONOUS, 2, "0123456789"),
3284 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3285 };
3286
3287 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233288 // After calling trans->RestartWithAuth(), this is the request we should
3289 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233290 MockWrite(ASYNC, 0,
3291 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173292 "Host: www.example.org:443\r\n"
3293 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233294 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3295
3296 MockWrite(ASYNC, 2,
3297 "GET / HTTP/1.1\r\n"
3298 "Host: www.example.org\r\n"
3299 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323300 };
3301
mmenked39192ee2015-12-09 00:57:233302 MockRead data_reads2[] = {
3303 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323304
mmenked39192ee2015-12-09 00:57:233305 MockRead(ASYNC, 3,
3306 "HTTP/1.1 200 OK\r\n"
3307 "Content-Type: text/html; charset=iso-8859-1\r\n"
3308 "Content-Length: 5\r\n\r\n"),
3309 // No response body because the test stops reading here.
3310 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323311 };
3312
mmenked39192ee2015-12-09 00:57:233313 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3314 arraysize(data_writes1));
3315 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073316 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233317 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3318 arraysize(data_writes2));
3319 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3320 SSLSocketDataProvider ssl(ASYNC, OK);
3321 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323322
[email protected]49639fa2011-12-20 23:22:413323 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323324
bnc691fda62016-08-12 00:43:163325 std::unique_ptr<HttpNetworkTransaction> trans(
mmenked39192ee2015-12-09 00:57:233326 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:323327
mmenked39192ee2015-12-09 00:57:233328 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013329 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233330
mmenke43758e62015-05-04 21:09:463331 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403332 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393333 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003334 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3335 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393336 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403337 entries, pos,
mikecirone8b85c432016-09-08 19:11:003338 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3339 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323340
[email protected]1c773ea12009-04-28 19:58:423341 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243342 ASSERT_TRUE(response);
3343 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323344 EXPECT_TRUE(response->headers->IsKeepAlive());
3345 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423346 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043347 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323348
mmenked39192ee2015-12-09 00:57:233349 LoadTimingInfo load_timing_info;
3350 // CONNECT requests and responses are handled at the connect job level, so
3351 // the transaction does not yet have a connection.
3352 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3353
[email protected]49639fa2011-12-20 23:22:413354 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323355
mmenked39192ee2015-12-09 00:57:233356 rv =
3357 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013358 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323359
[email protected]2d2697f92009-02-18 21:00:323360 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233361 EXPECT_EQ(200, response->headers->response_code());
3362 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423363 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133364
mmenked39192ee2015-12-09 00:57:233365 // The password prompt info should not be set.
3366 EXPECT_FALSE(response->auth_challenge);
3367
3368 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3369 TestLoadTimingNotReusedWithPac(load_timing_info,
3370 CONNECT_TIMING_HAS_SSL_TIMES);
3371
3372 trans.reset();
[email protected]102e27c2011-02-23 01:01:313373 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323374}
3375
mmenkee71e15332015-10-07 16:39:543376// Test the case a proxy closes a socket while the challenge body is being
3377// drained.
bncd16676a2016-07-20 16:23:013378TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543379 HttpRequestInfo request;
3380 request.method = "GET";
3381 request.url = GURL("https://www.example.org/");
3382 // Ensure that proxy authentication is attempted even
3383 // when the no authentication data flag is set.
3384 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3385
3386 // Configure against proxy server "myproxy:70".
3387 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093388 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543389
bnc691fda62016-08-12 00:43:163390 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543391
3392 // Since we have proxy, should try to establish tunnel.
3393 MockWrite data_writes1[] = {
3394 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173395 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543396 "Proxy-Connection: keep-alive\r\n\r\n"),
3397 };
3398
3399 // The proxy responds to the connect with a 407, using a persistent
3400 // connection.
3401 MockRead data_reads1[] = {
3402 // No credentials.
3403 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3404 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3405 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3406 // Server hands up in the middle of the body.
3407 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3408 };
3409
3410 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163411 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543412 // be issuing -- the final header line contains the credentials.
3413 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173414 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543415 "Proxy-Connection: keep-alive\r\n"
3416 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3417
3418 MockWrite("GET / HTTP/1.1\r\n"
3419 "Host: www.example.org\r\n"
3420 "Connection: keep-alive\r\n\r\n"),
3421 };
3422
3423 MockRead data_reads2[] = {
3424 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3425
3426 MockRead("HTTP/1.1 200 OK\r\n"),
3427 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3428 MockRead("Content-Length: 5\r\n\r\n"),
3429 MockRead(SYNCHRONOUS, "hello"),
3430 };
3431
3432 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3433 data_writes1, arraysize(data_writes1));
3434 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3435 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3436 data_writes2, arraysize(data_writes2));
3437 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3438 SSLSocketDataProvider ssl(ASYNC, OK);
3439 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3440
3441 TestCompletionCallback callback;
3442
tfarina42834112016-09-22 13:38:203443 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013444 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543445
bnc691fda62016-08-12 00:43:163446 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543447 ASSERT_TRUE(response);
3448 ASSERT_TRUE(response->headers);
3449 EXPECT_TRUE(response->headers->IsKeepAlive());
3450 EXPECT_EQ(407, response->headers->response_code());
3451 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3452
bnc691fda62016-08-12 00:43:163453 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013454 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543455
bnc691fda62016-08-12 00:43:163456 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543457 ASSERT_TRUE(response);
3458 ASSERT_TRUE(response->headers);
3459 EXPECT_TRUE(response->headers->IsKeepAlive());
3460 EXPECT_EQ(200, response->headers->response_code());
3461 std::string body;
bnc691fda62016-08-12 00:43:163462 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543463 EXPECT_EQ("hello", body);
3464}
3465
[email protected]a8e9b162009-03-12 00:06:443466// Test that we don't read the response body when we fail to establish a tunnel,
3467// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013468TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273469 HttpRequestInfo request;
3470 request.method = "GET";
bncce36dca22015-04-21 22:11:233471 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273472 request.load_flags = 0;
3473
[email protected]a8e9b162009-03-12 00:06:443474 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033475 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443476
danakj1fd259a02016-04-16 03:17:093477 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443478
bnc691fda62016-08-12 00:43:163479 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443480
[email protected]a8e9b162009-03-12 00:06:443481 // Since we have proxy, should try to establish tunnel.
3482 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173483 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3484 "Host: www.example.org:443\r\n"
3485 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443486 };
3487
3488 // The proxy responds to the connect with a 407.
3489 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243490 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3491 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3492 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233493 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243494 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443495 };
3496
[email protected]31a2bfe2010-02-09 08:03:393497 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3498 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073499 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443500
[email protected]49639fa2011-12-20 23:22:413501 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443502
tfarina42834112016-09-22 13:38:203503 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013504 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443505
3506 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013507 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443508
bnc691fda62016-08-12 00:43:163509 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243510 ASSERT_TRUE(response);
3511 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443512 EXPECT_TRUE(response->headers->IsKeepAlive());
3513 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423514 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443515
3516 std::string response_data;
bnc691fda62016-08-12 00:43:163517 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013518 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183519
3520 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313521 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443522}
3523
ttuttle7933c112015-01-06 00:55:243524// Test that we don't pass extraneous headers from the proxy's response to the
3525// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013526TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243527 HttpRequestInfo request;
3528 request.method = "GET";
bncce36dca22015-04-21 22:11:233529 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243530 request.load_flags = 0;
3531
3532 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033533 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243534
danakj1fd259a02016-04-16 03:17:093535 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243536
bnc691fda62016-08-12 00:43:163537 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243538
3539 // Since we have proxy, should try to establish tunnel.
3540 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173541 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3542 "Host: www.example.org:443\r\n"
3543 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243544 };
3545
3546 // The proxy responds to the connect with a 407.
3547 MockRead data_reads[] = {
3548 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3549 MockRead("X-Foo: bar\r\n"),
3550 MockRead("Set-Cookie: foo=bar\r\n"),
3551 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3552 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233553 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243554 };
3555
3556 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3557 arraysize(data_writes));
3558 session_deps_.socket_factory->AddSocketDataProvider(&data);
3559
3560 TestCompletionCallback callback;
3561
tfarina42834112016-09-22 13:38:203562 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243564
3565 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013566 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243567
bnc691fda62016-08-12 00:43:163568 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243569 ASSERT_TRUE(response);
3570 ASSERT_TRUE(response->headers);
3571 EXPECT_TRUE(response->headers->IsKeepAlive());
3572 EXPECT_EQ(407, response->headers->response_code());
3573 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3574 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3575 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3576
3577 std::string response_data;
bnc691fda62016-08-12 00:43:163578 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013579 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243580
3581 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3582 session->CloseAllConnections();
3583}
3584
[email protected]8fdbcd22010-05-05 02:54:523585// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3586// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013587TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523588 HttpRequestInfo request;
3589 request.method = "GET";
bncce36dca22015-04-21 22:11:233590 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523591 request.load_flags = 0;
3592
[email protected]cb9bf6ca2011-01-28 13:15:273593 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093594 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163595 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273596
[email protected]8fdbcd22010-05-05 02:54:523597 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233598 MockWrite(
3599 "GET / HTTP/1.1\r\n"
3600 "Host: www.example.org\r\n"
3601 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523602 };
3603
3604 MockRead data_reads1[] = {
3605 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3606 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3607 // Large content-length -- won't matter, as connection will be reset.
3608 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063609 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523610 };
3611
3612 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3613 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073614 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523615
[email protected]49639fa2011-12-20 23:22:413616 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523617
tfarina42834112016-09-22 13:38:203618 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523620
3621 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013622 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523623}
3624
[email protected]7a67a8152010-11-05 18:31:103625// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3626// through a non-authenticating proxy. The request should fail with
3627// ERR_UNEXPECTED_PROXY_AUTH.
3628// Note that it is impossible to detect if an HTTP server returns a 407 through
3629// a non-authenticating proxy - there is nothing to indicate whether the
3630// response came from the proxy or the server, so it is treated as if the proxy
3631// issued the challenge.
bncd16676a2016-07-20 16:23:013632TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273633 HttpRequestInfo request;
3634 request.method = "GET";
bncce36dca22015-04-21 22:11:233635 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273636
rdsmith82957ad2015-09-16 19:42:033637 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513638 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073639 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093640 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103641
[email protected]7a67a8152010-11-05 18:31:103642 // Since we have proxy, should try to establish tunnel.
3643 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173644 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3645 "Host: www.example.org:443\r\n"
3646 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103647
rsleevidb16bb02015-11-12 23:47:173648 MockWrite("GET / HTTP/1.1\r\n"
3649 "Host: www.example.org\r\n"
3650 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103651 };
3652
3653 MockRead data_reads1[] = {
3654 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3655
3656 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3657 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3658 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063659 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103660 };
3661
3662 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3663 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073664 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063665 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073666 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103667
[email protected]49639fa2011-12-20 23:22:413668 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103669
bnc691fda62016-08-12 00:43:163670 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103671
bnc691fda62016-08-12 00:43:163672 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013673 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103674
3675 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013676 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463677 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403678 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103679 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003680 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3681 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103682 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403683 entries, pos,
mikecirone8b85c432016-09-08 19:11:003684 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3685 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103686}
[email protected]2df19bb2010-08-25 20:13:463687
mmenke2a1781d2015-10-07 19:25:333688// Test a proxy auth scheme that allows default credentials and a proxy server
3689// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013690TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333691 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3692 HttpRequestInfo request;
3693 request.method = "GET";
3694 request.url = GURL("https://www.example.org/");
3695
3696 // Configure against proxy server "myproxy:70".
3697 session_deps_.proxy_service =
3698 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3699
danakj1fd259a02016-04-16 03:17:093700 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333701 new HttpAuthHandlerMock::Factory());
3702 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093703 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333704 mock_handler->set_allows_default_credentials(true);
3705 auth_handler_factory->AddMockHandler(mock_handler.release(),
3706 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483707 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333708
3709 // Add NetLog just so can verify load timing information gets a NetLog ID.
3710 NetLog net_log;
3711 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093712 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333713
3714 // Since we have proxy, should try to establish tunnel.
3715 MockWrite data_writes1[] = {
3716 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173717 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333718 "Proxy-Connection: keep-alive\r\n\r\n"),
3719 };
3720
3721 // The proxy responds to the connect with a 407, using a non-persistent
3722 // connection.
3723 MockRead data_reads1[] = {
3724 // No credentials.
3725 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3726 MockRead("Proxy-Authenticate: Mock\r\n"),
3727 MockRead("Proxy-Connection: close\r\n\r\n"),
3728 };
3729
3730 // Since the first connection couldn't be reused, need to establish another
3731 // once given credentials.
3732 MockWrite data_writes2[] = {
3733 // After calling trans->RestartWithAuth(), this is the request we should
3734 // be issuing -- the final header line contains the credentials.
3735 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173736 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333737 "Proxy-Connection: keep-alive\r\n"
3738 "Proxy-Authorization: auth_token\r\n\r\n"),
3739
3740 MockWrite("GET / HTTP/1.1\r\n"
3741 "Host: www.example.org\r\n"
3742 "Connection: keep-alive\r\n\r\n"),
3743 };
3744
3745 MockRead data_reads2[] = {
3746 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3747
3748 MockRead("HTTP/1.1 200 OK\r\n"),
3749 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3750 MockRead("Content-Length: 5\r\n\r\n"),
3751 MockRead(SYNCHRONOUS, "hello"),
3752 };
3753
3754 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3755 data_writes1, arraysize(data_writes1));
3756 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3757 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3758 data_writes2, arraysize(data_writes2));
3759 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3760 SSLSocketDataProvider ssl(ASYNC, OK);
3761 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3762
bnc691fda62016-08-12 00:43:163763 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333764 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3765
3766 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203767 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013768 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333769
3770 const HttpResponseInfo* response = trans->GetResponseInfo();
3771 ASSERT_TRUE(response);
3772 ASSERT_TRUE(response->headers);
3773 EXPECT_FALSE(response->headers->IsKeepAlive());
3774 EXPECT_EQ(407, response->headers->response_code());
3775 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3776 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523777 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333778
3779 LoadTimingInfo load_timing_info;
3780 // CONNECT requests and responses are handled at the connect job level, so
3781 // the transaction does not yet have a connection.
3782 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3783
3784 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013785 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333786 response = trans->GetResponseInfo();
3787 ASSERT_TRUE(response);
3788 ASSERT_TRUE(response->headers);
3789 EXPECT_TRUE(response->headers->IsKeepAlive());
3790 EXPECT_EQ(200, response->headers->response_code());
3791 EXPECT_EQ(5, response->headers->GetContentLength());
3792 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3793
3794 // The password prompt info should not be set.
3795 EXPECT_FALSE(response->auth_challenge);
3796
3797 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3798 TestLoadTimingNotReusedWithPac(load_timing_info,
3799 CONNECT_TIMING_HAS_SSL_TIMES);
3800
3801 trans.reset();
3802 session->CloseAllConnections();
3803}
3804
3805// Test a proxy auth scheme that allows default credentials and a proxy server
3806// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:013807TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333808 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3809 HttpRequestInfo request;
3810 request.method = "GET";
3811 request.url = GURL("https://www.example.org/");
3812
3813 // Configure against proxy server "myproxy:70".
3814 session_deps_.proxy_service =
3815 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3816
danakj1fd259a02016-04-16 03:17:093817 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333818 new HttpAuthHandlerMock::Factory());
3819 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093820 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333821 mock_handler->set_allows_default_credentials(true);
3822 auth_handler_factory->AddMockHandler(mock_handler.release(),
3823 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483824 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333825
3826 // Add NetLog just so can verify load timing information gets a NetLog ID.
3827 NetLog net_log;
3828 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093829 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333830
3831 // Should try to establish tunnel.
3832 MockWrite data_writes1[] = {
3833 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173834 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333835 "Proxy-Connection: keep-alive\r\n\r\n"),
3836
3837 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173838 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333839 "Proxy-Connection: keep-alive\r\n"
3840 "Proxy-Authorization: auth_token\r\n\r\n"),
3841 };
3842
3843 // The proxy responds to the connect with a 407, using a non-persistent
3844 // connection.
3845 MockRead data_reads1[] = {
3846 // No credentials.
3847 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3848 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3849 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3850 };
3851
3852 // Since the first connection was closed, need to establish another once given
3853 // credentials.
3854 MockWrite data_writes2[] = {
3855 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173856 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333857 "Proxy-Connection: keep-alive\r\n"
3858 "Proxy-Authorization: auth_token\r\n\r\n"),
3859
3860 MockWrite("GET / HTTP/1.1\r\n"
3861 "Host: www.example.org\r\n"
3862 "Connection: keep-alive\r\n\r\n"),
3863 };
3864
3865 MockRead data_reads2[] = {
3866 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3867
3868 MockRead("HTTP/1.1 200 OK\r\n"),
3869 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3870 MockRead("Content-Length: 5\r\n\r\n"),
3871 MockRead(SYNCHRONOUS, "hello"),
3872 };
3873
3874 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3875 data_writes1, arraysize(data_writes1));
3876 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3877 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3878 data_writes2, arraysize(data_writes2));
3879 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3880 SSLSocketDataProvider ssl(ASYNC, OK);
3881 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3882
bnc691fda62016-08-12 00:43:163883 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333884 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3885
3886 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203887 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013888 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333889
3890 const HttpResponseInfo* response = trans->GetResponseInfo();
3891 ASSERT_TRUE(response);
3892 ASSERT_TRUE(response->headers);
3893 EXPECT_TRUE(response->headers->IsKeepAlive());
3894 EXPECT_EQ(407, response->headers->response_code());
3895 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3896 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3897 EXPECT_FALSE(response->auth_challenge);
3898
3899 LoadTimingInfo load_timing_info;
3900 // CONNECT requests and responses are handled at the connect job level, so
3901 // the transaction does not yet have a connection.
3902 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3903
3904 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013905 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333906
3907 response = trans->GetResponseInfo();
3908 ASSERT_TRUE(response);
3909 ASSERT_TRUE(response->headers);
3910 EXPECT_TRUE(response->headers->IsKeepAlive());
3911 EXPECT_EQ(200, response->headers->response_code());
3912 EXPECT_EQ(5, response->headers->GetContentLength());
3913 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3914
3915 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523916 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333917
3918 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3919 TestLoadTimingNotReusedWithPac(load_timing_info,
3920 CONNECT_TIMING_HAS_SSL_TIMES);
3921
3922 trans.reset();
3923 session->CloseAllConnections();
3924}
3925
3926// Test a proxy auth scheme that allows default credentials and a proxy server
3927// that hangs up when credentials are initially sent, and hangs up again when
3928// they are retried.
bncd16676a2016-07-20 16:23:013929TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333930 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
3931 HttpRequestInfo request;
3932 request.method = "GET";
3933 request.url = GURL("https://www.example.org/");
3934
3935 // Configure against proxy server "myproxy:70".
3936 session_deps_.proxy_service =
3937 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3938
danakj1fd259a02016-04-16 03:17:093939 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333940 new HttpAuthHandlerMock::Factory());
3941 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093942 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333943 mock_handler->set_allows_default_credentials(true);
3944 auth_handler_factory->AddMockHandler(mock_handler.release(),
3945 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483946 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333947
3948 // Add NetLog just so can verify load timing information gets a NetLog ID.
3949 NetLog net_log;
3950 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093951 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333952
3953 // Should try to establish tunnel.
3954 MockWrite data_writes1[] = {
3955 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173956 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333957 "Proxy-Connection: keep-alive\r\n\r\n"),
3958
3959 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173960 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333961 "Proxy-Connection: keep-alive\r\n"
3962 "Proxy-Authorization: auth_token\r\n\r\n"),
3963 };
3964
3965 // The proxy responds to the connect with a 407, and then hangs up after the
3966 // second request is sent.
3967 MockRead data_reads1[] = {
3968 // No credentials.
3969 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3970 MockRead("Content-Length: 0\r\n"),
3971 MockRead("Proxy-Connection: keep-alive\r\n"),
3972 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3973 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3974 };
3975
3976 // HttpNetworkTransaction sees a reused connection that was closed with
3977 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
3978 // request.
3979 MockWrite data_writes2[] = {
3980 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173981 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333982 "Proxy-Connection: keep-alive\r\n\r\n"),
3983 };
3984
3985 // The proxy, having had more than enough of us, just hangs up.
3986 MockRead data_reads2[] = {
3987 // No credentials.
3988 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3989 };
3990
3991 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3992 data_writes1, arraysize(data_writes1));
3993 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3994 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3995 data_writes2, arraysize(data_writes2));
3996 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3997
bnc691fda62016-08-12 00:43:163998 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333999 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4000
4001 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204002 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014003 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334004
4005 const HttpResponseInfo* response = trans->GetResponseInfo();
4006 ASSERT_TRUE(response);
4007 ASSERT_TRUE(response->headers);
4008 EXPECT_TRUE(response->headers->IsKeepAlive());
4009 EXPECT_EQ(407, response->headers->response_code());
4010 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4011 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4012 EXPECT_FALSE(response->auth_challenge);
4013
4014 LoadTimingInfo load_timing_info;
4015 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4016
4017 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014018 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334019
4020 trans.reset();
4021 session->CloseAllConnections();
4022}
4023
4024// Test a proxy auth scheme that allows default credentials and a proxy server
4025// that hangs up when credentials are initially sent, and sends a challenge
4026// again they are retried.
bncd16676a2016-07-20 16:23:014027TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334028 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4029 HttpRequestInfo request;
4030 request.method = "GET";
4031 request.url = GURL("https://www.example.org/");
4032
4033 // Configure against proxy server "myproxy:70".
4034 session_deps_.proxy_service =
4035 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4036
danakj1fd259a02016-04-16 03:17:094037 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334038 new HttpAuthHandlerMock::Factory());
4039 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094040 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334041 mock_handler->set_allows_default_credentials(true);
4042 auth_handler_factory->AddMockHandler(mock_handler.release(),
4043 HttpAuth::AUTH_PROXY);
4044 // Add another handler for the second challenge. It supports default
4045 // credentials, but they shouldn't be used, since they were already tried.
4046 mock_handler.reset(new HttpAuthHandlerMock());
4047 mock_handler->set_allows_default_credentials(true);
4048 auth_handler_factory->AddMockHandler(mock_handler.release(),
4049 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484050 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334051
4052 // Add NetLog just so can verify load timing information gets a NetLog ID.
4053 NetLog net_log;
4054 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094055 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334056
4057 // Should try to establish tunnel.
4058 MockWrite data_writes1[] = {
4059 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174060 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334061 "Proxy-Connection: keep-alive\r\n\r\n"),
4062 };
4063
4064 // The proxy responds to the connect with a 407, using a non-persistent
4065 // connection.
4066 MockRead data_reads1[] = {
4067 // No credentials.
4068 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4069 MockRead("Proxy-Authenticate: Mock\r\n"),
4070 MockRead("Proxy-Connection: close\r\n\r\n"),
4071 };
4072
4073 // Since the first connection was closed, need to establish another once given
4074 // credentials.
4075 MockWrite data_writes2[] = {
4076 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174077 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334078 "Proxy-Connection: keep-alive\r\n"
4079 "Proxy-Authorization: auth_token\r\n\r\n"),
4080 };
4081
4082 MockRead data_reads2[] = {
4083 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4084 MockRead("Proxy-Authenticate: Mock\r\n"),
4085 MockRead("Proxy-Connection: close\r\n\r\n"),
4086 };
4087
4088 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4089 data_writes1, arraysize(data_writes1));
4090 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4091 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4092 data_writes2, arraysize(data_writes2));
4093 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4094 SSLSocketDataProvider ssl(ASYNC, OK);
4095 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4096
bnc691fda62016-08-12 00:43:164097 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334098 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4099
4100 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204101 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014102 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334103
4104 const HttpResponseInfo* response = trans->GetResponseInfo();
4105 ASSERT_TRUE(response);
4106 ASSERT_TRUE(response->headers);
4107 EXPECT_EQ(407, response->headers->response_code());
4108 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4109 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4110 EXPECT_FALSE(response->auth_challenge);
4111
4112 LoadTimingInfo load_timing_info;
4113 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4114
4115 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014116 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334117 response = trans->GetResponseInfo();
4118 ASSERT_TRUE(response);
4119 ASSERT_TRUE(response->headers);
4120 EXPECT_EQ(407, response->headers->response_code());
4121 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4122 EXPECT_TRUE(response->auth_challenge);
4123
4124 trans.reset();
4125 session->CloseAllConnections();
4126}
4127
[email protected]029c83b62013-01-24 05:28:204128// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014129TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204130 HttpRequestInfo request1;
4131 request1.method = "GET";
bncce36dca22015-04-21 22:11:234132 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204133
4134 HttpRequestInfo request2;
4135 request2.method = "GET";
bncce36dca22015-04-21 22:11:234136 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204137
4138 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034139 session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514140 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074141 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094142 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204143
4144 // Since we have proxy, should try to establish tunnel.
4145 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174146 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4147 "Host: www.example.org:443\r\n"
4148 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204149
rsleevidb16bb02015-11-12 23:47:174150 MockWrite("GET /1 HTTP/1.1\r\n"
4151 "Host: www.example.org\r\n"
4152 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204153
rsleevidb16bb02015-11-12 23:47:174154 MockWrite("GET /2 HTTP/1.1\r\n"
4155 "Host: www.example.org\r\n"
4156 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204157 };
4158
4159 // The proxy responds to the connect with a 407, using a persistent
4160 // connection.
4161 MockRead data_reads1[] = {
4162 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4163
4164 MockRead("HTTP/1.1 200 OK\r\n"),
4165 MockRead("Content-Length: 1\r\n\r\n"),
4166 MockRead(SYNCHRONOUS, "1"),
4167
4168 MockRead("HTTP/1.1 200 OK\r\n"),
4169 MockRead("Content-Length: 2\r\n\r\n"),
4170 MockRead(SYNCHRONOUS, "22"),
4171 };
4172
4173 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4174 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074175 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204176 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074177 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204178
4179 TestCompletionCallback callback1;
bnc691fda62016-08-12 00:43:164180 std::unique_ptr<HttpNetworkTransaction> trans1(
[email protected]90499482013-06-01 00:39:504181 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204182
4183 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014184 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204185
4186 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014187 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204188
4189 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524190 ASSERT_TRUE(response1);
4191 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204192 EXPECT_EQ(1, response1->headers->GetContentLength());
4193
4194 LoadTimingInfo load_timing_info1;
4195 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4196 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4197
4198 trans1.reset();
4199
4200 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:164201 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:504202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204203
4204 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014205 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204206
4207 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014208 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204209
4210 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524211 ASSERT_TRUE(response2);
4212 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204213 EXPECT_EQ(2, response2->headers->GetContentLength());
4214
4215 LoadTimingInfo load_timing_info2;
4216 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4217 TestLoadTimingReused(load_timing_info2);
4218
4219 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4220
4221 trans2.reset();
4222 session->CloseAllConnections();
4223}
4224
4225// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014226TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204227 HttpRequestInfo request1;
4228 request1.method = "GET";
bncce36dca22015-04-21 22:11:234229 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204230
4231 HttpRequestInfo request2;
4232 request2.method = "GET";
bncce36dca22015-04-21 22:11:234233 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204234
4235 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034236 session_deps_.proxy_service =
4237 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514238 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074239 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094240 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204241
4242 // Since we have proxy, should try to establish tunnel.
4243 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174244 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4245 "Host: www.example.org:443\r\n"
4246 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204247
rsleevidb16bb02015-11-12 23:47:174248 MockWrite("GET /1 HTTP/1.1\r\n"
4249 "Host: www.example.org\r\n"
4250 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204251
rsleevidb16bb02015-11-12 23:47:174252 MockWrite("GET /2 HTTP/1.1\r\n"
4253 "Host: www.example.org\r\n"
4254 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204255 };
4256
4257 // The proxy responds to the connect with a 407, using a persistent
4258 // connection.
4259 MockRead data_reads1[] = {
4260 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4261
4262 MockRead("HTTP/1.1 200 OK\r\n"),
4263 MockRead("Content-Length: 1\r\n\r\n"),
4264 MockRead(SYNCHRONOUS, "1"),
4265
4266 MockRead("HTTP/1.1 200 OK\r\n"),
4267 MockRead("Content-Length: 2\r\n\r\n"),
4268 MockRead(SYNCHRONOUS, "22"),
4269 };
4270
4271 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4272 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074273 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204274 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204276
4277 TestCompletionCallback callback1;
bnc691fda62016-08-12 00:43:164278 std::unique_ptr<HttpNetworkTransaction> trans1(
[email protected]90499482013-06-01 00:39:504279 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204280
4281 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014282 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204283
4284 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014285 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204286
4287 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524288 ASSERT_TRUE(response1);
4289 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204290 EXPECT_EQ(1, response1->headers->GetContentLength());
4291
4292 LoadTimingInfo load_timing_info1;
4293 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4294 TestLoadTimingNotReusedWithPac(load_timing_info1,
4295 CONNECT_TIMING_HAS_SSL_TIMES);
4296
4297 trans1.reset();
4298
4299 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:164300 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:504301 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204302
4303 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204305
4306 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014307 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204308
4309 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524310 ASSERT_TRUE(response2);
4311 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204312 EXPECT_EQ(2, response2->headers->GetContentLength());
4313
4314 LoadTimingInfo load_timing_info2;
4315 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4316 TestLoadTimingReusedWithPac(load_timing_info2);
4317
4318 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4319
4320 trans2.reset();
4321 session->CloseAllConnections();
4322}
4323
[email protected]2df19bb2010-08-25 20:13:464324// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014325TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274326 HttpRequestInfo request;
4327 request.method = "GET";
bncce36dca22015-04-21 22:11:234328 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274329
[email protected]2df19bb2010-08-25 20:13:464330 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034331 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514332 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074333 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094334 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464335
[email protected]2df19bb2010-08-25 20:13:464336 // Since we have proxy, should use full url
4337 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234338 MockWrite(
4339 "GET http://www.example.org/ HTTP/1.1\r\n"
4340 "Host: www.example.org\r\n"
4341 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464342 };
4343
4344 MockRead data_reads1[] = {
4345 MockRead("HTTP/1.1 200 OK\r\n"),
4346 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4347 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064348 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464349 };
4350
4351 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4352 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074353 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064354 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074355 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464356
[email protected]49639fa2011-12-20 23:22:414357 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464358
bnc691fda62016-08-12 00:43:164359 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504360
bnc691fda62016-08-12 00:43:164361 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014362 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464363
4364 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014365 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464366
[email protected]58e32bb2013-01-21 18:23:254367 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164368 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254369 TestLoadTimingNotReused(load_timing_info,
4370 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4371
bnc691fda62016-08-12 00:43:164372 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524373 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464374
4375 EXPECT_TRUE(response->headers->IsKeepAlive());
4376 EXPECT_EQ(200, response->headers->response_code());
4377 EXPECT_EQ(100, response->headers->GetContentLength());
4378 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4379
4380 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524381 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464382}
4383
[email protected]7642b5ae2010-09-01 20:55:174384// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014385TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274386 HttpRequestInfo request;
4387 request.method = "GET";
bncce36dca22015-04-21 22:11:234388 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274389 request.load_flags = 0;
4390
[email protected]7642b5ae2010-09-01 20:55:174391 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034392 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514393 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074394 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094395 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174396
bncce36dca22015-04-21 22:11:234397 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414398 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454399 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414400 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174401
bnc42331402016-07-25 13:36:154402 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414403 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174404 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414405 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174406 };
4407
rch8e6c6c42015-05-01 14:05:134408 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4409 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074410 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174411
[email protected]8ddf8322012-02-23 18:08:064412 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364413 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074414 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174415
[email protected]49639fa2011-12-20 23:22:414416 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174417
bnc691fda62016-08-12 00:43:164418 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504419
bnc691fda62016-08-12 00:43:164420 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014421 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:174422
4423 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014424 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:174425
[email protected]58e32bb2013-01-21 18:23:254426 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164427 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254428 TestLoadTimingNotReused(load_timing_info,
4429 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4430
bnc691fda62016-08-12 00:43:164431 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524432 ASSERT_TRUE(response);
4433 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024434 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174435
4436 std::string response_data;
bnc691fda62016-08-12 00:43:164437 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234438 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174439}
4440
[email protected]1c173852014-06-19 12:51:504441// Verifies that a session which races and wins against the owning transaction
4442// (completing prior to host resolution), doesn't fail the transaction.
4443// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:014444TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:504445 HttpRequestInfo request;
4446 request.method = "GET";
bncce36dca22015-04-21 22:11:234447 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504448 request.load_flags = 0;
4449
4450 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034451 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514452 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504453 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094454 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504455
bncce36dca22015-04-21 22:11:234456 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:414457 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454458 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414459 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:504460
bnc42331402016-07-25 13:36:154461 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414462 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:504463 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414464 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504465 };
4466
rch8e6c6c42015-05-01 14:05:134467 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4468 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504469 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4470
4471 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364472 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:504473 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4474
4475 TestCompletionCallback callback1;
4476
bnc691fda62016-08-12 00:43:164477 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:504478
4479 // Stall the hostname resolution begun by the transaction.
4480 session_deps_.host_resolver->set_synchronous_mode(false);
4481 session_deps_.host_resolver->set_ondemand_mode(true);
4482
bnc691fda62016-08-12 00:43:164483 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014484 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:504485
4486 // Race a session to the proxy, which completes first.
4487 session_deps_.host_resolver->set_ondemand_mode(false);
4488 SpdySessionKey key(
4489 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4490 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424491 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504492
4493 // Unstall the resolution begun by the transaction.
4494 session_deps_.host_resolver->set_ondemand_mode(true);
4495 session_deps_.host_resolver->ResolveAllPending();
4496
4497 EXPECT_FALSE(callback1.have_result());
4498 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014499 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:504500
bnc691fda62016-08-12 00:43:164501 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524502 ASSERT_TRUE(response);
4503 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024504 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504505
4506 std::string response_data;
bnc691fda62016-08-12 00:43:164507 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:504508 EXPECT_EQ(kUploadData, response_data);
4509}
4510
[email protected]dc7bd1c52010-11-12 00:01:134511// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014512TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274513 HttpRequestInfo request;
4514 request.method = "GET";
bncce36dca22015-04-21 22:11:234515 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274516 request.load_flags = 0;
4517
[email protected]79cb5c12011-09-12 13:12:044518 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034519 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514520 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074521 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094522 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134523
[email protected]dc7bd1c52010-11-12 00:01:134524 // The first request will be a bare GET, the second request will be a
4525 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:454526 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:414527 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:494528 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384529 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134530 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464531 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134532 };
bncdf80d44fd2016-07-15 20:27:414533 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4534 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
4535 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134536 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414537 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134538 };
4539
4540 // The first response is a 407 proxy authentication challenge, and the second
4541 // response will be a 200 response since the second request includes a valid
4542 // Authorization header.
4543 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464544 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134545 };
bnc42331402016-07-25 13:36:154546 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:414547 "407 Proxy Authentication Required", kExtraAuthenticationHeaders,
4548 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4549 SpdySerializedFrame body_authentication(
4550 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:154551 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:414552 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134553 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414554 CreateMockRead(resp_authentication, 1),
4555 CreateMockRead(body_authentication, 2),
4556 CreateMockRead(resp_data, 4),
4557 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:134558 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134559 };
4560
rch8e6c6c42015-05-01 14:05:134561 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4562 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074563 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134564
[email protected]8ddf8322012-02-23 18:08:064565 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364566 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074567 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134568
[email protected]49639fa2011-12-20 23:22:414569 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134570
bnc691fda62016-08-12 00:43:164571 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:134572
bnc691fda62016-08-12 00:43:164573 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014574 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134575
4576 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014577 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134578
bnc691fda62016-08-12 00:43:164579 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134580
wezca1070932016-05-26 20:30:524581 ASSERT_TRUE(response);
4582 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134583 EXPECT_EQ(407, response->headers->response_code());
4584 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434585 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134586
[email protected]49639fa2011-12-20 23:22:414587 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134588
bnc691fda62016-08-12 00:43:164589 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:014590 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134591
4592 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014593 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134594
bnc691fda62016-08-12 00:43:164595 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134596
wezca1070932016-05-26 20:30:524597 ASSERT_TRUE(response_restart);
4598 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134599 EXPECT_EQ(200, response_restart->headers->response_code());
4600 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524601 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134602}
4603
[email protected]d9da5fe2010-10-13 22:37:164604// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:014605TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274606 HttpRequestInfo request;
4607 request.method = "GET";
bncce36dca22015-04-21 22:11:234608 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274609 request.load_flags = 0;
4610
[email protected]d9da5fe2010-10-13 22:37:164611 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034612 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514613 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074614 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094615 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164616
bnc691fda62016-08-12 00:43:164617 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164618
bncce36dca22015-04-21 22:11:234619 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414620 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234621 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4622 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164623
bncce36dca22015-04-21 22:11:234624 const char get[] =
4625 "GET / HTTP/1.1\r\n"
4626 "Host: www.example.org\r\n"
4627 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414628 SpdySerializedFrame wrapped_get(
4629 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:154630 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164631 const char resp[] = "HTTP/1.1 200 OK\r\n"
4632 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414633 SpdySerializedFrame wrapped_get_resp(
4634 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
4635 SpdySerializedFrame wrapped_body(
4636 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
4637 SpdySerializedFrame window_update(
4638 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:044639
4640 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414641 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4642 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044643 };
4644
[email protected]d9da5fe2010-10-13 22:37:164645 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414646 CreateMockRead(conn_resp, 1, ASYNC),
4647 CreateMockRead(wrapped_get_resp, 3, ASYNC),
4648 CreateMockRead(wrapped_body, 4, ASYNC),
4649 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134650 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164651 };
4652
rch8e6c6c42015-05-01 14:05:134653 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4654 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074655 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164656
[email protected]8ddf8322012-02-23 18:08:064657 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364658 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074659 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064660 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074661 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164662
[email protected]49639fa2011-12-20 23:22:414663 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164664
bnc691fda62016-08-12 00:43:164665 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014666 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164667
4668 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014669 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164670
[email protected]58e32bb2013-01-21 18:23:254671 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164672 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254673 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4674
bnc691fda62016-08-12 00:43:164675 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524676 ASSERT_TRUE(response);
4677 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:164678 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4679
4680 std::string response_data;
bnc691fda62016-08-12 00:43:164681 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:164682 EXPECT_EQ("1234567890", response_data);
4683}
4684
4685// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:014686TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
4687 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:384688
[email protected]cb9bf6ca2011-01-28 13:15:274689 HttpRequestInfo request;
4690 request.method = "GET";
bncce36dca22015-04-21 22:11:234691 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274692 request.load_flags = 0;
4693
[email protected]d9da5fe2010-10-13 22:37:164694 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034695 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514696 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074697 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094698 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164699
bnc691fda62016-08-12 00:43:164700 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164701
bncce36dca22015-04-21 22:11:234702 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414703 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234704 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4705 // fetch https://www.example.org/ via SPDY
4706 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:414707 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:494708 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414709 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:154710 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414711 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:154712 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414713 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024714 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:414715 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
4716 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:024717 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:414718 SpdySerializedFrame window_update_get_resp(
4719 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
4720 SpdySerializedFrame window_update_body(
4721 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:044722
4723 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414724 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4725 CreateMockWrite(window_update_get_resp, 6),
4726 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:044727 };
4728
[email protected]d9da5fe2010-10-13 22:37:164729 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414730 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:094731 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:414732 CreateMockRead(wrapped_get_resp, 4, ASYNC),
4733 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134734 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164735 };
4736
rch32320842015-05-16 15:57:094737 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4738 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074739 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164740
[email protected]8ddf8322012-02-23 18:08:064741 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364742 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074743 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064744 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364745 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074746 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164747
[email protected]49639fa2011-12-20 23:22:414748 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164749
bnc691fda62016-08-12 00:43:164750 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014751 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164752
rch32320842015-05-16 15:57:094753 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:554754 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:094755 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:594756 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:164757 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014758 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164759
[email protected]58e32bb2013-01-21 18:23:254760 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164761 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254762 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4763
bnc691fda62016-08-12 00:43:164764 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524765 ASSERT_TRUE(response);
4766 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024767 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:164768
4769 std::string response_data;
bnc691fda62016-08-12 00:43:164770 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234771 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:164772}
4773
4774// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014775TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:274776 HttpRequestInfo request;
4777 request.method = "GET";
bncce36dca22015-04-21 22:11:234778 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274779 request.load_flags = 0;
4780
[email protected]d9da5fe2010-10-13 22:37:164781 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034782 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514783 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074784 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094785 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164786
bnc691fda62016-08-12 00:43:164787 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164788
bncce36dca22015-04-21 22:11:234789 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414790 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234791 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:414792 SpdySerializedFrame get(
[email protected]c10b20852013-05-15 21:29:204793 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:164794
4795 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414796 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:164797 };
4798
bnc42331402016-07-25 13:36:154799 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:414800 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:164801 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414802 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:164803 };
4804
rch8e6c6c42015-05-01 14:05:134805 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4806 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074807 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164808
[email protected]8ddf8322012-02-23 18:08:064809 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364810 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074811 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064812 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364813 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074814 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164815
[email protected]49639fa2011-12-20 23:22:414816 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164817
bnc691fda62016-08-12 00:43:164818 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014819 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164820
4821 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014822 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:164823
ttuttle960fcbf2016-04-19 13:26:324824 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:164825}
4826
[email protected]f6c63db52013-02-02 00:35:224827// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4828// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:014829TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224830 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
4831 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034832 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514833 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074834 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094835 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504836 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224837
4838 HttpRequestInfo request1;
4839 request1.method = "GET";
bncce36dca22015-04-21 22:11:234840 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224841 request1.load_flags = 0;
4842
4843 HttpRequestInfo request2;
4844 request2.method = "GET";
bncce36dca22015-04-21 22:11:234845 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224846 request2.load_flags = 0;
4847
bncce36dca22015-04-21 22:11:234848 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:414849 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234850 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:154851 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224852
bncce36dca22015-04-21 22:11:234853 // Fetch https://www.example.org/ via HTTP.
4854 const char get1[] =
4855 "GET / HTTP/1.1\r\n"
4856 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224857 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414858 SpdySerializedFrame wrapped_get1(
4859 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224860 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4861 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414862 SpdySerializedFrame wrapped_get_resp1(
4863 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
4864 SpdySerializedFrame wrapped_body1(
4865 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
4866 SpdySerializedFrame window_update(
4867 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:224868
bncce36dca22015-04-21 22:11:234869 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:294870 SpdyHeaderBlock connect2_block;
4871 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnca9b9e222016-07-11 20:10:404872 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
bnc42331402016-07-25 13:36:154873 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
4874 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:394875
bnc42331402016-07-25 13:36:154876 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:224877
bncce36dca22015-04-21 22:11:234878 // Fetch https://mail.example.org/ via HTTP.
4879 const char get2[] =
4880 "GET / HTTP/1.1\r\n"
4881 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224882 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414883 SpdySerializedFrame wrapped_get2(
4884 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224885 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4886 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414887 SpdySerializedFrame wrapped_get_resp2(
4888 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
4889 SpdySerializedFrame wrapped_body2(
4890 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224891
4892 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414893 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
4894 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:224895 };
4896
4897 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414898 CreateMockRead(conn_resp1, 1, ASYNC),
4899 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
4900 CreateMockRead(wrapped_body1, 4, ASYNC),
4901 CreateMockRead(conn_resp2, 6, ASYNC),
4902 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
4903 CreateMockRead(wrapped_body2, 9, ASYNC),
4904 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:224905 };
4906
mmenke11eb5152015-06-09 14:50:504907 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4908 arraysize(spdy_writes));
4909 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224910
4911 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364912 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:504913 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224914 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504915 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224916 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504917 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:224918
4919 TestCompletionCallback callback;
4920
bnc691fda62016-08-12 00:43:164921 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:204922 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014923 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:224924
4925 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164926 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:224927 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4928
bnc691fda62016-08-12 00:43:164929 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524930 ASSERT_TRUE(response);
4931 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:224932 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4933
4934 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294935 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:164936 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:504937 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224938
bnc691fda62016-08-12 00:43:164939 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:204940 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014941 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:224942
4943 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:164944 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:224945 // Even though the SPDY connection is reused, a new tunnelled connection has
4946 // to be created, so the socket's load timing looks like a fresh connection.
4947 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
4948
4949 // The requests should have different IDs, since they each are using their own
4950 // separate stream.
4951 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4952
bnc691fda62016-08-12 00:43:164953 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:504954 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224955}
4956
4957// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4958// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:014959TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224960 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
4961 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034962 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514963 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074964 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094965 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504966 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224967
4968 HttpRequestInfo request1;
4969 request1.method = "GET";
bncce36dca22015-04-21 22:11:234970 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224971 request1.load_flags = 0;
4972
4973 HttpRequestInfo request2;
4974 request2.method = "GET";
bncce36dca22015-04-21 22:11:234975 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:224976 request2.load_flags = 0;
4977
bncce36dca22015-04-21 22:11:234978 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:414979 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234980 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:154981 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224982
bncce36dca22015-04-21 22:11:234983 // Fetch https://www.example.org/ via HTTP.
4984 const char get1[] =
4985 "GET / HTTP/1.1\r\n"
4986 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224987 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414988 SpdySerializedFrame wrapped_get1(
4989 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224990 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4991 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414992 SpdySerializedFrame wrapped_get_resp1(
4993 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
4994 SpdySerializedFrame wrapped_body1(
4995 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
4996 SpdySerializedFrame window_update(
4997 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:224998
bncce36dca22015-04-21 22:11:234999 // Fetch https://www.example.org/2 via HTTP.
5000 const char get2[] =
5001 "GET /2 HTTP/1.1\r\n"
5002 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225003 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415004 SpdySerializedFrame wrapped_get2(
5005 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225006 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5007 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415008 SpdySerializedFrame wrapped_get_resp2(
5009 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5010 SpdySerializedFrame wrapped_body2(
5011 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225012
5013 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415014 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5015 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225016 };
5017
5018 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415019 CreateMockRead(conn_resp1, 1, ASYNC),
5020 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5021 CreateMockRead(wrapped_body1, 4, ASYNC),
5022 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
5023 CreateMockRead(wrapped_body2, 7, ASYNC),
5024 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225025 };
5026
mmenke11eb5152015-06-09 14:50:505027 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5028 arraysize(spdy_writes));
5029 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225030
5031 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365032 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505033 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225034 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505035 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225036
5037 TestCompletionCallback callback;
5038
bnc691fda62016-08-12 00:43:165039 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:505040 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:205041 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225043
5044 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015045 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225046
5047 LoadTimingInfo load_timing_info;
5048 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5049 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5050
5051 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525052 ASSERT_TRUE(response);
5053 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225054 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5055
5056 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295057 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505058 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225059 trans.reset();
5060
bnc691fda62016-08-12 00:43:165061 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:505062 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:205063 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015064 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225065
[email protected]f6c63db52013-02-02 00:35:225066 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015067 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225068
5069 LoadTimingInfo load_timing_info2;
5070 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5071 TestLoadTimingReused(load_timing_info2);
5072
5073 // The requests should have the same ID.
5074 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5075
[email protected]90499482013-06-01 00:39:505076 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225077}
5078
5079// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5080// Proxy to different servers.
bncd16676a2016-07-20 16:23:015081TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225082 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035083 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515084 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075085 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095086 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505087 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225088
5089 HttpRequestInfo request1;
5090 request1.method = "GET";
bncce36dca22015-04-21 22:11:235091 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225092 request1.load_flags = 0;
5093
5094 HttpRequestInfo request2;
5095 request2.method = "GET";
bncce36dca22015-04-21 22:11:235096 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225097 request2.load_flags = 0;
5098
bncce36dca22015-04-21 22:11:235099 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265100 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235101 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415102 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155103 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5104 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415105 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385106 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225107
bncce36dca22015-04-21 22:11:235108 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265109 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235110 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415111 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155112 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5113 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415114 SpdySerializedFrame body2(
5115 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225116
5117 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415118 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225119 };
5120
5121 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415122 CreateMockRead(get_resp1, 1, ASYNC),
5123 CreateMockRead(body1, 2, ASYNC),
5124 CreateMockRead(get_resp2, 4, ASYNC),
5125 CreateMockRead(body2, 5, ASYNC),
5126 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225127 };
5128
mmenke11eb5152015-06-09 14:50:505129 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5130 arraysize(spdy_writes));
5131 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225132
5133 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365134 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505135 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225136
5137 TestCompletionCallback callback;
5138
bnc691fda62016-08-12 00:43:165139 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:505140 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:205141 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015142 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225143
5144 LoadTimingInfo load_timing_info;
5145 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5146 TestLoadTimingNotReused(load_timing_info,
5147 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5148
5149 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525150 ASSERT_TRUE(response);
5151 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025152 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225153
5154 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295155 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505156 rv = trans->Read(buf.get(), 256, callback.callback());
5157 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225158 // Delete the first request, so the second one can reuse the socket.
5159 trans.reset();
5160
bnc691fda62016-08-12 00:43:165161 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205162 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015163 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225164
5165 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165166 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225167 TestLoadTimingReused(load_timing_info2);
5168
5169 // The requests should have the same ID.
5170 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5171
bnc691fda62016-08-12 00:43:165172 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505173 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225174}
5175
[email protected]2df19bb2010-08-25 20:13:465176// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015177TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465178 HttpRequestInfo request;
5179 request.method = "GET";
bncce36dca22015-04-21 22:11:235180 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465181 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295182 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465183
[email protected]79cb5c12011-09-12 13:12:045184 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035185 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515186 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075187 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095188 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275189
[email protected]2df19bb2010-08-25 20:13:465190 // Since we have proxy, should use full url
5191 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165192 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5193 "Host: www.example.org\r\n"
5194 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465195
bnc691fda62016-08-12 00:43:165196 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235197 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165198 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5199 "Host: www.example.org\r\n"
5200 "Proxy-Connection: keep-alive\r\n"
5201 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465202 };
5203
5204 // The proxy responds to the GET with a 407, using a persistent
5205 // connection.
5206 MockRead data_reads1[] = {
5207 // No credentials.
5208 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5209 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5210 MockRead("Proxy-Connection: keep-alive\r\n"),
5211 MockRead("Content-Length: 0\r\n\r\n"),
5212
5213 MockRead("HTTP/1.1 200 OK\r\n"),
5214 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5215 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065216 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465217 };
5218
5219 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5220 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075221 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065222 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075223 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465224
[email protected]49639fa2011-12-20 23:22:415225 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465226
bnc691fda62016-08-12 00:43:165227 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505228
bnc691fda62016-08-12 00:43:165229 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465231
5232 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015233 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465234
[email protected]58e32bb2013-01-21 18:23:255235 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165236 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255237 TestLoadTimingNotReused(load_timing_info,
5238 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5239
bnc691fda62016-08-12 00:43:165240 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525241 ASSERT_TRUE(response);
5242 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465243 EXPECT_EQ(407, response->headers->response_code());
5244 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435245 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465246
[email protected]49639fa2011-12-20 23:22:415247 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465248
bnc691fda62016-08-12 00:43:165249 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465251
5252 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015253 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465254
[email protected]58e32bb2013-01-21 18:23:255255 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165256 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255257 // Retrying with HTTP AUTH is considered to be reusing a socket.
5258 TestLoadTimingReused(load_timing_info);
5259
bnc691fda62016-08-12 00:43:165260 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525261 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465262
5263 EXPECT_TRUE(response->headers->IsKeepAlive());
5264 EXPECT_EQ(200, response->headers->response_code());
5265 EXPECT_EQ(100, response->headers->GetContentLength());
5266 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5267
5268 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525269 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465270}
5271
[email protected]23e482282013-06-14 16:08:025272void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085273 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425274 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085275 request.method = "GET";
bncce36dca22015-04-21 22:11:235276 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085277 request.load_flags = 0;
5278
[email protected]cb9bf6ca2011-01-28 13:15:275279 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035280 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095281 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275282
[email protected]c744cf22009-02-27 07:28:085283 // Since we have proxy, should try to establish tunnel.
5284 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175285 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5286 "Host: www.example.org:443\r\n"
5287 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085288 };
5289
5290 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235291 status, MockRead("Content-Length: 10\r\n\r\n"),
5292 // No response body because the test stops reading here.
5293 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085294 };
5295
[email protected]31a2bfe2010-02-09 08:03:395296 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5297 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075298 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085299
[email protected]49639fa2011-12-20 23:22:415300 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085301
bnc691fda62016-08-12 00:43:165302 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505303
tfarina42834112016-09-22 13:38:205304 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085306
5307 rv = callback.WaitForResult();
5308 EXPECT_EQ(expected_status, rv);
5309}
5310
[email protected]23e482282013-06-14 16:08:025311void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235312 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085313 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425314 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085315}
5316
bncd16676a2016-07-20 16:23:015317TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085318 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5319}
5320
bncd16676a2016-07-20 16:23:015321TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085322 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5323}
5324
bncd16676a2016-07-20 16:23:015325TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085326 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5327}
5328
bncd16676a2016-07-20 16:23:015329TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085330 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5331}
5332
bncd16676a2016-07-20 16:23:015333TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085334 ConnectStatusHelper(
5335 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5336}
5337
bncd16676a2016-07-20 16:23:015338TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085339 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5340}
5341
bncd16676a2016-07-20 16:23:015342TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085343 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5344}
5345
bncd16676a2016-07-20 16:23:015346TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085347 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5348}
5349
bncd16676a2016-07-20 16:23:015350TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085351 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5352}
5353
bncd16676a2016-07-20 16:23:015354TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085355 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5356}
5357
bncd16676a2016-07-20 16:23:015358TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085359 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5360}
5361
bncd16676a2016-07-20 16:23:015362TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085363 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5364}
5365
bncd16676a2016-07-20 16:23:015366TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085367 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5368}
5369
bncd16676a2016-07-20 16:23:015370TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085371 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5372}
5373
bncd16676a2016-07-20 16:23:015374TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085375 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5376}
5377
bncd16676a2016-07-20 16:23:015378TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085379 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5380}
5381
bncd16676a2016-07-20 16:23:015382TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375383 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5384}
5385
bncd16676a2016-07-20 16:23:015386TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085387 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5388}
5389
bncd16676a2016-07-20 16:23:015390TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085391 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5392}
5393
bncd16676a2016-07-20 16:23:015394TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085395 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5396}
5397
bncd16676a2016-07-20 16:23:015398TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085399 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5400}
5401
bncd16676a2016-07-20 16:23:015402TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085403 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5404}
5405
bncd16676a2016-07-20 16:23:015406TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085407 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5408}
5409
bncd16676a2016-07-20 16:23:015410TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085411 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5412}
5413
bncd16676a2016-07-20 16:23:015414TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085415 ConnectStatusHelperWithExpectedStatus(
5416 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545417 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085418}
5419
bncd16676a2016-07-20 16:23:015420TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085421 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5422}
5423
bncd16676a2016-07-20 16:23:015424TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085425 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5426}
5427
bncd16676a2016-07-20 16:23:015428TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085429 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5430}
5431
bncd16676a2016-07-20 16:23:015432TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085433 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5434}
5435
bncd16676a2016-07-20 16:23:015436TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085437 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5438}
5439
bncd16676a2016-07-20 16:23:015440TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085441 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5442}
5443
bncd16676a2016-07-20 16:23:015444TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085445 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5446}
5447
bncd16676a2016-07-20 16:23:015448TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085449 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5450}
5451
bncd16676a2016-07-20 16:23:015452TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085453 ConnectStatusHelper(
5454 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5455}
5456
bncd16676a2016-07-20 16:23:015457TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085458 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5459}
5460
bncd16676a2016-07-20 16:23:015461TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085462 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5463}
5464
bncd16676a2016-07-20 16:23:015465TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085466 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5467}
5468
bncd16676a2016-07-20 16:23:015469TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085470 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5471}
5472
bncd16676a2016-07-20 16:23:015473TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085474 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5475}
5476
bncd16676a2016-07-20 16:23:015477TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085478 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5479}
5480
bncd16676a2016-07-20 16:23:015481TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085482 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5483}
5484
[email protected]038e9a32008-10-08 22:40:165485// Test the flow when both the proxy server AND origin server require
5486// authentication. Again, this uses basic auth for both since that is
5487// the simplest to mock.
bncd16676a2016-07-20 16:23:015488TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275489 HttpRequestInfo request;
5490 request.method = "GET";
bncce36dca22015-04-21 22:11:235491 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275492 request.load_flags = 0;
5493
[email protected]038e9a32008-10-08 22:40:165494 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035495 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095496 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075497
bnc691fda62016-08-12 00:43:165498 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:165499
[email protected]f9ee6b52008-11-08 06:46:235500 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235501 MockWrite(
5502 "GET http://www.example.org/ HTTP/1.1\r\n"
5503 "Host: www.example.org\r\n"
5504 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235505 };
5506
[email protected]038e9a32008-10-08 22:40:165507 MockRead data_reads1[] = {
5508 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5509 // Give a couple authenticate options (only the middle one is actually
5510 // supported).
[email protected]22927ad2009-09-21 19:56:195511 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165512 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5513 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5514 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5515 // Large content-length -- won't matter, as connection will be reset.
5516 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065517 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165518 };
5519
bnc691fda62016-08-12 00:43:165520 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:165521 // request we should be issuing -- the final header line contains the
5522 // proxy's credentials.
5523 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235524 MockWrite(
5525 "GET http://www.example.org/ HTTP/1.1\r\n"
5526 "Host: www.example.org\r\n"
5527 "Proxy-Connection: keep-alive\r\n"
5528 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165529 };
5530
5531 // Now the proxy server lets the request pass through to origin server.
5532 // The origin server responds with a 401.
5533 MockRead data_reads2[] = {
5534 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5535 // Note: We are using the same realm-name as the proxy server. This is
5536 // completely valid, as realms are unique across hosts.
5537 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5538 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5539 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065540 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165541 };
5542
bnc691fda62016-08-12 00:43:165543 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:165544 // the credentials for both the proxy and origin server.
5545 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235546 MockWrite(
5547 "GET http://www.example.org/ HTTP/1.1\r\n"
5548 "Host: www.example.org\r\n"
5549 "Proxy-Connection: keep-alive\r\n"
5550 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5551 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165552 };
5553
5554 // Lastly we get the desired content.
5555 MockRead data_reads3[] = {
5556 MockRead("HTTP/1.0 200 OK\r\n"),
5557 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5558 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065559 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165560 };
5561
[email protected]31a2bfe2010-02-09 08:03:395562 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5563 data_writes1, arraysize(data_writes1));
5564 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5565 data_writes2, arraysize(data_writes2));
5566 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5567 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075568 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5569 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5570 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165571
[email protected]49639fa2011-12-20 23:22:415572 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165573
tfarina42834112016-09-22 13:38:205574 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015575 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165576
5577 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015578 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165579
bnc691fda62016-08-12 00:43:165580 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525581 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045582 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165583
[email protected]49639fa2011-12-20 23:22:415584 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165585
bnc691fda62016-08-12 00:43:165586 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015587 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165588
5589 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015590 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165591
bnc691fda62016-08-12 00:43:165592 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525593 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045594 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165595
[email protected]49639fa2011-12-20 23:22:415596 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165597
bnc691fda62016-08-12 00:43:165598 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5599 callback3.callback());
robpercival214763f2016-07-01 23:27:015600 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165601
5602 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015603 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165604
bnc691fda62016-08-12 00:43:165605 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525606 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165607 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165608}
[email protected]4ddaf2502008-10-23 18:26:195609
[email protected]ea9dc9a2009-09-05 00:43:325610// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5611// can't hook into its internals to cause it to generate predictable NTLM
5612// authorization headers.
5613#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295614// The NTLM authentication unit tests were generated by capturing the HTTP
5615// requests and responses using Fiddler 2 and inspecting the generated random
5616// bytes in the debugger.
5617
5618// Enter the correct password and authenticate successfully.
bncd16676a2016-07-20 16:23:015619TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425620 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245621 request.method = "GET";
5622 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545623
5624 // Ensure load is not disrupted by flags which suppress behaviour specific
5625 // to other auth schemes.
5626 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245627
[email protected]cb9bf6ca2011-01-28 13:15:275628 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5629 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095630 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275631
[email protected]3f918782009-02-28 01:29:245632 MockWrite data_writes1[] = {
5633 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5634 "Host: 172.22.68.17\r\n"
5635 "Connection: keep-alive\r\n\r\n"),
5636 };
5637
5638 MockRead data_reads1[] = {
5639 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045640 // Negotiate and NTLM are often requested together. However, we only want
5641 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5642 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245643 MockRead("WWW-Authenticate: NTLM\r\n"),
5644 MockRead("Connection: close\r\n"),
5645 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365646 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245647 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065648 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245649 };
5650
5651 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165652 // After restarting with a null identity, this is the
5653 // request we should be issuing -- the final header line contains a Type
5654 // 1 message.
5655 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5656 "Host: 172.22.68.17\r\n"
5657 "Connection: keep-alive\r\n"
5658 "Authorization: NTLM "
5659 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245660
bnc691fda62016-08-12 00:43:165661 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5662 // (the credentials for the origin server). The second request continues
5663 // on the same connection.
5664 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5665 "Host: 172.22.68.17\r\n"
5666 "Connection: keep-alive\r\n"
5667 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5668 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5669 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5670 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5671 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245672 };
5673
5674 MockRead data_reads2[] = {
5675 // The origin server responds with a Type 2 message.
5676 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5677 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295678 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245679 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5680 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5681 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5682 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5683 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5684 "BtAAAAAAA=\r\n"),
5685 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365686 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245687 MockRead("You are not authorized to view this page\r\n"),
5688
5689 // Lastly we get the desired content.
5690 MockRead("HTTP/1.1 200 OK\r\n"),
5691 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5692 MockRead("Content-Length: 13\r\n\r\n"),
5693 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065694 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245695 };
5696
[email protected]31a2bfe2010-02-09 08:03:395697 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5698 data_writes1, arraysize(data_writes1));
5699 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5700 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075701 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5702 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245703
[email protected]49639fa2011-12-20 23:22:415704 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245705
bnc691fda62016-08-12 00:43:165706 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505707
tfarina42834112016-09-22 13:38:205708 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015709 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245710
5711 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015712 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245713
bnc691fda62016-08-12 00:43:165714 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:225715
bnc691fda62016-08-12 00:43:165716 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525717 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045718 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245719
[email protected]49639fa2011-12-20 23:22:415720 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255721
bnc691fda62016-08-12 00:43:165722 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
5723 callback2.callback());
robpercival214763f2016-07-01 23:27:015724 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:255725
5726 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015727 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:255728
bnc691fda62016-08-12 00:43:165729 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:255730
bnc691fda62016-08-12 00:43:165731 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525732 ASSERT_TRUE(response);
5733 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:255734
[email protected]49639fa2011-12-20 23:22:415735 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245736
bnc691fda62016-08-12 00:43:165737 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:015738 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245739
[email protected]0757e7702009-03-27 04:00:225740 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015741 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245742
bnc691fda62016-08-12 00:43:165743 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525744 ASSERT_TRUE(response);
5745 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:245746 EXPECT_EQ(13, response->headers->GetContentLength());
5747}
5748
[email protected]385a4672009-03-11 22:21:295749// Enter a wrong password, and then the correct one.
bncd16676a2016-07-20 16:23:015750TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425751 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295752 request.method = "GET";
5753 request.url = GURL("http://172.22.68.17/kids/login.aspx");
5754 request.load_flags = 0;
5755
[email protected]cb9bf6ca2011-01-28 13:15:275756 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5757 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275759
[email protected]385a4672009-03-11 22:21:295760 MockWrite data_writes1[] = {
5761 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5762 "Host: 172.22.68.17\r\n"
5763 "Connection: keep-alive\r\n\r\n"),
5764 };
5765
5766 MockRead data_reads1[] = {
5767 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045768 // Negotiate and NTLM are often requested together. However, we only want
5769 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5770 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:295771 MockRead("WWW-Authenticate: NTLM\r\n"),
5772 MockRead("Connection: close\r\n"),
5773 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365774 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295775 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065776 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295777 };
5778
5779 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165780 // After restarting with a null identity, this is the
5781 // request we should be issuing -- the final header line contains a Type
5782 // 1 message.
5783 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5784 "Host: 172.22.68.17\r\n"
5785 "Connection: keep-alive\r\n"
5786 "Authorization: NTLM "
5787 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295788
bnc691fda62016-08-12 00:43:165789 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5790 // (the credentials for the origin server). The second request continues
5791 // on the same connection.
5792 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5793 "Host: 172.22.68.17\r\n"
5794 "Connection: keep-alive\r\n"
5795 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5796 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5797 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
5798 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
5799 "4Ww7b7E=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295800 };
5801
5802 MockRead data_reads2[] = {
5803 // The origin server responds with a Type 2 message.
5804 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5805 MockRead("WWW-Authenticate: NTLM "
5806 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
5807 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5808 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5809 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5810 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5811 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5812 "BtAAAAAAA=\r\n"),
5813 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365814 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295815 MockRead("You are not authorized to view this page\r\n"),
5816
5817 // Wrong password.
5818 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:295819 MockRead("WWW-Authenticate: NTLM\r\n"),
5820 MockRead("Connection: close\r\n"),
5821 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365822 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295823 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065824 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295825 };
5826
5827 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:165828 // After restarting with a null identity, this is the
5829 // request we should be issuing -- the final header line contains a Type
5830 // 1 message.
5831 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5832 "Host: 172.22.68.17\r\n"
5833 "Connection: keep-alive\r\n"
5834 "Authorization: NTLM "
5835 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295836
bnc691fda62016-08-12 00:43:165837 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5838 // (the credentials for the origin server). The second request continues
5839 // on the same connection.
5840 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5841 "Host: 172.22.68.17\r\n"
5842 "Connection: keep-alive\r\n"
5843 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5844 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5845 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
5846 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
5847 "+4MUm7c=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295848 };
5849
5850 MockRead data_reads3[] = {
5851 // The origin server responds with a Type 2 message.
5852 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5853 MockRead("WWW-Authenticate: NTLM "
5854 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
5855 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5856 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5857 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5858 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5859 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5860 "BtAAAAAAA=\r\n"),
5861 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365862 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295863 MockRead("You are not authorized to view this page\r\n"),
5864
5865 // Lastly we get the desired content.
5866 MockRead("HTTP/1.1 200 OK\r\n"),
5867 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5868 MockRead("Content-Length: 13\r\n\r\n"),
5869 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065870 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:295871 };
5872
[email protected]31a2bfe2010-02-09 08:03:395873 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5874 data_writes1, arraysize(data_writes1));
5875 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5876 data_writes2, arraysize(data_writes2));
5877 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5878 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075879 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5880 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5881 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:295882
[email protected]49639fa2011-12-20 23:22:415883 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:295884
bnc691fda62016-08-12 00:43:165885 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505886
tfarina42834112016-09-22 13:38:205887 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015888 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:295889
5890 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015891 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:295892
bnc691fda62016-08-12 00:43:165893 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:295894
bnc691fda62016-08-12 00:43:165895 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525896 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045897 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:295898
[email protected]49639fa2011-12-20 23:22:415899 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:295900
[email protected]0757e7702009-03-27 04:00:225901 // Enter the wrong password.
bnc691fda62016-08-12 00:43:165902 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
5903 callback2.callback());
robpercival214763f2016-07-01 23:27:015904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:295905
[email protected]10af5fe72011-01-31 16:17:255906 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015907 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:295908
bnc691fda62016-08-12 00:43:165909 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415910 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:165911 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:015912 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:255913 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015914 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:165915 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:225916
bnc691fda62016-08-12 00:43:165917 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525918 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045919 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:225920
[email protected]49639fa2011-12-20 23:22:415921 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:225922
5923 // Now enter the right password.
bnc691fda62016-08-12 00:43:165924 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
5925 callback4.callback());
robpercival214763f2016-07-01 23:27:015926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:255927
5928 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:015929 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:255930
bnc691fda62016-08-12 00:43:165931 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:255932
[email protected]49639fa2011-12-20 23:22:415933 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:255934
5935 // One more roundtrip
bnc691fda62016-08-12 00:43:165936 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:015937 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:225938
5939 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:015940 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:225941
bnc691fda62016-08-12 00:43:165942 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525943 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:295944 EXPECT_EQ(13, response->headers->GetContentLength());
5945}
[email protected]ea9dc9a2009-09-05 00:43:325946#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:295947
[email protected]4ddaf2502008-10-23 18:26:195948// Test reading a server response which has only headers, and no body.
5949// After some maximum number of bytes is consumed, the transaction should
5950// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:015951TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:425952 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:195953 request.method = "GET";
bncce36dca22015-04-21 22:11:235954 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:195955 request.load_flags = 0;
5956
danakj1fd259a02016-04-16 03:17:095957 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:165958 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:275959
[email protected]b75b7b2f2009-10-06 00:54:535960 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:435961 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:535962 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:195963
5964 MockRead data_reads[] = {
5965 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065966 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:195967 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:065968 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:195969 };
[email protected]31a2bfe2010-02-09 08:03:395970 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075971 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:195972
[email protected]49639fa2011-12-20 23:22:415973 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:195974
tfarina42834112016-09-22 13:38:205975 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:195977
5978 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015979 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:195980}
[email protected]f4e426b2008-11-05 00:24:495981
5982// Make sure that we don't try to reuse a TCPClientSocket when failing to
5983// establish tunnel.
5984// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:015985TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275986 HttpRequestInfo request;
5987 request.method = "GET";
bncce36dca22015-04-21 22:11:235988 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275989 request.load_flags = 0;
5990
[email protected]f4e426b2008-11-05 00:24:495991 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035992 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:015993
danakj1fd259a02016-04-16 03:17:095994 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495995
bnc691fda62016-08-12 00:43:165996 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:505997 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495998
[email protected]f4e426b2008-11-05 00:24:495999 // Since we have proxy, should try to establish tunnel.
6000 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176001 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6002 "Host: www.example.org:443\r\n"
6003 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496004 };
6005
[email protected]77848d12008-11-14 00:00:226006 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496007 // connection. Usually a proxy would return 501 (not implemented),
6008 // or 200 (tunnel established).
6009 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236010 MockRead("HTTP/1.1 404 Not Found\r\n"),
6011 MockRead("Content-Length: 10\r\n\r\n"),
6012 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496013 };
6014
[email protected]31a2bfe2010-02-09 08:03:396015 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6016 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076017 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496018
[email protected]49639fa2011-12-20 23:22:416019 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496020
tfarina42834112016-09-22 13:38:206021 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016022 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496023
6024 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016025 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496026
[email protected]b4404c02009-04-10 16:38:526027 // Empty the current queue. This is necessary because idle sockets are
6028 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556029 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526030
[email protected]f4e426b2008-11-05 00:24:496031 // We now check to make sure the TCPClientSocket was not added back to
6032 // the pool.
[email protected]90499482013-06-01 00:39:506033 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496034 trans.reset();
fdoray92e35a72016-06-10 15:54:556035 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496036 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506037 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496038}
[email protected]372d34a2008-11-05 21:30:516039
[email protected]1b157c02009-04-21 01:55:406040// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016041TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426042 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406043 request.method = "GET";
bncce36dca22015-04-21 22:11:236044 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406045 request.load_flags = 0;
6046
danakj1fd259a02016-04-16 03:17:096047 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276048
bnc691fda62016-08-12 00:43:166049 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276050
[email protected]1b157c02009-04-21 01:55:406051 MockRead data_reads[] = {
6052 // A part of the response body is received with the response headers.
6053 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6054 // The rest of the response body is received in two parts.
6055 MockRead("lo"),
6056 MockRead(" world"),
6057 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066058 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406059 };
6060
[email protected]31a2bfe2010-02-09 08:03:396061 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076062 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406063
[email protected]49639fa2011-12-20 23:22:416064 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406065
tfarina42834112016-09-22 13:38:206066 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406068
6069 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016070 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406071
bnc691fda62016-08-12 00:43:166072 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526073 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406074
wezca1070932016-05-26 20:30:526075 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406076 std::string status_line = response->headers->GetStatusLine();
6077 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6078
[email protected]90499482013-06-01 00:39:506079 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406080
6081 std::string response_data;
bnc691fda62016-08-12 00:43:166082 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016083 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406084 EXPECT_EQ("hello world", response_data);
6085
6086 // Empty the current queue. This is necessary because idle sockets are
6087 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556088 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406089
6090 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506091 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406092}
6093
[email protected]76a505b2010-08-25 06:23:006094// Make sure that we recycle a SSL socket after reading all of the response
6095// body.
bncd16676a2016-07-20 16:23:016096TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006097 HttpRequestInfo request;
6098 request.method = "GET";
bncce36dca22015-04-21 22:11:236099 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006100 request.load_flags = 0;
6101
6102 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236103 MockWrite(
6104 "GET / HTTP/1.1\r\n"
6105 "Host: www.example.org\r\n"
6106 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006107 };
6108
6109 MockRead data_reads[] = {
6110 MockRead("HTTP/1.1 200 OK\r\n"),
6111 MockRead("Content-Length: 11\r\n\r\n"),
6112 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066113 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006114 };
6115
[email protected]8ddf8322012-02-23 18:08:066116 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076117 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006118
6119 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6120 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076121 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006122
[email protected]49639fa2011-12-20 23:22:416123 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006124
danakj1fd259a02016-04-16 03:17:096125 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166126 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006127
tfarina42834112016-09-22 13:38:206128 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006129
robpercival214763f2016-07-01 23:27:016130 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6131 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006132
bnc691fda62016-08-12 00:43:166133 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526134 ASSERT_TRUE(response);
6135 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006136 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6137
[email protected]90499482013-06-01 00:39:506138 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006139
6140 std::string response_data;
bnc691fda62016-08-12 00:43:166141 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016142 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006143 EXPECT_EQ("hello world", response_data);
6144
6145 // Empty the current queue. This is necessary because idle sockets are
6146 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556147 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006148
6149 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506150 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006151}
6152
6153// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6154// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016155TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006156 HttpRequestInfo request;
6157 request.method = "GET";
bncce36dca22015-04-21 22:11:236158 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006159 request.load_flags = 0;
6160
6161 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236162 MockWrite(
6163 "GET / HTTP/1.1\r\n"
6164 "Host: www.example.org\r\n"
6165 "Connection: keep-alive\r\n\r\n"),
6166 MockWrite(
6167 "GET / HTTP/1.1\r\n"
6168 "Host: www.example.org\r\n"
6169 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006170 };
6171
6172 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426173 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6174 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006175
[email protected]8ddf8322012-02-23 18:08:066176 SSLSocketDataProvider ssl(ASYNC, OK);
6177 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076178 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6179 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006180
6181 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6182 data_writes, arraysize(data_writes));
6183 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6184 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076185 session_deps_.socket_factory->AddSocketDataProvider(&data);
6186 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006187
[email protected]49639fa2011-12-20 23:22:416188 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006189
danakj1fd259a02016-04-16 03:17:096190 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166191 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:506192 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006193
tfarina42834112016-09-22 13:38:206194 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006195
robpercival214763f2016-07-01 23:27:016196 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6197 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006198
6199 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526200 ASSERT_TRUE(response);
6201 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006202 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6203
[email protected]90499482013-06-01 00:39:506204 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006205
6206 std::string response_data;
6207 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016208 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006209 EXPECT_EQ("hello world", response_data);
6210
6211 // Empty the current queue. This is necessary because idle sockets are
6212 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556213 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006214
6215 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506216 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006217
6218 // Now start the second transaction, which should reuse the previous socket.
6219
[email protected]90499482013-06-01 00:39:506220 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006221
tfarina42834112016-09-22 13:38:206222 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006223
robpercival214763f2016-07-01 23:27:016224 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6225 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006226
6227 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526228 ASSERT_TRUE(response);
6229 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006230 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6231
[email protected]90499482013-06-01 00:39:506232 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006233
6234 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016235 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006236 EXPECT_EQ("hello world", response_data);
6237
6238 // Empty the current queue. This is necessary because idle sockets are
6239 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556240 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006241
6242 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506243 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006244}
6245
maksim.sisov0adf8592016-07-15 06:25:566246// Grab a socket, use it, and put it back into the pool. Then, make
6247// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016248TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566249 HttpRequestInfo request;
6250 request.method = "GET";
6251 request.url = GURL("http://www.example.org/");
6252 request.load_flags = 0;
6253
6254 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6255
bnc691fda62016-08-12 00:43:166256 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566257
6258 MockRead data_reads[] = {
6259 // A part of the response body is received with the response headers.
6260 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6261 // The rest of the response body is received in two parts.
6262 MockRead("lo"), MockRead(" world"),
6263 MockRead("junk"), // Should not be read!!
6264 MockRead(SYNCHRONOUS, OK),
6265 };
6266
6267 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6268 session_deps_.socket_factory->AddSocketDataProvider(&data);
6269
6270 TestCompletionCallback callback;
6271
tfarina42834112016-09-22 13:38:206272 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566273 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6274
6275 EXPECT_THAT(callback.GetResult(rv), IsOk());
6276
bnc691fda62016-08-12 00:43:166277 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566278 ASSERT_TRUE(response);
6279 EXPECT_TRUE(response->headers);
6280 std::string status_line = response->headers->GetStatusLine();
6281 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6282
6283 // Make memory critical notification and ensure the transaction still has been
6284 // operating right.
6285 base::MemoryPressureListener::NotifyMemoryPressure(
6286 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6287 base::RunLoop().RunUntilIdle();
6288
6289 // Socket should not be flushed as long as it is not idle.
6290 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6291
6292 std::string response_data;
bnc691fda62016-08-12 00:43:166293 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566294 EXPECT_THAT(rv, IsOk());
6295 EXPECT_EQ("hello world", response_data);
6296
6297 // Empty the current queue. This is necessary because idle sockets are
6298 // added to the connection pool asynchronously with a PostTask.
6299 base::RunLoop().RunUntilIdle();
6300
6301 // We now check to make sure the socket was added back to the pool.
6302 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6303
6304 // Idle sockets should be flushed now.
6305 base::MemoryPressureListener::NotifyMemoryPressure(
6306 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6307 base::RunLoop().RunUntilIdle();
6308
6309 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6310}
6311
6312// Grab an SSL socket, use it, and put it back into the pool. Then, make
6313// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016314TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566315 HttpRequestInfo request;
6316 request.method = "GET";
6317 request.url = GURL("https://www.example.org/");
6318 request.load_flags = 0;
6319
6320 MockWrite data_writes[] = {
6321 MockWrite("GET / HTTP/1.1\r\n"
6322 "Host: www.example.org\r\n"
6323 "Connection: keep-alive\r\n\r\n"),
6324 };
6325
6326 MockRead data_reads[] = {
6327 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6328 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6329
6330 SSLSocketDataProvider ssl(ASYNC, OK);
6331 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6332
6333 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6334 arraysize(data_writes));
6335 session_deps_.socket_factory->AddSocketDataProvider(&data);
6336
6337 TestCompletionCallback callback;
6338
6339 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166340 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566341
6342 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:206343 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566344
6345 EXPECT_THAT(callback.GetResult(rv), IsOk());
6346
bnc691fda62016-08-12 00:43:166347 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566348 ASSERT_TRUE(response);
6349 ASSERT_TRUE(response->headers);
6350 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6351
6352 // Make memory critical notification and ensure the transaction still has been
6353 // operating right.
6354 base::MemoryPressureListener::NotifyMemoryPressure(
6355 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6356 base::RunLoop().RunUntilIdle();
6357
6358 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6359
6360 std::string response_data;
bnc691fda62016-08-12 00:43:166361 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566362 EXPECT_THAT(rv, IsOk());
6363 EXPECT_EQ("hello world", response_data);
6364
6365 // Empty the current queue. This is necessary because idle sockets are
6366 // added to the connection pool asynchronously with a PostTask.
6367 base::RunLoop().RunUntilIdle();
6368
6369 // We now check to make sure the socket was added back to the pool.
6370 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6371
6372 // Make memory notification once again and ensure idle socket is closed.
6373 base::MemoryPressureListener::NotifyMemoryPressure(
6374 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6375 base::RunLoop().RunUntilIdle();
6376
6377 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6378}
6379
[email protected]b4404c02009-04-10 16:38:526380// Make sure that we recycle a socket after a zero-length response.
6381// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016382TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426383 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526384 request.method = "GET";
bncce36dca22015-04-21 22:11:236385 request.url = GURL(
6386 "http://www.example.org/csi?v=3&s=web&action=&"
6387 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6388 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6389 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526390 request.load_flags = 0;
6391
danakj1fd259a02016-04-16 03:17:096392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276393
[email protected]b4404c02009-04-10 16:38:526394 MockRead data_reads[] = {
6395 MockRead("HTTP/1.1 204 No Content\r\n"
6396 "Content-Length: 0\r\n"
6397 "Content-Type: text/html\r\n\r\n"),
6398 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066399 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526400 };
6401
[email protected]31a2bfe2010-02-09 08:03:396402 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076403 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526404
mmenkecc2298e2015-12-07 18:20:186405 // Transaction must be created after the MockReads, so it's destroyed before
6406 // them.
bnc691fda62016-08-12 00:43:166407 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186408
[email protected]49639fa2011-12-20 23:22:416409 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526410
tfarina42834112016-09-22 13:38:206411 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016412 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526413
6414 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016415 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526416
bnc691fda62016-08-12 00:43:166417 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526418 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526419
wezca1070932016-05-26 20:30:526420 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526421 std::string status_line = response->headers->GetStatusLine();
6422 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6423
[email protected]90499482013-06-01 00:39:506424 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526425
6426 std::string response_data;
bnc691fda62016-08-12 00:43:166427 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016428 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526429 EXPECT_EQ("", response_data);
6430
6431 // Empty the current queue. This is necessary because idle sockets are
6432 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556433 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526434
6435 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506436 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526437}
6438
bncd16676a2016-07-20 16:23:016439TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096440 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226441 element_readers.push_back(
ricea2deef682016-09-09 08:04:076442 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226443 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276444
[email protected]1c773ea12009-04-28 19:58:426445 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516446 // Transaction 1: a GET request that succeeds. The socket is recycled
6447 // after use.
6448 request[0].method = "GET";
6449 request[0].url = GURL("http://www.google.com/");
6450 request[0].load_flags = 0;
6451 // Transaction 2: a POST request. Reuses the socket kept alive from
6452 // transaction 1. The first attempts fails when writing the POST data.
6453 // This causes the transaction to retry with a new socket. The second
6454 // attempt succeeds.
6455 request[1].method = "POST";
6456 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276457 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516458 request[1].load_flags = 0;
6459
danakj1fd259a02016-04-16 03:17:096460 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516461
6462 // The first socket is used for transaction 1 and the first attempt of
6463 // transaction 2.
6464
6465 // The response of transaction 1.
6466 MockRead data_reads1[] = {
6467 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6468 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066469 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516470 };
6471 // The mock write results of transaction 1 and the first attempt of
6472 // transaction 2.
6473 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066474 MockWrite(SYNCHRONOUS, 64), // GET
6475 MockWrite(SYNCHRONOUS, 93), // POST
6476 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516477 };
[email protected]31a2bfe2010-02-09 08:03:396478 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6479 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516480
6481 // The second socket is used for the second attempt of transaction 2.
6482
6483 // The response of transaction 2.
6484 MockRead data_reads2[] = {
6485 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6486 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066487 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516488 };
6489 // The mock write results of the second attempt of transaction 2.
6490 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066491 MockWrite(SYNCHRONOUS, 93), // POST
6492 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516493 };
[email protected]31a2bfe2010-02-09 08:03:396494 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6495 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516496
[email protected]bb88e1d32013-05-03 23:11:076497 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6498 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516499
thestig9d3bb0c2015-01-24 00:49:516500 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516501 "hello world", "welcome"
6502 };
6503
6504 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:166505 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:516506
[email protected]49639fa2011-12-20 23:22:416507 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516508
tfarina42834112016-09-22 13:38:206509 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016510 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:516511
6512 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016513 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516514
bnc691fda62016-08-12 00:43:166515 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526516 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516517
wezca1070932016-05-26 20:30:526518 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516519 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6520
6521 std::string response_data;
bnc691fda62016-08-12 00:43:166522 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016523 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516524 EXPECT_EQ(kExpectedResponseData[i], response_data);
6525 }
6526}
[email protected]f9ee6b52008-11-08 06:46:236527
6528// Test the request-challenge-retry sequence for basic auth when there is
6529// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166530// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:016531TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426532 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236533 request.method = "GET";
bncce36dca22015-04-21 22:11:236534 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416535 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296536
danakj1fd259a02016-04-16 03:17:096537 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166538 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276539
[email protected]a97cca42009-08-14 01:00:296540 // The password contains an escaped character -- for this test to pass it
6541 // will need to be unescaped by HttpNetworkTransaction.
6542 EXPECT_EQ("b%40r", request.url.password());
6543
[email protected]f9ee6b52008-11-08 06:46:236544 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236545 MockWrite(
6546 "GET / HTTP/1.1\r\n"
6547 "Host: www.example.org\r\n"
6548 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236549 };
6550
6551 MockRead data_reads1[] = {
6552 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6553 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6554 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066555 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236556 };
6557
[email protected]2262e3a2012-05-22 16:08:166558 // After the challenge above, the transaction will be restarted using the
6559 // identity from the url (foo, b@r) to answer the challenge.
6560 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236561 MockWrite(
6562 "GET / HTTP/1.1\r\n"
6563 "Host: www.example.org\r\n"
6564 "Connection: keep-alive\r\n"
6565 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166566 };
6567
6568 MockRead data_reads2[] = {
6569 MockRead("HTTP/1.0 200 OK\r\n"),
6570 MockRead("Content-Length: 100\r\n\r\n"),
6571 MockRead(SYNCHRONOUS, OK),
6572 };
6573
[email protected]31a2bfe2010-02-09 08:03:396574 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6575 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166576 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6577 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076578 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6579 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236580
[email protected]49639fa2011-12-20 23:22:416581 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:206582 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236584 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016585 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166586 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166587
6588 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166589 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016590 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166591 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016592 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166593 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226594
bnc691fda62016-08-12 00:43:166595 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526596 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166597
6598 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526599 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166600
6601 EXPECT_EQ(100, response->headers->GetContentLength());
6602
6603 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556604 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166605}
6606
6607// Test the request-challenge-retry sequence for basic auth when there is an
6608// incorrect identity in the URL. The identity from the URL should be used only
6609// once.
bncd16676a2016-07-20 16:23:016610TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166611 HttpRequestInfo request;
6612 request.method = "GET";
6613 // Note: the URL has a username:password in it. The password "baz" is
6614 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236615 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166616
6617 request.load_flags = LOAD_NORMAL;
6618
danakj1fd259a02016-04-16 03:17:096619 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166620 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:166621
6622 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236623 MockWrite(
6624 "GET / HTTP/1.1\r\n"
6625 "Host: www.example.org\r\n"
6626 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166627 };
6628
6629 MockRead data_reads1[] = {
6630 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6631 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6632 MockRead("Content-Length: 10\r\n\r\n"),
6633 MockRead(SYNCHRONOUS, ERR_FAILED),
6634 };
6635
6636 // After the challenge above, the transaction will be restarted using the
6637 // identity from the url (foo, baz) to answer the challenge.
6638 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236639 MockWrite(
6640 "GET / HTTP/1.1\r\n"
6641 "Host: www.example.org\r\n"
6642 "Connection: keep-alive\r\n"
6643 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166644 };
6645
6646 MockRead data_reads2[] = {
6647 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6648 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6649 MockRead("Content-Length: 10\r\n\r\n"),
6650 MockRead(SYNCHRONOUS, ERR_FAILED),
6651 };
6652
6653 // After the challenge above, the transaction will be restarted using the
6654 // identity supplied by the user (foo, bar) to answer the challenge.
6655 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236656 MockWrite(
6657 "GET / HTTP/1.1\r\n"
6658 "Host: www.example.org\r\n"
6659 "Connection: keep-alive\r\n"
6660 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166661 };
6662
6663 MockRead data_reads3[] = {
6664 MockRead("HTTP/1.0 200 OK\r\n"),
6665 MockRead("Content-Length: 100\r\n\r\n"),
6666 MockRead(SYNCHRONOUS, OK),
6667 };
6668
6669 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6670 data_writes1, arraysize(data_writes1));
6671 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6672 data_writes2, arraysize(data_writes2));
6673 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6674 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076675 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6676 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6677 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166678
6679 TestCompletionCallback callback1;
6680
tfarina42834112016-09-22 13:38:206681 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016682 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166683
6684 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016685 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:166686
bnc691fda62016-08-12 00:43:166687 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166688 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166689 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166691 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016692 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166693 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166694
bnc691fda62016-08-12 00:43:166695 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526696 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166697 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6698
6699 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166700 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:016701 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166702 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016703 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166704 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166705
bnc691fda62016-08-12 00:43:166706 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526707 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166708
6709 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526710 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166711
6712 EXPECT_EQ(100, response->headers->GetContentLength());
6713
[email protected]ea9dc9a2009-09-05 00:43:326714 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556715 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326716}
6717
[email protected]2217aa22013-10-11 03:03:546718
6719// Test the request-challenge-retry sequence for basic auth when there is a
6720// correct identity in the URL, but its use is being suppressed. The identity
6721// from the URL should never be used.
bncd16676a2016-07-20 16:23:016722TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:546723 HttpRequestInfo request;
6724 request.method = "GET";
bncce36dca22015-04-21 22:11:236725 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546726 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6727
danakj1fd259a02016-04-16 03:17:096728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:546730
6731 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236732 MockWrite(
6733 "GET / HTTP/1.1\r\n"
6734 "Host: www.example.org\r\n"
6735 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546736 };
6737
6738 MockRead data_reads1[] = {
6739 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6740 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6741 MockRead("Content-Length: 10\r\n\r\n"),
6742 MockRead(SYNCHRONOUS, ERR_FAILED),
6743 };
6744
6745 // After the challenge above, the transaction will be restarted using the
6746 // identity supplied by the user, not the one in the URL, to answer the
6747 // challenge.
6748 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236749 MockWrite(
6750 "GET / HTTP/1.1\r\n"
6751 "Host: www.example.org\r\n"
6752 "Connection: keep-alive\r\n"
6753 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546754 };
6755
6756 MockRead data_reads3[] = {
6757 MockRead("HTTP/1.0 200 OK\r\n"),
6758 MockRead("Content-Length: 100\r\n\r\n"),
6759 MockRead(SYNCHRONOUS, OK),
6760 };
6761
6762 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6763 data_writes1, arraysize(data_writes1));
6764 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6765 data_writes3, arraysize(data_writes3));
6766 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6767 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6768
6769 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:206770 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016771 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:546772 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016773 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166774 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:546775
bnc691fda62016-08-12 00:43:166776 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526777 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:546778 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6779
6780 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166781 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:016782 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:546783 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016784 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166785 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:546786
bnc691fda62016-08-12 00:43:166787 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526788 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:546789
6790 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526791 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:546792 EXPECT_EQ(100, response->headers->GetContentLength());
6793
6794 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556795 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:546796}
6797
[email protected]f9ee6b52008-11-08 06:46:236798// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:016799TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:096800 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:236801
6802 // Transaction 1: authenticate (foo, bar) on MyRealm1
6803 {
[email protected]1c773ea12009-04-28 19:58:426804 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236805 request.method = "GET";
bncce36dca22015-04-21 22:11:236806 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:236807 request.load_flags = 0;
6808
bnc691fda62016-08-12 00:43:166809 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276810
[email protected]f9ee6b52008-11-08 06:46:236811 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236812 MockWrite(
6813 "GET /x/y/z HTTP/1.1\r\n"
6814 "Host: www.example.org\r\n"
6815 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236816 };
6817
6818 MockRead data_reads1[] = {
6819 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6820 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6821 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066822 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236823 };
6824
6825 // Resend with authorization (username=foo, password=bar)
6826 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236827 MockWrite(
6828 "GET /x/y/z HTTP/1.1\r\n"
6829 "Host: www.example.org\r\n"
6830 "Connection: keep-alive\r\n"
6831 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236832 };
6833
6834 // Sever accepts the authorization.
6835 MockRead data_reads2[] = {
6836 MockRead("HTTP/1.0 200 OK\r\n"),
6837 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066838 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236839 };
6840
[email protected]31a2bfe2010-02-09 08:03:396841 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6842 data_writes1, arraysize(data_writes1));
6843 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6844 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076845 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6846 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236847
[email protected]49639fa2011-12-20 23:22:416848 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236849
tfarina42834112016-09-22 13:38:206850 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016851 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236852
6853 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016854 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:236855
bnc691fda62016-08-12 00:43:166856 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526857 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046858 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236859
[email protected]49639fa2011-12-20 23:22:416860 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236861
bnc691fda62016-08-12 00:43:166862 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
6863 callback2.callback());
robpercival214763f2016-07-01 23:27:016864 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236865
6866 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016867 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:236868
bnc691fda62016-08-12 00:43:166869 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526870 ASSERT_TRUE(response);
6871 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:236872 EXPECT_EQ(100, response->headers->GetContentLength());
6873 }
6874
6875 // ------------------------------------------------------------------------
6876
6877 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
6878 {
[email protected]1c773ea12009-04-28 19:58:426879 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236880 request.method = "GET";
6881 // Note that Transaction 1 was at /x/y/z, so this is in the same
6882 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:236883 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:236884 request.load_flags = 0;
6885
bnc691fda62016-08-12 00:43:166886 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276887
[email protected]f9ee6b52008-11-08 06:46:236888 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236889 MockWrite(
6890 "GET /x/y/a/b HTTP/1.1\r\n"
6891 "Host: www.example.org\r\n"
6892 "Connection: keep-alive\r\n"
6893 // Send preemptive authorization for MyRealm1
6894 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236895 };
6896
6897 // The server didn't like the preemptive authorization, and
6898 // challenges us for a different realm (MyRealm2).
6899 MockRead data_reads1[] = {
6900 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6901 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
6902 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066903 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236904 };
6905
6906 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
6907 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236908 MockWrite(
6909 "GET /x/y/a/b HTTP/1.1\r\n"
6910 "Host: www.example.org\r\n"
6911 "Connection: keep-alive\r\n"
6912 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236913 };
6914
6915 // Sever accepts the authorization.
6916 MockRead data_reads2[] = {
6917 MockRead("HTTP/1.0 200 OK\r\n"),
6918 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066919 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236920 };
6921
[email protected]31a2bfe2010-02-09 08:03:396922 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6923 data_writes1, arraysize(data_writes1));
6924 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6925 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076926 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6927 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236928
[email protected]49639fa2011-12-20 23:22:416929 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236930
tfarina42834112016-09-22 13:38:206931 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016932 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236933
6934 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016935 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:236936
bnc691fda62016-08-12 00:43:166937 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526938 ASSERT_TRUE(response);
6939 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:046940 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:436941 EXPECT_EQ("http://www.example.org",
6942 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:046943 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:196944 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:236945
[email protected]49639fa2011-12-20 23:22:416946 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236947
bnc691fda62016-08-12 00:43:166948 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6949 callback2.callback());
robpercival214763f2016-07-01 23:27:016950 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236951
6952 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016953 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:236954
bnc691fda62016-08-12 00:43:166955 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526956 ASSERT_TRUE(response);
6957 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:236958 EXPECT_EQ(100, response->headers->GetContentLength());
6959 }
6960
6961 // ------------------------------------------------------------------------
6962
6963 // Transaction 3: Resend a request in MyRealm's protection space --
6964 // succeed with preemptive authorization.
6965 {
[email protected]1c773ea12009-04-28 19:58:426966 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236967 request.method = "GET";
bncce36dca22015-04-21 22:11:236968 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:236969 request.load_flags = 0;
6970
bnc691fda62016-08-12 00:43:166971 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276972
[email protected]f9ee6b52008-11-08 06:46:236973 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236974 MockWrite(
6975 "GET /x/y/z2 HTTP/1.1\r\n"
6976 "Host: www.example.org\r\n"
6977 "Connection: keep-alive\r\n"
6978 // The authorization for MyRealm1 gets sent preemptively
6979 // (since the url is in the same protection space)
6980 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236981 };
6982
6983 // Sever accepts the preemptive authorization
6984 MockRead data_reads1[] = {
6985 MockRead("HTTP/1.0 200 OK\r\n"),
6986 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066987 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236988 };
6989
[email protected]31a2bfe2010-02-09 08:03:396990 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6991 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076992 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:236993
[email protected]49639fa2011-12-20 23:22:416994 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236995
tfarina42834112016-09-22 13:38:206996 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236998
6999 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017000 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237001
bnc691fda62016-08-12 00:43:167002 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527003 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237004
wezca1070932016-05-26 20:30:527005 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237006 EXPECT_EQ(100, response->headers->GetContentLength());
7007 }
7008
7009 // ------------------------------------------------------------------------
7010
7011 // Transaction 4: request another URL in MyRealm (however the
7012 // url is not known to belong to the protection space, so no pre-auth).
7013 {
[email protected]1c773ea12009-04-28 19:58:427014 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237015 request.method = "GET";
bncce36dca22015-04-21 22:11:237016 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237017 request.load_flags = 0;
7018
bnc691fda62016-08-12 00:43:167019 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277020
[email protected]f9ee6b52008-11-08 06:46:237021 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237022 MockWrite(
7023 "GET /x/1 HTTP/1.1\r\n"
7024 "Host: www.example.org\r\n"
7025 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237026 };
7027
7028 MockRead data_reads1[] = {
7029 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7030 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7031 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067032 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237033 };
7034
7035 // Resend with authorization from MyRealm's cache.
7036 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237037 MockWrite(
7038 "GET /x/1 HTTP/1.1\r\n"
7039 "Host: www.example.org\r\n"
7040 "Connection: keep-alive\r\n"
7041 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237042 };
7043
7044 // Sever accepts the authorization.
7045 MockRead data_reads2[] = {
7046 MockRead("HTTP/1.0 200 OK\r\n"),
7047 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067048 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237049 };
7050
[email protected]31a2bfe2010-02-09 08:03:397051 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7052 data_writes1, arraysize(data_writes1));
7053 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7054 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077055 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7056 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237057
[email protected]49639fa2011-12-20 23:22:417058 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237059
tfarina42834112016-09-22 13:38:207060 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237062
7063 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017064 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237065
bnc691fda62016-08-12 00:43:167066 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417067 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167068 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017069 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227070 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017071 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167072 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227073
bnc691fda62016-08-12 00:43:167074 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527075 ASSERT_TRUE(response);
7076 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237077 EXPECT_EQ(100, response->headers->GetContentLength());
7078 }
7079
7080 // ------------------------------------------------------------------------
7081
7082 // Transaction 5: request a URL in MyRealm, but the server rejects the
7083 // cached identity. Should invalidate and re-prompt.
7084 {
[email protected]1c773ea12009-04-28 19:58:427085 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237086 request.method = "GET";
bncce36dca22015-04-21 22:11:237087 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237088 request.load_flags = 0;
7089
bnc691fda62016-08-12 00:43:167090 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277091
[email protected]f9ee6b52008-11-08 06:46:237092 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237093 MockWrite(
7094 "GET /p/q/t HTTP/1.1\r\n"
7095 "Host: www.example.org\r\n"
7096 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237097 };
7098
7099 MockRead data_reads1[] = {
7100 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7101 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7102 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067103 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237104 };
7105
7106 // Resend with authorization from cache for MyRealm.
7107 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237108 MockWrite(
7109 "GET /p/q/t HTTP/1.1\r\n"
7110 "Host: www.example.org\r\n"
7111 "Connection: keep-alive\r\n"
7112 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237113 };
7114
7115 // Sever rejects the authorization.
7116 MockRead data_reads2[] = {
7117 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7118 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7119 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067120 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237121 };
7122
7123 // At this point we should prompt for new credentials for MyRealm.
7124 // Restart with username=foo3, password=foo4.
7125 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237126 MockWrite(
7127 "GET /p/q/t HTTP/1.1\r\n"
7128 "Host: www.example.org\r\n"
7129 "Connection: keep-alive\r\n"
7130 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237131 };
7132
7133 // Sever accepts the authorization.
7134 MockRead data_reads3[] = {
7135 MockRead("HTTP/1.0 200 OK\r\n"),
7136 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067137 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237138 };
7139
[email protected]31a2bfe2010-02-09 08:03:397140 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7141 data_writes1, arraysize(data_writes1));
7142 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7143 data_writes2, arraysize(data_writes2));
7144 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7145 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077146 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7147 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7148 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237149
[email protected]49639fa2011-12-20 23:22:417150 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237151
tfarina42834112016-09-22 13:38:207152 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017153 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237154
7155 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017156 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237157
bnc691fda62016-08-12 00:43:167158 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417159 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167160 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017161 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227162 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017163 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167164 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227165
bnc691fda62016-08-12 00:43:167166 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527167 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047168 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237169
[email protected]49639fa2011-12-20 23:22:417170 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237171
bnc691fda62016-08-12 00:43:167172 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7173 callback3.callback());
robpercival214763f2016-07-01 23:27:017174 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237175
[email protected]0757e7702009-03-27 04:00:227176 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017177 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237178
bnc691fda62016-08-12 00:43:167179 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527180 ASSERT_TRUE(response);
7181 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237182 EXPECT_EQ(100, response->headers->GetContentLength());
7183 }
7184}
[email protected]89ceba9a2009-03-21 03:46:067185
[email protected]3c32c5f2010-05-18 15:18:127186// Tests that nonce count increments when multiple auth attempts
7187// are started with the same nonce.
bncd16676a2016-07-20 16:23:017188TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447189 HttpAuthHandlerDigest::Factory* digest_factory =
7190 new HttpAuthHandlerDigest::Factory();
7191 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7192 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7193 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077194 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097195 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127196
7197 // Transaction 1: authenticate (foo, bar) on MyRealm1
7198 {
[email protected]3c32c5f2010-05-18 15:18:127199 HttpRequestInfo request;
7200 request.method = "GET";
bncce36dca22015-04-21 22:11:237201 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127202 request.load_flags = 0;
7203
bnc691fda62016-08-12 00:43:167204 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277205
[email protected]3c32c5f2010-05-18 15:18:127206 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237207 MockWrite(
7208 "GET /x/y/z HTTP/1.1\r\n"
7209 "Host: www.example.org\r\n"
7210 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127211 };
7212
7213 MockRead data_reads1[] = {
7214 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7215 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7216 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067217 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127218 };
7219
7220 // Resend with authorization (username=foo, password=bar)
7221 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237222 MockWrite(
7223 "GET /x/y/z HTTP/1.1\r\n"
7224 "Host: www.example.org\r\n"
7225 "Connection: keep-alive\r\n"
7226 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7227 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7228 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7229 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127230 };
7231
7232 // Sever accepts the authorization.
7233 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087234 MockRead("HTTP/1.0 200 OK\r\n"),
7235 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127236 };
7237
7238 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7239 data_writes1, arraysize(data_writes1));
7240 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7241 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077242 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7243 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127244
[email protected]49639fa2011-12-20 23:22:417245 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127246
tfarina42834112016-09-22 13:38:207247 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017248 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127249
7250 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017251 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127252
bnc691fda62016-08-12 00:43:167253 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527254 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047255 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127256
[email protected]49639fa2011-12-20 23:22:417257 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127258
bnc691fda62016-08-12 00:43:167259 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7260 callback2.callback());
robpercival214763f2016-07-01 23:27:017261 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127262
7263 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017264 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127265
bnc691fda62016-08-12 00:43:167266 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527267 ASSERT_TRUE(response);
7268 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127269 }
7270
7271 // ------------------------------------------------------------------------
7272
7273 // Transaction 2: Request another resource in digestive's protection space.
7274 // This will preemptively add an Authorization header which should have an
7275 // "nc" value of 2 (as compared to 1 in the first use.
7276 {
[email protected]3c32c5f2010-05-18 15:18:127277 HttpRequestInfo request;
7278 request.method = "GET";
7279 // Note that Transaction 1 was at /x/y/z, so this is in the same
7280 // protection space as digest.
bncce36dca22015-04-21 22:11:237281 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127282 request.load_flags = 0;
7283
bnc691fda62016-08-12 00:43:167284 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277285
[email protected]3c32c5f2010-05-18 15:18:127286 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237287 MockWrite(
7288 "GET /x/y/a/b HTTP/1.1\r\n"
7289 "Host: www.example.org\r\n"
7290 "Connection: keep-alive\r\n"
7291 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7292 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7293 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7294 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127295 };
7296
7297 // Sever accepts the authorization.
7298 MockRead data_reads1[] = {
7299 MockRead("HTTP/1.0 200 OK\r\n"),
7300 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067301 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127302 };
7303
7304 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7305 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077306 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127307
[email protected]49639fa2011-12-20 23:22:417308 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127309
tfarina42834112016-09-22 13:38:207310 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017311 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127312
7313 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017314 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127315
bnc691fda62016-08-12 00:43:167316 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527317 ASSERT_TRUE(response);
7318 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127319 }
7320}
7321
[email protected]89ceba9a2009-03-21 03:46:067322// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017323TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067324 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097325 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167326 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067327
7328 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167329 trans.read_buf_ = new IOBuffer(15);
7330 trans.read_buf_len_ = 15;
7331 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067332
7333 // Setup state in response_
bnc691fda62016-08-12 00:43:167334 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577335 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087336 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577337 response->response_time = base::Time::Now();
7338 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067339
7340 { // Setup state for response_.vary_data
7341 HttpRequestInfo request;
7342 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7343 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277344 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437345 request.extra_headers.SetHeader("Foo", "1");
7346 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507347 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067348 }
7349
7350 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167351 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067352
7353 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167354 EXPECT_FALSE(trans.read_buf_);
7355 EXPECT_EQ(0, trans.read_buf_len_);
7356 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527357 EXPECT_FALSE(response->auth_challenge);
7358 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047359 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087360 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577361 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067362}
7363
[email protected]bacff652009-03-31 17:50:337364// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017365TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337366 HttpRequestInfo request;
7367 request.method = "GET";
bncce36dca22015-04-21 22:11:237368 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337369 request.load_flags = 0;
7370
danakj1fd259a02016-04-16 03:17:097371 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167372 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277373
[email protected]bacff652009-03-31 17:50:337374 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237375 MockWrite(
7376 "GET / HTTP/1.1\r\n"
7377 "Host: www.example.org\r\n"
7378 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337379 };
7380
7381 MockRead data_reads[] = {
7382 MockRead("HTTP/1.0 200 OK\r\n"),
7383 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7384 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067385 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337386 };
7387
[email protected]5ecc992a42009-11-11 01:41:597388 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397389 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7390 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067391 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7392 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337393
[email protected]bb88e1d32013-05-03 23:11:077394 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7395 session_deps_.socket_factory->AddSocketDataProvider(&data);
7396 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7397 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337398
[email protected]49639fa2011-12-20 23:22:417399 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337400
tfarina42834112016-09-22 13:38:207401 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017402 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337403
7404 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017405 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337406
bnc691fda62016-08-12 00:43:167407 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017408 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337409
7410 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017411 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337412
bnc691fda62016-08-12 00:43:167413 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337414
wezca1070932016-05-26 20:30:527415 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337416 EXPECT_EQ(100, response->headers->GetContentLength());
7417}
7418
7419// Test HTTPS connections to a site with a bad certificate, going through a
7420// proxy
bncd16676a2016-07-20 16:23:017421TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037422 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337423
7424 HttpRequestInfo request;
7425 request.method = "GET";
bncce36dca22015-04-21 22:11:237426 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337427 request.load_flags = 0;
7428
7429 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177430 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7431 "Host: www.example.org:443\r\n"
7432 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337433 };
7434
7435 MockRead proxy_reads[] = {
7436 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067437 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337438 };
7439
7440 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177441 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7442 "Host: www.example.org:443\r\n"
7443 "Proxy-Connection: keep-alive\r\n\r\n"),
7444 MockWrite("GET / HTTP/1.1\r\n"
7445 "Host: www.example.org\r\n"
7446 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337447 };
7448
7449 MockRead data_reads[] = {
7450 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7451 MockRead("HTTP/1.0 200 OK\r\n"),
7452 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7453 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067454 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337455 };
7456
[email protected]31a2bfe2010-02-09 08:03:397457 StaticSocketDataProvider ssl_bad_certificate(
7458 proxy_reads, arraysize(proxy_reads),
7459 proxy_writes, arraysize(proxy_writes));
7460 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7461 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067462 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7463 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337464
[email protected]bb88e1d32013-05-03 23:11:077465 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7466 session_deps_.socket_factory->AddSocketDataProvider(&data);
7467 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337469
[email protected]49639fa2011-12-20 23:22:417470 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337471
7472 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077473 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337474
danakj1fd259a02016-04-16 03:17:097475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167476 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:337477
tfarina42834112016-09-22 13:38:207478 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337480
7481 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017482 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337483
bnc691fda62016-08-12 00:43:167484 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337486
7487 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017488 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337489
bnc691fda62016-08-12 00:43:167490 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337491
wezca1070932016-05-26 20:30:527492 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337493 EXPECT_EQ(100, response->headers->GetContentLength());
7494 }
7495}
7496
[email protected]2df19bb2010-08-25 20:13:467497
7498// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:017499TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037500 session_deps_.proxy_service =
7501 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517502 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077503 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467504
7505 HttpRequestInfo request;
7506 request.method = "GET";
bncce36dca22015-04-21 22:11:237507 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467508 request.load_flags = 0;
7509
7510 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177511 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7512 "Host: www.example.org:443\r\n"
7513 "Proxy-Connection: keep-alive\r\n\r\n"),
7514 MockWrite("GET / HTTP/1.1\r\n"
7515 "Host: www.example.org\r\n"
7516 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467517 };
7518
7519 MockRead data_reads[] = {
7520 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7521 MockRead("HTTP/1.1 200 OK\r\n"),
7522 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7523 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067524 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467525 };
7526
7527 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7528 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067529 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7530 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467531
[email protected]bb88e1d32013-05-03 23:11:077532 session_deps_.socket_factory->AddSocketDataProvider(&data);
7533 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7534 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467535
[email protected]49639fa2011-12-20 23:22:417536 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467537
danakj1fd259a02016-04-16 03:17:097538 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167539 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:467540
tfarina42834112016-09-22 13:38:207541 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017542 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:467543
7544 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017545 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167546 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:467547
wezca1070932016-05-26 20:30:527548 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467549
7550 EXPECT_TRUE(response->headers->IsKeepAlive());
7551 EXPECT_EQ(200, response->headers->response_code());
7552 EXPECT_EQ(100, response->headers->GetContentLength());
7553 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207554
7555 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167556 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207557 TestLoadTimingNotReusedWithPac(load_timing_info,
7558 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467559}
7560
[email protected]511f6f52010-12-17 03:58:297561// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017562TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037563 session_deps_.proxy_service =
7564 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517565 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077566 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297567
7568 HttpRequestInfo request;
7569 request.method = "GET";
bncce36dca22015-04-21 22:11:237570 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297571 request.load_flags = 0;
7572
7573 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177574 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7575 "Host: www.example.org:443\r\n"
7576 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297577 };
7578
7579 MockRead data_reads[] = {
7580 MockRead("HTTP/1.1 302 Redirect\r\n"),
7581 MockRead("Location: http://login.example.com/\r\n"),
7582 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067583 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297584 };
7585
7586 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7587 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067588 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297589
[email protected]bb88e1d32013-05-03 23:11:077590 session_deps_.socket_factory->AddSocketDataProvider(&data);
7591 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297592
[email protected]49639fa2011-12-20 23:22:417593 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297594
danakj1fd259a02016-04-16 03:17:097595 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167596 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297597
tfarina42834112016-09-22 13:38:207598 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017599 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297600
7601 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017602 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167603 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297604
wezca1070932016-05-26 20:30:527605 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297606
7607 EXPECT_EQ(302, response->headers->response_code());
7608 std::string url;
7609 EXPECT_TRUE(response->headers->IsRedirect(&url));
7610 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207611
7612 // In the case of redirects from proxies, HttpNetworkTransaction returns
7613 // timing for the proxy connection instead of the connection to the host,
7614 // and no send / receive times.
7615 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7616 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167617 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207618
7619 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:297620 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207621
7622 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7623 EXPECT_LE(load_timing_info.proxy_resolve_start,
7624 load_timing_info.proxy_resolve_end);
7625 EXPECT_LE(load_timing_info.proxy_resolve_end,
7626 load_timing_info.connect_timing.connect_start);
7627 ExpectConnectTimingHasTimes(
7628 load_timing_info.connect_timing,
7629 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7630
7631 EXPECT_TRUE(load_timing_info.send_start.is_null());
7632 EXPECT_TRUE(load_timing_info.send_end.is_null());
7633 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297634}
7635
7636// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017637TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037638 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297639
7640 HttpRequestInfo request;
7641 request.method = "GET";
bncce36dca22015-04-21 22:11:237642 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297643 request.load_flags = 0;
7644
bncdf80d44fd2016-07-15 20:27:417645 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237646 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417647 SpdySerializedFrame goaway(
[email protected]c10b20852013-05-15 21:29:207648 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297649 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417650 CreateMockWrite(conn, 0, SYNCHRONOUS),
7651 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297652 };
7653
7654 static const char* const kExtraHeaders[] = {
7655 "location",
7656 "http://login.example.com/",
7657 };
bnc42331402016-07-25 13:36:157658 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:417659 "302 Redirect", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297660 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417661 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297662 };
7663
rch8e6c6c42015-05-01 14:05:137664 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7665 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067666 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367667 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297668
[email protected]bb88e1d32013-05-03 23:11:077669 session_deps_.socket_factory->AddSocketDataProvider(&data);
7670 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297671
[email protected]49639fa2011-12-20 23:22:417672 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297673
danakj1fd259a02016-04-16 03:17:097674 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167675 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297676
tfarina42834112016-09-22 13:38:207677 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017678 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297679
7680 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017681 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167682 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297683
wezca1070932016-05-26 20:30:527684 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297685
7686 EXPECT_EQ(302, response->headers->response_code());
7687 std::string url;
7688 EXPECT_TRUE(response->headers->IsRedirect(&url));
7689 EXPECT_EQ("http://login.example.com/", url);
7690}
7691
[email protected]4eddbc732012-08-09 05:40:177692// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017693TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037694 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297695
7696 HttpRequestInfo request;
7697 request.method = "GET";
bncce36dca22015-04-21 22:11:237698 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297699 request.load_flags = 0;
7700
7701 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177702 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7703 "Host: www.example.org:443\r\n"
7704 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297705 };
7706
7707 MockRead data_reads[] = {
7708 MockRead("HTTP/1.1 404 Not Found\r\n"),
7709 MockRead("Content-Length: 23\r\n\r\n"),
7710 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067711 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297712 };
7713
7714 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7715 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067716 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297717
[email protected]bb88e1d32013-05-03 23:11:077718 session_deps_.socket_factory->AddSocketDataProvider(&data);
7719 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297720
[email protected]49639fa2011-12-20 23:22:417721 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297722
danakj1fd259a02016-04-16 03:17:097723 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167724 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297725
tfarina42834112016-09-22 13:38:207726 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297728
7729 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017730 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:297731
ttuttle960fcbf2016-04-19 13:26:327732 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297733}
7734
[email protected]4eddbc732012-08-09 05:40:177735// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017736TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037737 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297738
7739 HttpRequestInfo request;
7740 request.method = "GET";
bncce36dca22015-04-21 22:11:237741 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297742 request.load_flags = 0;
7743
bncdf80d44fd2016-07-15 20:27:417744 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237745 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417746 SpdySerializedFrame rst(
[email protected]c10b20852013-05-15 21:29:207747 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297748 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417749 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:297750 };
7751
7752 static const char* const kExtraHeaders[] = {
7753 "location",
7754 "http://login.example.com/",
7755 };
bnc42331402016-07-25 13:36:157756 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:417757 "404 Not Found", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
7758 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:557759 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297760 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417761 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:137762 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297763 };
7764
rch8e6c6c42015-05-01 14:05:137765 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7766 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067767 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367768 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297769
[email protected]bb88e1d32013-05-03 23:11:077770 session_deps_.socket_factory->AddSocketDataProvider(&data);
7771 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297772
[email protected]49639fa2011-12-20 23:22:417773 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297774
danakj1fd259a02016-04-16 03:17:097775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297777
tfarina42834112016-09-22 13:38:207778 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017779 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297780
7781 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017782 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:297783
ttuttle960fcbf2016-04-19 13:26:327784 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297785}
7786
[email protected]0c5fb722012-02-28 11:50:357787// Test the request-challenge-retry sequence for basic auth, through
7788// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:017789TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:357790 HttpRequestInfo request;
7791 request.method = "GET";
bncce36dca22015-04-21 22:11:237792 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:357793 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:297794 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:357795
7796 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037797 session_deps_.proxy_service =
7798 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:517799 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077800 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:097801 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:357802
7803 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:417804 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237805 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417806 SpdySerializedFrame rst(
[email protected]c10b20852013-05-15 21:29:207807 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
rdsmithebb50aa2015-11-12 03:44:387808 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:357809
bnc691fda62016-08-12 00:43:167810 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:357811 // be issuing -- the final header line contains the credentials.
7812 const char* const kAuthCredentials[] = {
7813 "proxy-authorization", "Basic Zm9vOmJhcg==",
7814 };
bncdf80d44fd2016-07-15 20:27:417815 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:347816 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:237817 HostPortPair("www.example.org", 443)));
7818 // fetch https://www.example.org/ via HTTP
7819 const char get[] =
7820 "GET / HTTP/1.1\r\n"
7821 "Host: www.example.org\r\n"
7822 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:417823 SpdySerializedFrame wrapped_get(
7824 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:357825
7826 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:417827 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
7828 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:357829 };
7830
7831 // The proxy responds to the connect with a 407, using a persistent
7832 // connection.
thestig9d3bb0c2015-01-24 00:49:517833 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:357834 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:357835 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
7836 };
bnc42331402016-07-25 13:36:157837 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:417838 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:357839
bnc42331402016-07-25 13:36:157840 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:357841 const char resp[] = "HTTP/1.1 200 OK\r\n"
7842 "Content-Length: 5\r\n\r\n";
7843
bncdf80d44fd2016-07-15 20:27:417844 SpdySerializedFrame wrapped_get_resp(
7845 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
7846 SpdySerializedFrame wrapped_body(
7847 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:357848 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:417849 CreateMockRead(conn_auth_resp, 1, ASYNC),
7850 CreateMockRead(conn_resp, 4, ASYNC),
7851 CreateMockRead(wrapped_get_resp, 6, ASYNC),
7852 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:137853 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:357854 };
7855
rch8e6c6c42015-05-01 14:05:137856 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7857 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077858 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:357859 // Negotiate SPDY to the proxy
7860 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:367861 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:077862 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:357863 // Vanilla SSL to the server
7864 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077865 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:357866
7867 TestCompletionCallback callback1;
7868
bnc691fda62016-08-12 00:43:167869 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:507870 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:357871
7872 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:017873 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:357874
7875 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017876 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:467877 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:357878 log.GetEntries(&entries);
7879 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:007880 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
7881 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:357882 ExpectLogContainsSomewhere(
7883 entries, pos,
mikecirone8b85c432016-09-08 19:11:007884 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
7885 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:357886
7887 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527888 ASSERT_TRUE(response);
7889 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:357890 EXPECT_EQ(407, response->headers->response_code());
7891 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:527892 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:437893 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:357894
7895 TestCompletionCallback callback2;
7896
7897 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
7898 callback2.callback());
robpercival214763f2016-07-01 23:27:017899 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:357900
7901 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017902 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:357903
7904 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527905 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:357906
7907 EXPECT_TRUE(response->headers->IsKeepAlive());
7908 EXPECT_EQ(200, response->headers->response_code());
7909 EXPECT_EQ(5, response->headers->GetContentLength());
7910 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7911
7912 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:527913 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:357914
[email protected]029c83b62013-01-24 05:28:207915 LoadTimingInfo load_timing_info;
7916 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7917 TestLoadTimingNotReusedWithPac(load_timing_info,
7918 CONNECT_TIMING_HAS_SSL_TIMES);
7919
[email protected]0c5fb722012-02-28 11:50:357920 trans.reset();
7921 session->CloseAllConnections();
7922}
7923
[email protected]7c6f7ba2012-04-03 04:09:297924// Test that an explicitly trusted SPDY proxy can push a resource from an
7925// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:017926TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:157927 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:097928 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:157929 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
7930 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:297931 HttpRequestInfo request;
7932 HttpRequestInfo push_request;
7933
[email protected]7c6f7ba2012-04-03 04:09:297934 request.method = "GET";
bncce36dca22015-04-21 22:11:237935 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:297936 push_request.method = "GET";
7937 push_request.url = GURL("http://www.another-origin.com/foo.dat");
7938
tbansal28e68f82016-02-04 02:56:157939 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:037940 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:157941 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:517942 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077943 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507944
tbansal28e68f82016-02-04 02:56:157945 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:507946
danakj1fd259a02016-04-16 03:17:097947 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:297948
bncdf80d44fd2016-07-15 20:27:417949 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:457950 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]7c6f7ba2012-04-03 04:09:297951
7952 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:417953 CreateMockWrite(stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:297954 };
7955
bncdf80d44fd2016-07-15 20:27:417956 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:157957 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:297958
bncdf80d44fd2016-07-15 20:27:417959 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:297960
bncdf80d44fd2016-07-15 20:27:417961 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:557962 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:437963 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:417964 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
7965 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:297966
7967 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:417968 CreateMockRead(stream1_reply, 1, ASYNC),
7969 CreateMockRead(stream2_syn, 2, ASYNC),
7970 CreateMockRead(stream1_body, 3, ASYNC),
7971 CreateMockRead(stream2_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:597972 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:297973 };
7974
rch8e6c6c42015-05-01 14:05:137975 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7976 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077977 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:297978 // Negotiate SPDY to the proxy
7979 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:367980 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:077981 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:297982
bnc691fda62016-08-12 00:43:167983 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:507984 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:297985 TestCompletionCallback callback;
7986 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:017987 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:297988
7989 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017990 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:297991 const HttpResponseInfo* response = trans->GetResponseInfo();
7992
bnc691fda62016-08-12 00:43:167993 std::unique_ptr<HttpNetworkTransaction> push_trans(
[email protected]90499482013-06-01 00:39:507994 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7995 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:017996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:297997
7998 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017999 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298000 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8001
wezca1070932016-05-26 20:30:528002 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298003 EXPECT_TRUE(response->headers->IsKeepAlive());
8004
8005 EXPECT_EQ(200, response->headers->response_code());
8006 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8007
8008 std::string response_data;
8009 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018010 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298011 EXPECT_EQ("hello!", response_data);
8012
[email protected]029c83b62013-01-24 05:28:208013 LoadTimingInfo load_timing_info;
8014 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8015 TestLoadTimingNotReusedWithPac(load_timing_info,
8016 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8017
[email protected]7c6f7ba2012-04-03 04:09:298018 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528019 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298020 EXPECT_EQ(200, push_response->headers->response_code());
8021
8022 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018023 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298024 EXPECT_EQ("pushed", response_data);
8025
[email protected]029c83b62013-01-24 05:28:208026 LoadTimingInfo push_load_timing_info;
8027 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8028 TestLoadTimingReusedWithPac(push_load_timing_info);
8029 // The transactions should share a socket ID, despite being for different
8030 // origins.
8031 EXPECT_EQ(load_timing_info.socket_log_id,
8032 push_load_timing_info.socket_log_id);
8033
[email protected]7c6f7ba2012-04-03 04:09:298034 trans.reset();
8035 push_trans.reset();
8036 session->CloseAllConnections();
8037}
8038
[email protected]8c843192012-04-05 07:15:008039// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018040TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158041 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098042 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158043 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8044 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008045 HttpRequestInfo request;
8046
8047 request.method = "GET";
bncce36dca22015-04-21 22:11:238048 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008049
tbansal28e68f82016-02-04 02:56:158050 session_deps_.proxy_service =
8051 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518052 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078053 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508054
8055 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:158056 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:508057
danakj1fd259a02016-04-16 03:17:098058 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008059
bncdf80d44fd2016-07-15 20:27:418060 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458061 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008062
bncdf80d44fd2016-07-15 20:27:418063 SpdySerializedFrame push_rst(
[email protected]c10b20852013-05-15 21:29:208064 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008065
8066 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418067 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008068 };
8069
bncdf80d44fd2016-07-15 20:27:418070 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158071 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008072
bncdf80d44fd2016-07-15 20:27:418073 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008074
bncdf80d44fd2016-07-15 20:27:418075 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558076 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008077
8078 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418079 CreateMockRead(stream1_reply, 1, ASYNC),
8080 CreateMockRead(stream2_syn, 2, ASYNC),
8081 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598082 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008083 };
8084
rch8e6c6c42015-05-01 14:05:138085 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8086 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078087 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008088 // Negotiate SPDY to the proxy
8089 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368090 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078091 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008092
bnc691fda62016-08-12 00:43:168093 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508094 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:008095 TestCompletionCallback callback;
8096 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008098
8099 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018100 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008101 const HttpResponseInfo* response = trans->GetResponseInfo();
8102
wezca1070932016-05-26 20:30:528103 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008104 EXPECT_TRUE(response->headers->IsKeepAlive());
8105
8106 EXPECT_EQ(200, response->headers->response_code());
8107 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8108
8109 std::string response_data;
8110 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018111 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008112 EXPECT_EQ("hello!", response_data);
8113
8114 trans.reset();
8115 session->CloseAllConnections();
8116}
8117
tbansal8ef1d3e2016-02-03 04:05:428118// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8119// resources.
bncd16676a2016-07-20 16:23:018120TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158121 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098122 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158123 proxy_delegate->set_trusted_spdy_proxy(
8124 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8125
tbansal8ef1d3e2016-02-03 04:05:428126 HttpRequestInfo request;
8127
8128 request.method = "GET";
8129 request.url = GURL("http://www.example.org/");
8130
8131 // Configure against https proxy server "myproxy:70".
8132 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8133 BoundTestNetLog log;
8134 session_deps_.net_log = log.bound().net_log();
8135
8136 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:158137 session_deps_.proxy_delegate.reset(proxy_delegate.release());
tbansal8ef1d3e2016-02-03 04:05:428138
danakj1fd259a02016-04-16 03:17:098139 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428140
bncdf80d44fd2016-07-15 20:27:418141 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458142 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tbansal8ef1d3e2016-02-03 04:05:428143
8144 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418145 CreateMockWrite(stream1_syn, 0, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428146 };
8147
bncdf80d44fd2016-07-15 20:27:418148 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158149 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428150
bncdf80d44fd2016-07-15 20:27:418151 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:498152 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
8153
bncdf80d44fd2016-07-15 20:27:418154 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428155
bncdf80d44fd2016-07-15 20:27:418156 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158157 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428158
bncdf80d44fd2016-07-15 20:27:418159 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428160
8161 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418162 CreateMockRead(stream1_reply, 1, ASYNC),
8163 CreateMockRead(stream2_syn, 2, ASYNC),
8164 CreateMockRead(stream1_body, 3, ASYNC),
8165 CreateMockRead(stream2_body, 4, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428166 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
8167 };
8168
8169 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8170 arraysize(spdy_writes));
8171 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8172 // Negotiate SPDY to the proxy
8173 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368174 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428175 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8176
bnc691fda62016-08-12 00:43:168177 std::unique_ptr<HttpNetworkTransaction> trans(
tbansal8ef1d3e2016-02-03 04:05:428178 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8179 TestCompletionCallback callback;
8180 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018181 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428182
8183 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018184 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428185 const HttpResponseInfo* response = trans->GetResponseInfo();
8186
wezca1070932016-05-26 20:30:528187 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428188 EXPECT_TRUE(response->headers->IsKeepAlive());
8189
8190 EXPECT_EQ(200, response->headers->response_code());
8191 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8192
8193 std::string response_data;
8194 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018195 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428196 EXPECT_EQ("hello!", response_data);
8197
8198 trans.reset();
8199 session->CloseAllConnections();
8200}
8201
[email protected]2df19bb2010-08-25 20:13:468202// Test HTTPS connections to a site with a bad certificate, going through an
8203// HTTPS proxy
bncd16676a2016-07-20 16:23:018204TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038205 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468206
8207 HttpRequestInfo request;
8208 request.method = "GET";
bncce36dca22015-04-21 22:11:238209 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468210 request.load_flags = 0;
8211
8212 // Attempt to fetch the URL from a server with a bad cert
8213 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178214 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8215 "Host: www.example.org:443\r\n"
8216 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468217 };
8218
8219 MockRead bad_cert_reads[] = {
8220 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068221 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468222 };
8223
8224 // Attempt to fetch the URL with a good cert
8225 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178226 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8227 "Host: www.example.org:443\r\n"
8228 "Proxy-Connection: keep-alive\r\n\r\n"),
8229 MockWrite("GET / HTTP/1.1\r\n"
8230 "Host: www.example.org\r\n"
8231 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468232 };
8233
8234 MockRead good_cert_reads[] = {
8235 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8236 MockRead("HTTP/1.0 200 OK\r\n"),
8237 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8238 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068239 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468240 };
8241
8242 StaticSocketDataProvider ssl_bad_certificate(
8243 bad_cert_reads, arraysize(bad_cert_reads),
8244 bad_cert_writes, arraysize(bad_cert_writes));
8245 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8246 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068247 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8248 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468249
8250 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078251 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8252 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8253 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468254
8255 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078256 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8257 session_deps_.socket_factory->AddSocketDataProvider(&data);
8258 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468259
[email protected]49639fa2011-12-20 23:22:418260 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468261
danakj1fd259a02016-04-16 03:17:098262 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168263 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468264
tfarina42834112016-09-22 13:38:208265 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018266 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468267
8268 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018269 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468270
bnc691fda62016-08-12 00:43:168271 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018272 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468273
8274 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018275 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468276
bnc691fda62016-08-12 00:43:168277 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468278
wezca1070932016-05-26 20:30:528279 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468280 EXPECT_EQ(100, response->headers->GetContentLength());
8281}
8282
bncd16676a2016-07-20 16:23:018283TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428284 HttpRequestInfo request;
8285 request.method = "GET";
bncce36dca22015-04-21 22:11:238286 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438287 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8288 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428289
danakj1fd259a02016-04-16 03:17:098290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168291 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278292
[email protected]1c773ea12009-04-28 19:58:428293 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238294 MockWrite(
8295 "GET / HTTP/1.1\r\n"
8296 "Host: www.example.org\r\n"
8297 "Connection: keep-alive\r\n"
8298 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428299 };
8300
8301 // Lastly, the server responds with the actual content.
8302 MockRead data_reads[] = {
8303 MockRead("HTTP/1.0 200 OK\r\n"),
8304 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8305 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068306 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428307 };
8308
[email protected]31a2bfe2010-02-09 08:03:398309 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8310 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078311 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428312
[email protected]49639fa2011-12-20 23:22:418313 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428314
tfarina42834112016-09-22 13:38:208315 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018316 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428317
8318 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018319 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428320}
8321
bncd16676a2016-07-20 16:23:018322TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298323 HttpRequestInfo request;
8324 request.method = "GET";
bncce36dca22015-04-21 22:11:238325 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298326 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8327 "Chromium Ultra Awesome X Edition");
8328
rdsmith82957ad2015-09-16 19:42:038329 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098330 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168331 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278332
[email protected]da81f132010-08-18 23:39:298333 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178334 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8335 "Host: www.example.org:443\r\n"
8336 "Proxy-Connection: keep-alive\r\n"
8337 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298338 };
8339 MockRead data_reads[] = {
8340 // Return an error, so the transaction stops here (this test isn't
8341 // interested in the rest).
8342 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8343 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8344 MockRead("Proxy-Connection: close\r\n\r\n"),
8345 };
8346
8347 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8348 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078349 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298350
[email protected]49639fa2011-12-20 23:22:418351 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298352
tfarina42834112016-09-22 13:38:208353 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018354 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298355
8356 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018357 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298358}
8359
bncd16676a2016-07-20 16:23:018360TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428361 HttpRequestInfo request;
8362 request.method = "GET";
bncce36dca22015-04-21 22:11:238363 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428364 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:168365 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8366 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428367
danakj1fd259a02016-04-16 03:17:098368 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168369 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278370
[email protected]1c773ea12009-04-28 19:58:428371 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238372 MockWrite(
8373 "GET / HTTP/1.1\r\n"
8374 "Host: www.example.org\r\n"
8375 "Connection: keep-alive\r\n"
8376 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428377 };
8378
8379 // Lastly, the server responds with the actual content.
8380 MockRead data_reads[] = {
8381 MockRead("HTTP/1.0 200 OK\r\n"),
8382 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8383 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068384 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428385 };
8386
[email protected]31a2bfe2010-02-09 08:03:398387 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8388 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078389 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428390
[email protected]49639fa2011-12-20 23:22:418391 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428392
tfarina42834112016-09-22 13:38:208393 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018394 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428395
8396 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018397 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428398}
8399
bncd16676a2016-07-20 16:23:018400TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428401 HttpRequestInfo request;
8402 request.method = "POST";
bncce36dca22015-04-21 22:11:238403 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428404
danakj1fd259a02016-04-16 03:17:098405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278407
[email protected]1c773ea12009-04-28 19:58:428408 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238409 MockWrite(
8410 "POST / HTTP/1.1\r\n"
8411 "Host: www.example.org\r\n"
8412 "Connection: keep-alive\r\n"
8413 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428414 };
8415
8416 // Lastly, the server responds with the actual content.
8417 MockRead data_reads[] = {
8418 MockRead("HTTP/1.0 200 OK\r\n"),
8419 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8420 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068421 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428422 };
8423
[email protected]31a2bfe2010-02-09 08:03:398424 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8425 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078426 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428427
[email protected]49639fa2011-12-20 23:22:418428 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428429
tfarina42834112016-09-22 13:38:208430 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018431 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428432
8433 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018434 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428435}
8436
bncd16676a2016-07-20 16:23:018437TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428438 HttpRequestInfo request;
8439 request.method = "PUT";
bncce36dca22015-04-21 22:11:238440 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428441
danakj1fd259a02016-04-16 03:17:098442 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168443 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278444
[email protected]1c773ea12009-04-28 19:58:428445 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238446 MockWrite(
8447 "PUT / HTTP/1.1\r\n"
8448 "Host: www.example.org\r\n"
8449 "Connection: keep-alive\r\n"
8450 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428451 };
8452
8453 // Lastly, the server responds with the actual content.
8454 MockRead data_reads[] = {
8455 MockRead("HTTP/1.0 200 OK\r\n"),
8456 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8457 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068458 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428459 };
8460
[email protected]31a2bfe2010-02-09 08:03:398461 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8462 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078463 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428464
[email protected]49639fa2011-12-20 23:22:418465 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428466
tfarina42834112016-09-22 13:38:208467 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018468 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428469
8470 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018471 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428472}
8473
bncd16676a2016-07-20 16:23:018474TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428475 HttpRequestInfo request;
8476 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238477 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428478
danakj1fd259a02016-04-16 03:17:098479 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168480 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278481
[email protected]1c773ea12009-04-28 19:58:428482 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138483 MockWrite("HEAD / HTTP/1.1\r\n"
8484 "Host: www.example.org\r\n"
8485 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428486 };
8487
8488 // Lastly, the server responds with the actual content.
8489 MockRead data_reads[] = {
8490 MockRead("HTTP/1.0 200 OK\r\n"),
8491 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8492 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068493 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428494 };
8495
[email protected]31a2bfe2010-02-09 08:03:398496 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8497 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078498 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428499
[email protected]49639fa2011-12-20 23:22:418500 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428501
tfarina42834112016-09-22 13:38:208502 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018503 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428504
8505 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018506 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428507}
8508
bncd16676a2016-07-20 16:23:018509TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428510 HttpRequestInfo request;
8511 request.method = "GET";
bncce36dca22015-04-21 22:11:238512 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428513 request.load_flags = LOAD_BYPASS_CACHE;
8514
danakj1fd259a02016-04-16 03:17:098515 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168516 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278517
[email protected]1c773ea12009-04-28 19:58:428518 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238519 MockWrite(
8520 "GET / HTTP/1.1\r\n"
8521 "Host: www.example.org\r\n"
8522 "Connection: keep-alive\r\n"
8523 "Pragma: no-cache\r\n"
8524 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428525 };
8526
8527 // Lastly, the server responds with the actual content.
8528 MockRead data_reads[] = {
8529 MockRead("HTTP/1.0 200 OK\r\n"),
8530 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8531 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068532 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428533 };
8534
[email protected]31a2bfe2010-02-09 08:03:398535 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8536 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078537 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428538
[email protected]49639fa2011-12-20 23:22:418539 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428540
tfarina42834112016-09-22 13:38:208541 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018542 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428543
8544 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018545 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428546}
8547
bncd16676a2016-07-20 16:23:018548TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428549 HttpRequestInfo request;
8550 request.method = "GET";
bncce36dca22015-04-21 22:11:238551 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428552 request.load_flags = LOAD_VALIDATE_CACHE;
8553
danakj1fd259a02016-04-16 03:17:098554 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168555 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278556
[email protected]1c773ea12009-04-28 19:58:428557 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238558 MockWrite(
8559 "GET / HTTP/1.1\r\n"
8560 "Host: www.example.org\r\n"
8561 "Connection: keep-alive\r\n"
8562 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428563 };
8564
8565 // Lastly, the server responds with the actual content.
8566 MockRead data_reads[] = {
8567 MockRead("HTTP/1.0 200 OK\r\n"),
8568 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8569 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068570 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428571 };
8572
[email protected]31a2bfe2010-02-09 08:03:398573 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8574 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078575 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428576
[email protected]49639fa2011-12-20 23:22:418577 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428578
tfarina42834112016-09-22 13:38:208579 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018580 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428581
8582 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018583 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428584}
8585
bncd16676a2016-07-20 16:23:018586TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428587 HttpRequestInfo request;
8588 request.method = "GET";
bncce36dca22015-04-21 22:11:238589 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438590 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428591
danakj1fd259a02016-04-16 03:17:098592 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168593 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278594
[email protected]1c773ea12009-04-28 19:58:428595 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238596 MockWrite(
8597 "GET / HTTP/1.1\r\n"
8598 "Host: www.example.org\r\n"
8599 "Connection: keep-alive\r\n"
8600 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428601 };
8602
8603 // Lastly, the server responds with the actual content.
8604 MockRead data_reads[] = {
8605 MockRead("HTTP/1.0 200 OK\r\n"),
8606 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8607 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068608 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428609 };
8610
[email protected]31a2bfe2010-02-09 08:03:398611 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8612 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078613 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428614
[email protected]49639fa2011-12-20 23:22:418615 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428616
tfarina42834112016-09-22 13:38:208617 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018618 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428619
8620 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018621 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428622}
8623
bncd16676a2016-07-20 16:23:018624TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478625 HttpRequestInfo request;
8626 request.method = "GET";
bncce36dca22015-04-21 22:11:238627 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438628 request.extra_headers.SetHeader("referer", "www.foo.com");
8629 request.extra_headers.SetHeader("hEllo", "Kitty");
8630 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478631
danakj1fd259a02016-04-16 03:17:098632 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168633 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278634
[email protected]270c6412010-03-29 22:02:478635 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238636 MockWrite(
8637 "GET / HTTP/1.1\r\n"
8638 "Host: www.example.org\r\n"
8639 "Connection: keep-alive\r\n"
8640 "referer: www.foo.com\r\n"
8641 "hEllo: Kitty\r\n"
8642 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478643 };
8644
8645 // Lastly, the server responds with the actual content.
8646 MockRead data_reads[] = {
8647 MockRead("HTTP/1.0 200 OK\r\n"),
8648 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8649 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068650 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478651 };
8652
8653 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8654 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078655 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478656
[email protected]49639fa2011-12-20 23:22:418657 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478658
tfarina42834112016-09-22 13:38:208659 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018660 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:478661
8662 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018663 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:478664}
8665
bncd16676a2016-07-20 16:23:018666TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278667 HttpRequestInfo request;
8668 request.method = "GET";
bncce36dca22015-04-21 22:11:238669 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278670 request.load_flags = 0;
8671
rdsmith82957ad2015-09-16 19:42:038672 session_deps_.proxy_service =
8673 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518674 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078675 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028676
danakj1fd259a02016-04-16 03:17:098677 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168678 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028679
[email protected]3cd17242009-06-23 02:59:028680 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8681 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8682
8683 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238684 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8685 MockWrite(
8686 "GET / HTTP/1.1\r\n"
8687 "Host: www.example.org\r\n"
8688 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028689
8690 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068691 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028692 MockRead("HTTP/1.0 200 OK\r\n"),
8693 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8694 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068695 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028696 };
8697
[email protected]31a2bfe2010-02-09 08:03:398698 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8699 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078700 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028701
[email protected]49639fa2011-12-20 23:22:418702 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028703
tfarina42834112016-09-22 13:38:208704 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018705 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:028706
8707 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018708 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028709
bnc691fda62016-08-12 00:43:168710 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528711 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028712
[email protected]029c83b62013-01-24 05:28:208713 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168714 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208715 TestLoadTimingNotReusedWithPac(load_timing_info,
8716 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8717
[email protected]3cd17242009-06-23 02:59:028718 std::string response_text;
bnc691fda62016-08-12 00:43:168719 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018720 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028721 EXPECT_EQ("Payload", response_text);
8722}
8723
bncd16676a2016-07-20 16:23:018724TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278725 HttpRequestInfo request;
8726 request.method = "GET";
bncce36dca22015-04-21 22:11:238727 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278728 request.load_flags = 0;
8729
rdsmith82957ad2015-09-16 19:42:038730 session_deps_.proxy_service =
8731 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518732 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078733 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028734
danakj1fd259a02016-04-16 03:17:098735 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168736 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028737
[email protected]3cd17242009-06-23 02:59:028738 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8739 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8740
8741 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238742 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8743 arraysize(write_buffer)),
8744 MockWrite(
8745 "GET / HTTP/1.1\r\n"
8746 "Host: www.example.org\r\n"
8747 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028748
8749 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018750 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8751 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358752 MockRead("HTTP/1.0 200 OK\r\n"),
8753 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8754 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068755 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358756 };
8757
[email protected]31a2bfe2010-02-09 08:03:398758 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8759 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078760 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358761
[email protected]8ddf8322012-02-23 18:08:068762 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078763 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358764
[email protected]49639fa2011-12-20 23:22:418765 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358766
tfarina42834112016-09-22 13:38:208767 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018768 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:358769
8770 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018771 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:358772
[email protected]029c83b62013-01-24 05:28:208773 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168774 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208775 TestLoadTimingNotReusedWithPac(load_timing_info,
8776 CONNECT_TIMING_HAS_SSL_TIMES);
8777
bnc691fda62016-08-12 00:43:168778 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528779 ASSERT_TRUE(response);
[email protected]e0c27be2009-07-15 13:09:358780
8781 std::string response_text;
bnc691fda62016-08-12 00:43:168782 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018783 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:358784 EXPECT_EQ("Payload", response_text);
8785}
8786
bncd16676a2016-07-20 16:23:018787TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:208788 HttpRequestInfo request;
8789 request.method = "GET";
bncce36dca22015-04-21 22:11:238790 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:208791 request.load_flags = 0;
8792
rdsmith82957ad2015-09-16 19:42:038793 session_deps_.proxy_service =
8794 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518795 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078796 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:208797
danakj1fd259a02016-04-16 03:17:098798 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168799 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:208800
8801 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8802 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8803
8804 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238805 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8806 MockWrite(
8807 "GET / HTTP/1.1\r\n"
8808 "Host: www.example.org\r\n"
8809 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:208810
8811 MockRead data_reads[] = {
8812 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
8813 MockRead("HTTP/1.0 200 OK\r\n"),
8814 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8815 MockRead("Payload"),
8816 MockRead(SYNCHRONOUS, OK)
8817 };
8818
8819 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8820 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078821 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:208822
8823 TestCompletionCallback callback;
8824
tfarina42834112016-09-22 13:38:208825 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:208827
8828 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018829 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:208830
bnc691fda62016-08-12 00:43:168831 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528832 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:208833
8834 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168835 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208836 TestLoadTimingNotReused(load_timing_info,
8837 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8838
8839 std::string response_text;
bnc691fda62016-08-12 00:43:168840 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018841 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:208842 EXPECT_EQ("Payload", response_text);
8843}
8844
bncd16676a2016-07-20 16:23:018845TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278846 HttpRequestInfo request;
8847 request.method = "GET";
bncce36dca22015-04-21 22:11:238848 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278849 request.load_flags = 0;
8850
rdsmith82957ad2015-09-16 19:42:038851 session_deps_.proxy_service =
8852 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518853 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078854 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358855
danakj1fd259a02016-04-16 03:17:098856 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168857 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:358858
[email protected]e0c27be2009-07-15 13:09:358859 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8860 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378861 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238862 0x05, // Version
8863 0x01, // Command (CONNECT)
8864 0x00, // Reserved.
8865 0x03, // Address type (DOMAINNAME).
8866 0x0F, // Length of domain (15)
8867 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8868 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:378869 };
[email protected]e0c27be2009-07-15 13:09:358870 const char kSOCKS5OkResponse[] =
8871 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
8872
8873 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238874 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8875 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
8876 MockWrite(
8877 "GET / HTTP/1.1\r\n"
8878 "Host: www.example.org\r\n"
8879 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358880
8881 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018882 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8883 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:358884 MockRead("HTTP/1.0 200 OK\r\n"),
8885 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8886 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068887 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358888 };
8889
[email protected]31a2bfe2010-02-09 08:03:398890 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8891 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078892 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358893
[email protected]49639fa2011-12-20 23:22:418894 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358895
tfarina42834112016-09-22 13:38:208896 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:358898
8899 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018900 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:358901
bnc691fda62016-08-12 00:43:168902 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528903 ASSERT_TRUE(response);
[email protected]e0c27be2009-07-15 13:09:358904
[email protected]029c83b62013-01-24 05:28:208905 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168906 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208907 TestLoadTimingNotReusedWithPac(load_timing_info,
8908 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8909
[email protected]e0c27be2009-07-15 13:09:358910 std::string response_text;
bnc691fda62016-08-12 00:43:168911 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018912 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:358913 EXPECT_EQ("Payload", response_text);
8914}
8915
bncd16676a2016-07-20 16:23:018916TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278917 HttpRequestInfo request;
8918 request.method = "GET";
bncce36dca22015-04-21 22:11:238919 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278920 request.load_flags = 0;
8921
rdsmith82957ad2015-09-16 19:42:038922 session_deps_.proxy_service =
8923 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518924 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078925 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358926
danakj1fd259a02016-04-16 03:17:098927 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168928 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:358929
[email protected]e0c27be2009-07-15 13:09:358930 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8931 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378932 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238933 0x05, // Version
8934 0x01, // Command (CONNECT)
8935 0x00, // Reserved.
8936 0x03, // Address type (DOMAINNAME).
8937 0x0F, // Length of domain (15)
8938 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8939 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:378940 };
8941
[email protected]e0c27be2009-07-15 13:09:358942 const char kSOCKS5OkResponse[] =
8943 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
8944
8945 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238946 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8947 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
8948 arraysize(kSOCKS5OkRequest)),
8949 MockWrite(
8950 "GET / HTTP/1.1\r\n"
8951 "Host: www.example.org\r\n"
8952 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358953
8954 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018955 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8956 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:028957 MockRead("HTTP/1.0 200 OK\r\n"),
8958 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8959 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068960 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028961 };
8962
[email protected]31a2bfe2010-02-09 08:03:398963 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8964 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078965 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028966
[email protected]8ddf8322012-02-23 18:08:068967 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078968 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:028969
[email protected]49639fa2011-12-20 23:22:418970 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028971
tfarina42834112016-09-22 13:38:208972 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018973 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:028974
8975 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018976 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028977
bnc691fda62016-08-12 00:43:168978 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528979 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028980
[email protected]029c83b62013-01-24 05:28:208981 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168982 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208983 TestLoadTimingNotReusedWithPac(load_timing_info,
8984 CONNECT_TIMING_HAS_SSL_TIMES);
8985
[email protected]3cd17242009-06-23 02:59:028986 std::string response_text;
bnc691fda62016-08-12 00:43:168987 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018988 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028989 EXPECT_EQ("Payload", response_text);
8990}
8991
[email protected]448d4ca52012-03-04 04:12:238992namespace {
8993
[email protected]04e5be32009-06-26 20:00:318994// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:068995
8996struct GroupNameTest {
8997 std::string proxy_server;
8998 std::string url;
8999 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189000 bool ssl;
[email protected]2d731a32010-04-29 01:04:069001};
9002
danakj1fd259a02016-04-16 03:17:099003std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079004 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099005 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069006
bnc525e175a2016-06-20 12:36:409007 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539008 session->http_server_properties();
bnccacc0992015-03-20 20:22:229009 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:409010 AlternateProtocolFromNextProto(kProtoHTTP2), "", 444);
bnc7dc7e1b42015-07-28 14:43:129011 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229012 http_server_properties->SetAlternativeService(
bncaa60ff402016-06-22 19:12:429013 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469014 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069015
9016 return session;
9017}
9018
mmenkee65e7af2015-10-13 17:16:429019int GroupNameTransactionHelper(const std::string& url,
9020 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069021 HttpRequestInfo request;
9022 request.method = "GET";
9023 request.url = GURL(url);
9024 request.load_flags = 0;
9025
bnc691fda62016-08-12 00:43:169026 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279027
[email protected]49639fa2011-12-20 23:22:419028 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069029
9030 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209031 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069032}
9033
[email protected]448d4ca52012-03-04 04:12:239034} // namespace
9035
bncd16676a2016-07-20 16:23:019036TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069037 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239038 {
9039 "", // unused
9040 "http://www.example.org/direct",
9041 "www.example.org:80",
9042 false,
9043 },
9044 {
9045 "", // unused
9046 "http://[2001:1418:13:1::25]/direct",
9047 "[2001:1418:13:1::25]:80",
9048 false,
9049 },
[email protected]04e5be32009-06-26 20:00:319050
bncce36dca22015-04-21 22:11:239051 // SSL Tests
9052 {
9053 "", // unused
9054 "https://www.example.org/direct_ssl",
9055 "ssl/www.example.org:443",
9056 true,
9057 },
9058 {
9059 "", // unused
9060 "https://[2001:1418:13:1::25]/direct",
9061 "ssl/[2001:1418:13:1::25]:443",
9062 true,
9063 },
9064 {
9065 "", // unused
bncaa60ff402016-06-22 19:12:429066 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239067 "ssl/host.with.alternate:443",
9068 true,
9069 },
[email protected]2d731a32010-04-29 01:04:069070 };
[email protected]2ff8b312010-04-26 22:20:549071
viettrungluue4a8b882014-10-16 06:17:389072 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039073 session_deps_.proxy_service =
9074 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099075 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409076 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069077
mmenkee65e7af2015-10-13 17:16:429078 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289079 CaptureGroupNameTransportSocketPool* transport_conn_pool =
9080 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139081 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349082 new CaptureGroupNameSSLSocketPool(NULL, NULL);
danakj1fd259a02016-04-16 03:17:099083 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449084 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029085 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9086 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489087 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069088
9089 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429090 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189091 if (tests[i].ssl)
9092 EXPECT_EQ(tests[i].expected_group_name,
9093 ssl_conn_pool->last_group_name_received());
9094 else
9095 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289096 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069097 }
[email protected]2d731a32010-04-29 01:04:069098}
9099
bncd16676a2016-07-20 16:23:019100TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069101 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239102 {
9103 "http_proxy",
9104 "http://www.example.org/http_proxy_normal",
9105 "www.example.org:80",
9106 false,
9107 },
[email protected]2d731a32010-04-29 01:04:069108
bncce36dca22015-04-21 22:11:239109 // SSL Tests
9110 {
9111 "http_proxy",
9112 "https://www.example.org/http_connect_ssl",
9113 "ssl/www.example.org:443",
9114 true,
9115 },
[email protected]af3490e2010-10-16 21:02:299116
bncce36dca22015-04-21 22:11:239117 {
9118 "http_proxy",
bncaa60ff402016-06-22 19:12:429119 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239120 "ssl/host.with.alternate:443",
9121 true,
9122 },
[email protected]45499252013-01-23 17:12:569123
bncce36dca22015-04-21 22:11:239124 {
9125 "http_proxy",
9126 "ftp://ftp.google.com/http_proxy_normal",
9127 "ftp/ftp.google.com:21",
9128 false,
9129 },
[email protected]2d731a32010-04-29 01:04:069130 };
9131
viettrungluue4a8b882014-10-16 06:17:389132 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039133 session_deps_.proxy_service =
9134 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099135 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409136 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069137
mmenkee65e7af2015-10-13 17:16:429138 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069139
[email protected]e60e47a2010-07-14 03:37:189140 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139141 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349142 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139143 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349144 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029145
danakj1fd259a02016-04-16 03:17:099146 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449147 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029148 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
9149 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489150 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069151
9152 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429153 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189154 if (tests[i].ssl)
9155 EXPECT_EQ(tests[i].expected_group_name,
9156 ssl_conn_pool->last_group_name_received());
9157 else
9158 EXPECT_EQ(tests[i].expected_group_name,
9159 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069160 }
[email protected]2d731a32010-04-29 01:04:069161}
9162
bncd16676a2016-07-20 16:23:019163TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069164 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239165 {
9166 "socks4://socks_proxy:1080",
9167 "http://www.example.org/socks4_direct",
9168 "socks4/www.example.org:80",
9169 false,
9170 },
9171 {
9172 "socks5://socks_proxy:1080",
9173 "http://www.example.org/socks5_direct",
9174 "socks5/www.example.org:80",
9175 false,
9176 },
[email protected]2d731a32010-04-29 01:04:069177
bncce36dca22015-04-21 22:11:239178 // SSL Tests
9179 {
9180 "socks4://socks_proxy:1080",
9181 "https://www.example.org/socks4_ssl",
9182 "socks4/ssl/www.example.org:443",
9183 true,
9184 },
9185 {
9186 "socks5://socks_proxy:1080",
9187 "https://www.example.org/socks5_ssl",
9188 "socks5/ssl/www.example.org:443",
9189 true,
9190 },
[email protected]af3490e2010-10-16 21:02:299191
bncce36dca22015-04-21 22:11:239192 {
9193 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429194 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239195 "socks4/ssl/host.with.alternate:443",
9196 true,
9197 },
[email protected]04e5be32009-06-26 20:00:319198 };
9199
viettrungluue4a8b882014-10-16 06:17:389200 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039201 session_deps_.proxy_service =
9202 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099203 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409204 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029205
mmenkee65e7af2015-10-13 17:16:429206 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319207
[email protected]e60e47a2010-07-14 03:37:189208 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139209 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349210 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139211 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349212 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029213
danakj1fd259a02016-04-16 03:17:099214 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449215 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029216 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
9217 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489218 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319219
bnc691fda62016-08-12 00:43:169220 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319221
[email protected]2d731a32010-04-29 01:04:069222 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429223 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189224 if (tests[i].ssl)
9225 EXPECT_EQ(tests[i].expected_group_name,
9226 ssl_conn_pool->last_group_name_received());
9227 else
9228 EXPECT_EQ(tests[i].expected_group_name,
9229 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319230 }
9231}
9232
bncd16676a2016-07-20 16:23:019233TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279234 HttpRequestInfo request;
9235 request.method = "GET";
bncce36dca22015-04-21 22:11:239236 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279237
rdsmith82957ad2015-09-16 19:42:039238 session_deps_.proxy_service =
9239 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329240
[email protected]69719062010-01-05 20:09:219241 // This simulates failure resolving all hostnames; that means we will fail
9242 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079243 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329244
danakj1fd259a02016-04-16 03:17:099245 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169246 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259247
[email protected]49639fa2011-12-20 23:22:419248 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259249
tfarina42834112016-09-22 13:38:209250 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019251 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259252
[email protected]9172a982009-06-06 00:30:259253 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019254 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259255}
9256
[email protected]685af592010-05-11 19:31:249257// Base test to make sure that when the load flags for a request specify to
9258// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029259void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079260 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279261 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109262 HttpRequestInfo request_info;
9263 request_info.method = "GET";
9264 request_info.load_flags = load_flags;
9265 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279266
[email protected]a2c2fb92009-07-18 07:31:049267 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:079268 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:329269
danakj1fd259a02016-04-16 03:17:099270 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169271 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289272
bncce36dca22015-04-21 22:11:239273 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289274 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299275 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109276 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079277 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239278 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109279 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209280 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019281 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479282 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019283 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289284
9285 // Verify that it was added to host cache, by doing a subsequent async lookup
9286 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109287 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079288 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239289 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109290 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209291 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019292 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289293
bncce36dca22015-04-21 22:11:239294 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289295 // we can tell if the next lookup hit the cache, or the "network".
9296 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239297 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289298
9299 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9300 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069301 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399302 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079303 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289304
[email protected]3b9cca42009-06-16 01:08:289305 // Run the request.
tfarina42834112016-09-22 13:38:209306 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019307 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419308 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289309
9310 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239311 // "www.example.org".
robpercival214763f2016-07-01 23:27:019312 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289313}
9314
[email protected]685af592010-05-11 19:31:249315// There are multiple load flags that should trigger the host cache bypass.
9316// Test each in isolation:
bncd16676a2016-07-20 16:23:019317TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249318 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9319}
9320
bncd16676a2016-07-20 16:23:019321TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249322 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9323}
9324
bncd16676a2016-07-20 16:23:019325TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249326 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9327}
9328
[email protected]0877e3d2009-10-17 22:29:579329// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019330TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579331 HttpRequestInfo request;
9332 request.method = "GET";
9333 request.url = GURL("http://www.foo.com/");
9334 request.load_flags = 0;
9335
9336 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069337 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579338 };
[email protected]31a2bfe2010-02-09 08:03:399339 StaticSocketDataProvider data(NULL, 0,
9340 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079341 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099342 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579343
[email protected]49639fa2011-12-20 23:22:419344 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579345
bnc691fda62016-08-12 00:43:169346 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579347
tfarina42834112016-09-22 13:38:209348 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019349 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579350
9351 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019352 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599353
9354 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169355 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599356 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579357}
9358
zmo9528c9f42015-08-04 22:12:089359// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019360TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579361 HttpRequestInfo request;
9362 request.method = "GET";
9363 request.url = GURL("http://www.foo.com/");
9364 request.load_flags = 0;
9365
9366 MockRead data_reads[] = {
9367 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069368 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579369 };
9370
[email protected]31a2bfe2010-02-09 08:03:399371 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079372 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579374
[email protected]49639fa2011-12-20 23:22:419375 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579376
bnc691fda62016-08-12 00:43:169377 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579378
tfarina42834112016-09-22 13:38:209379 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019380 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579381
9382 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019383 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089384
bnc691fda62016-08-12 00:43:169385 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529386 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089387
wezca1070932016-05-26 20:30:529388 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089389 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9390
9391 std::string response_data;
bnc691fda62016-08-12 00:43:169392 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019393 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089394 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599395
9396 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169397 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599398 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579399}
9400
9401// Make sure that a dropped connection while draining the body for auth
9402// restart does the right thing.
bncd16676a2016-07-20 16:23:019403TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579404 HttpRequestInfo request;
9405 request.method = "GET";
bncce36dca22015-04-21 22:11:239406 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579407 request.load_flags = 0;
9408
9409 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239410 MockWrite(
9411 "GET / HTTP/1.1\r\n"
9412 "Host: www.example.org\r\n"
9413 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579414 };
9415
9416 MockRead data_reads1[] = {
9417 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9418 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9419 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9420 MockRead("Content-Length: 14\r\n\r\n"),
9421 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069422 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579423 };
9424
[email protected]31a2bfe2010-02-09 08:03:399425 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9426 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079427 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579428
bnc691fda62016-08-12 00:43:169429 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579430 // be issuing -- the final header line contains the credentials.
9431 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239432 MockWrite(
9433 "GET / HTTP/1.1\r\n"
9434 "Host: www.example.org\r\n"
9435 "Connection: keep-alive\r\n"
9436 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579437 };
9438
9439 // Lastly, the server responds with the actual content.
9440 MockRead data_reads2[] = {
9441 MockRead("HTTP/1.1 200 OK\r\n"),
9442 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9443 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069444 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579445 };
9446
[email protected]31a2bfe2010-02-09 08:03:399447 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9448 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079449 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579451
[email protected]49639fa2011-12-20 23:22:419452 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579453
bnc691fda62016-08-12 00:43:169454 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509455
tfarina42834112016-09-22 13:38:209456 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019457 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579458
9459 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019460 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579461
bnc691fda62016-08-12 00:43:169462 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529463 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049464 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579465
[email protected]49639fa2011-12-20 23:22:419466 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579467
bnc691fda62016-08-12 00:43:169468 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579470
9471 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019472 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579473
bnc691fda62016-08-12 00:43:169474 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529475 ASSERT_TRUE(response);
9476 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579477 EXPECT_EQ(100, response->headers->GetContentLength());
9478}
9479
9480// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019481TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039482 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579483
9484 HttpRequestInfo request;
9485 request.method = "GET";
bncce36dca22015-04-21 22:11:239486 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579487 request.load_flags = 0;
9488
9489 MockRead proxy_reads[] = {
9490 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069491 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579492 };
9493
[email protected]31a2bfe2010-02-09 08:03:399494 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069495 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579496
[email protected]bb88e1d32013-05-03 23:11:079497 session_deps_.socket_factory->AddSocketDataProvider(&data);
9498 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579499
[email protected]49639fa2011-12-20 23:22:419500 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579501
[email protected]bb88e1d32013-05-03 23:11:079502 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579503
danakj1fd259a02016-04-16 03:17:099504 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169505 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579506
tfarina42834112016-09-22 13:38:209507 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019508 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579509
9510 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019511 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:579512}
9513
bncd16676a2016-07-20 16:23:019514TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469515 HttpRequestInfo request;
9516 request.method = "GET";
bncce36dca22015-04-21 22:11:239517 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469518 request.load_flags = 0;
9519
danakj1fd259a02016-04-16 03:17:099520 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169521 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279522
[email protected]e22e1362009-11-23 21:31:129523 MockRead data_reads[] = {
9524 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069525 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129526 };
[email protected]9492e4a2010-02-24 00:58:469527
9528 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079529 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469530
[email protected]49639fa2011-12-20 23:22:419531 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469532
tfarina42834112016-09-22 13:38:209533 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:469535
robpercival214763f2016-07-01 23:27:019536 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:469537
bnc691fda62016-08-12 00:43:169538 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529539 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469540
wezca1070932016-05-26 20:30:529541 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469542 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9543
9544 std::string response_data;
bnc691fda62016-08-12 00:43:169545 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019546 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:129547}
9548
bncd16676a2016-07-20 16:23:019549TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159550 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529551 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149552 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219553 UploadFileElementReader::ScopedOverridingContentLengthForTests
9554 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339555
danakj1fd259a02016-04-16 03:17:099556 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079557 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149558 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:079559 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229560 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279561
9562 HttpRequestInfo request;
9563 request.method = "POST";
bncce36dca22015-04-21 22:11:239564 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279565 request.upload_data_stream = &upload_data_stream;
9566 request.load_flags = 0;
9567
danakj1fd259a02016-04-16 03:17:099568 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169569 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:339570
9571 MockRead data_reads[] = {
9572 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9573 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069574 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339575 };
[email protected]31a2bfe2010-02-09 08:03:399576 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079577 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339578
[email protected]49639fa2011-12-20 23:22:419579 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339580
tfarina42834112016-09-22 13:38:209581 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019582 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:339583
9584 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019585 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:339586
bnc691fda62016-08-12 00:43:169587 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529588 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339589
maksim.sisove869bf52016-06-23 17:11:529590 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339591
[email protected]dd3aa792013-07-16 19:10:239592 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339593}
9594
bncd16676a2016-07-20 16:23:019595TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159596 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529597 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369598 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:309599 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:369600 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119601 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369602
danakj1fd259a02016-04-16 03:17:099603 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079604 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149605 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:079606 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229607 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279608
9609 HttpRequestInfo request;
9610 request.method = "POST";
bncce36dca22015-04-21 22:11:239611 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279612 request.upload_data_stream = &upload_data_stream;
9613 request.load_flags = 0;
9614
[email protected]999dd8c2013-11-12 06:45:549615 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099616 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169617 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:369618
[email protected]999dd8c2013-11-12 06:45:549619 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079620 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369621
[email protected]49639fa2011-12-20 23:22:419622 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369623
tfarina42834112016-09-22 13:38:209624 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:369626
9627 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019628 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:369629
[email protected]dd3aa792013-07-16 19:10:239630 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369631}
9632
bncd16676a2016-07-20 16:23:019633TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:039634 class FakeUploadElementReader : public UploadElementReader {
9635 public:
9636 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209637 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039638
9639 const CompletionCallback& callback() const { return callback_; }
9640
9641 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209642 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039643 callback_ = callback;
9644 return ERR_IO_PENDING;
9645 }
avibf0746c2015-12-09 19:53:149646 uint64_t GetContentLength() const override { return 0; }
9647 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209648 int Read(IOBuffer* buf,
9649 int buf_length,
9650 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039651 return ERR_FAILED;
9652 }
9653
9654 private:
9655 CompletionCallback callback_;
9656 };
9657
9658 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099659 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9660 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229661 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039662
9663 HttpRequestInfo request;
9664 request.method = "POST";
bncce36dca22015-04-21 22:11:239665 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039666 request.upload_data_stream = &upload_data_stream;
9667 request.load_flags = 0;
9668
danakj1fd259a02016-04-16 03:17:099669 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169670 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:419671 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039672
9673 StaticSocketDataProvider data;
9674 session_deps_.socket_factory->AddSocketDataProvider(&data);
9675
9676 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:209677 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019678 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:559679 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039680
9681 // Transaction is pending on request body initialization.
9682 ASSERT_FALSE(fake_reader->callback().is_null());
9683
9684 // Return Init()'s result after the transaction gets destroyed.
9685 trans.reset();
9686 fake_reader->callback().Run(OK); // Should not crash.
9687}
9688
[email protected]aeefc9e82010-02-19 16:18:279689// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:019690TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279691 HttpRequestInfo request;
9692 request.method = "GET";
bncce36dca22015-04-21 22:11:239693 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279694 request.load_flags = 0;
9695
9696 // First transaction will request a resource and receive a Basic challenge
9697 // with realm="first_realm".
9698 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239699 MockWrite(
9700 "GET / HTTP/1.1\r\n"
9701 "Host: www.example.org\r\n"
9702 "Connection: keep-alive\r\n"
9703 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279704 };
9705 MockRead data_reads1[] = {
9706 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9707 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9708 "\r\n"),
9709 };
9710
bnc691fda62016-08-12 00:43:169711 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:279712 // for first_realm. The server will reject and provide a challenge with
9713 // second_realm.
9714 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239715 MockWrite(
9716 "GET / HTTP/1.1\r\n"
9717 "Host: www.example.org\r\n"
9718 "Connection: keep-alive\r\n"
9719 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9720 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279721 };
9722 MockRead data_reads2[] = {
9723 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9724 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9725 "\r\n"),
9726 };
9727
9728 // This again fails, and goes back to first_realm. Make sure that the
9729 // entry is removed from cache.
9730 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239731 MockWrite(
9732 "GET / HTTP/1.1\r\n"
9733 "Host: www.example.org\r\n"
9734 "Connection: keep-alive\r\n"
9735 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9736 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279737 };
9738 MockRead data_reads3[] = {
9739 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9740 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9741 "\r\n"),
9742 };
9743
9744 // Try one last time (with the correct password) and get the resource.
9745 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239746 MockWrite(
9747 "GET / HTTP/1.1\r\n"
9748 "Host: www.example.org\r\n"
9749 "Connection: keep-alive\r\n"
9750 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9751 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279752 };
9753 MockRead data_reads4[] = {
9754 MockRead("HTTP/1.1 200 OK\r\n"
9755 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509756 "Content-Length: 5\r\n"
9757 "\r\n"
9758 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279759 };
9760
9761 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9762 data_writes1, arraysize(data_writes1));
9763 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9764 data_writes2, arraysize(data_writes2));
9765 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9766 data_writes3, arraysize(data_writes3));
9767 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9768 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079769 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9770 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9771 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9772 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279773
[email protected]49639fa2011-12-20 23:22:419774 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279775
danakj1fd259a02016-04-16 03:17:099776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509778
[email protected]aeefc9e82010-02-19 16:18:279779 // Issue the first request with Authorize headers. There should be a
9780 // password prompt for first_realm waiting to be filled in after the
9781 // transaction completes.
tfarina42834112016-09-22 13:38:209782 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:279784 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019785 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169786 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529787 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049788 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529789 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049790 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:439791 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:049792 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199793 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279794
9795 // Issue the second request with an incorrect password. There should be a
9796 // password prompt for second_realm waiting to be filled in after the
9797 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419798 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169799 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
9800 callback2.callback());
robpercival214763f2016-07-01 23:27:019801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:279802 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019803 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169804 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529805 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049806 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529807 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049808 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:439809 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:049810 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199811 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279812
9813 // Issue the third request with another incorrect password. There should be
9814 // a password prompt for first_realm waiting to be filled in. If the password
9815 // prompt is not present, it indicates that the HttpAuthCacheEntry for
9816 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:419817 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:169818 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
9819 callback3.callback());
robpercival214763f2016-07-01 23:27:019820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:279821 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:019822 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169823 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529824 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049825 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529826 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049827 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:439828 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:049829 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199830 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279831
9832 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:419833 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:169834 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
9835 callback4.callback());
robpercival214763f2016-07-01 23:27:019836 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:279837 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:019838 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169839 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529840 ASSERT_TRUE(response);
9841 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:279842}
9843
bncd16676a2016-07-20 16:23:019844TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:529845 MockRead data_reads[] = {
9846 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:439847 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:529848 MockRead("\r\n"),
9849 MockRead("hello world"),
9850 MockRead(SYNCHRONOUS, OK),
9851 };
9852
9853 HttpRequestInfo request;
9854 request.method = "GET";
bncb26024382016-06-29 02:39:459855 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:529856 request.load_flags = 0;
9857
9858 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:529859 session_deps_.socket_factory->AddSocketDataProvider(&data);
9860
bncb26024382016-06-29 02:39:459861 SSLSocketDataProvider ssl(ASYNC, OK);
9862 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9863
bncc958faa2015-07-31 18:14:529864 TestCompletionCallback callback;
9865
danakj1fd259a02016-04-16 03:17:099866 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169867 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:529868
tfarina42834112016-09-22 13:38:209869 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019870 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:529871
bncb26024382016-06-29 02:39:459872 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:409873 HttpServerProperties* http_server_properties =
9874 session->http_server_properties();
bncc958faa2015-07-31 18:14:529875 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:409876 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:529877 EXPECT_TRUE(alternative_service_vector.empty());
9878
robpercival214763f2016-07-01 23:27:019879 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:529880
bnc691fda62016-08-12 00:43:169881 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529882 ASSERT_TRUE(response);
9883 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:529884 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9885 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:529886 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:529887
9888 std::string response_data;
bnc691fda62016-08-12 00:43:169889 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:529890 EXPECT_EQ("hello world", response_data);
9891
9892 alternative_service_vector =
bnc525e175a2016-06-20 12:36:409893 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:529894 ASSERT_EQ(1u, alternative_service_vector.size());
bnca9b9e222016-07-11 20:10:409895 EXPECT_EQ(AlternateProtocolFromNextProto(kProtoHTTP2),
bncc958faa2015-07-31 18:14:529896 alternative_service_vector[0].protocol);
bncb26024382016-06-29 02:39:459897 EXPECT_EQ("mail.example.org", alternative_service_vector[0].host);
bncc958faa2015-07-31 18:14:529898 EXPECT_EQ(443, alternative_service_vector[0].port);
9899}
9900
bnce3dd56f2016-06-01 10:37:119901// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:019902TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:119903 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:119904 MockRead data_reads[] = {
9905 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:439906 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:119907 MockRead("\r\n"),
9908 MockRead("hello world"),
9909 MockRead(SYNCHRONOUS, OK),
9910 };
9911
9912 HttpRequestInfo request;
9913 request.method = "GET";
9914 request.url = GURL("http://www.example.org/");
9915 request.load_flags = 0;
9916
9917 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9918 session_deps_.socket_factory->AddSocketDataProvider(&data);
9919
9920 TestCompletionCallback callback;
9921
9922 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169923 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:119924
9925 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:409926 HttpServerProperties* http_server_properties =
9927 session->http_server_properties();
bnce3dd56f2016-06-01 10:37:119928 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:409929 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:119930 EXPECT_TRUE(alternative_service_vector.empty());
9931
tfarina42834112016-09-22 13:38:209932 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019933 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9934 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:119935
bnc691fda62016-08-12 00:43:169936 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:119937 ASSERT_TRUE(response);
9938 ASSERT_TRUE(response->headers);
9939 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9940 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:529941 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:119942
9943 std::string response_data;
bnc691fda62016-08-12 00:43:169944 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:119945 EXPECT_EQ("hello world", response_data);
9946
9947 alternative_service_vector =
bnc525e175a2016-06-20 12:36:409948 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:119949 EXPECT_TRUE(alternative_service_vector.empty());
9950}
9951
bnc8bef8da22016-05-30 01:28:259952// HTTP/2 Alternative Services should be disabled if alternative service
9953// hostname is different from that of origin.
9954// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:019955TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:259956 DisableHTTP2AlternativeServicesWithDifferentHost) {
bncb26024382016-06-29 02:39:459957 session_deps_.enable_http2_alternative_service_with_different_host = false;
9958
bnc8bef8da22016-05-30 01:28:259959 HttpRequestInfo request;
9960 request.method = "GET";
bncb26024382016-06-29 02:39:459961 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:259962 request.load_flags = 0;
9963
9964 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9965 StaticSocketDataProvider first_data;
9966 first_data.set_connect_data(mock_connect);
9967 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:459968 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369969 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:459970 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:259971
9972 MockRead data_reads[] = {
9973 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
9974 MockRead(ASYNC, OK),
9975 };
9976 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
9977 0);
9978 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
9979
9980 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9981
bnc525e175a2016-06-20 12:36:409982 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:259983 session->http_server_properties();
9984 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:409985 AlternateProtocolFromNextProto(kProtoHTTP2), "different.example.org",
bnc8bef8da22016-05-30 01:28:259986 444);
9987 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9988 http_server_properties->SetAlternativeService(
9989 url::SchemeHostPort(request.url), alternative_service, expiration);
9990
bnc691fda62016-08-12 00:43:169991 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:259992 TestCompletionCallback callback;
9993
tfarina42834112016-09-22 13:38:209994 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:259995 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:019996 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:259997}
9998
bnce3dd56f2016-06-01 10:37:119999// Regression test for https://crbug.com/615497:
10000// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110001TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110002 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110003 HttpRequestInfo request;
10004 request.method = "GET";
10005 request.url = GURL("http://www.example.org/");
10006 request.load_flags = 0;
10007
10008 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10009 StaticSocketDataProvider first_data;
10010 first_data.set_connect_data(mock_connect);
10011 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10012
10013 MockRead data_reads[] = {
10014 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10015 MockRead(ASYNC, OK),
10016 };
10017 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10018 0);
10019 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10020
10021 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10022
bnc525e175a2016-06-20 12:36:4010023 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110024 session->http_server_properties();
10025 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010026 AlternateProtocolFromNextProto(kProtoHTTP2), "", 444);
bnce3dd56f2016-06-01 10:37:1110027 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10028 http_server_properties->SetAlternativeService(
10029 url::SchemeHostPort(request.url), alternative_service, expiration);
10030
bnc691fda62016-08-12 00:43:1610031 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110032 TestCompletionCallback callback;
10033
tfarina42834112016-09-22 13:38:2010034 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110035 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110036 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110037}
10038
bncd16676a2016-07-20 16:23:0110039TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810040 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910041 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010042 HttpServerProperties* http_server_properties =
10043 session->http_server_properties();
bncb26024382016-06-29 02:39:4510044 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc4f575852015-10-14 18:35:0810045 AlternativeService alternative_service(QUIC, "", 80);
10046 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc525e175a2016-06-20 12:36:4010047 http_server_properties->SetAlternativeService(
10048 test_server, alternative_service, expiration);
bnc4f575852015-10-14 18:35:0810049 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010050 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810051 EXPECT_EQ(1u, alternative_service_vector.size());
10052
10053 // Send a clear header.
10054 MockRead data_reads[] = {
10055 MockRead("HTTP/1.1 200 OK\r\n"),
10056 MockRead("Alt-Svc: clear\r\n"),
10057 MockRead("\r\n"),
10058 MockRead("hello world"),
10059 MockRead(SYNCHRONOUS, OK),
10060 };
10061 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10062 session_deps_.socket_factory->AddSocketDataProvider(&data);
10063
bncb26024382016-06-29 02:39:4510064 SSLSocketDataProvider ssl(ASYNC, OK);
10065 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10066
bnc4f575852015-10-14 18:35:0810067 HttpRequestInfo request;
10068 request.method = "GET";
bncb26024382016-06-29 02:39:4510069 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810070 request.load_flags = 0;
10071
10072 TestCompletionCallback callback;
10073
bnc691fda62016-08-12 00:43:1610074 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810075
tfarina42834112016-09-22 13:38:2010076 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110077 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810078
bnc691fda62016-08-12 00:43:1610079 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210080 ASSERT_TRUE(response);
10081 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810082 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10083 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210084 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810085
10086 std::string response_data;
bnc691fda62016-08-12 00:43:1610087 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810088 EXPECT_EQ("hello world", response_data);
10089
10090 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010091 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810092 EXPECT_TRUE(alternative_service_vector.empty());
10093}
10094
bncd16676a2016-07-20 16:23:0110095TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210096 MockRead data_reads[] = {
10097 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310098 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10099 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210100 MockRead("hello world"),
10101 MockRead(SYNCHRONOUS, OK),
10102 };
10103
10104 HttpRequestInfo request;
10105 request.method = "GET";
bncb26024382016-06-29 02:39:4510106 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210107 request.load_flags = 0;
10108
10109 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210110 session_deps_.socket_factory->AddSocketDataProvider(&data);
10111
bncb26024382016-06-29 02:39:4510112 SSLSocketDataProvider ssl(ASYNC, OK);
10113 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10114
bncc958faa2015-07-31 18:14:5210115 TestCompletionCallback callback;
10116
danakj1fd259a02016-04-16 03:17:0910117 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610118 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210119
tfarina42834112016-09-22 13:38:2010120 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110121 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210122
bncb26024382016-06-29 02:39:4510123 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010124 HttpServerProperties* http_server_properties =
10125 session->http_server_properties();
bncc958faa2015-07-31 18:14:5210126 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010127 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210128 EXPECT_TRUE(alternative_service_vector.empty());
10129
robpercival214763f2016-07-01 23:27:0110130 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210131
bnc691fda62016-08-12 00:43:1610132 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210133 ASSERT_TRUE(response);
10134 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210135 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10136 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210137 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210138
10139 std::string response_data;
bnc691fda62016-08-12 00:43:1610140 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210141 EXPECT_EQ("hello world", response_data);
10142
10143 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010144 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210145 ASSERT_EQ(2u, alternative_service_vector.size());
bnca9b9e222016-07-11 20:10:4010146 EXPECT_EQ(AlternateProtocolFromNextProto(kProtoHTTP2),
bncc958faa2015-07-31 18:14:5210147 alternative_service_vector[0].protocol);
10148 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
10149 EXPECT_EQ(443, alternative_service_vector[0].port);
bnca9b9e222016-07-11 20:10:4010150 EXPECT_EQ(AlternateProtocolFromNextProto(kProtoHTTP2),
bnc3f0118e2016-02-02 15:42:2210151 alternative_service_vector[1].protocol);
bncc958faa2015-07-31 18:14:5210152 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
10153 EXPECT_EQ(1234, alternative_service_vector[1].port);
10154}
10155
bncd16676a2016-07-20 16:23:0110156TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610157 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210158 HostPortPair alternative("alternative.example.org", 443);
10159 std::string origin_url = "https://origin.example.org:443";
10160 std::string alternative_url = "https://alternative.example.org:443";
10161
10162 // Negotiate HTTP/1.1 with alternative.example.org.
10163 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610164 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210165 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10166
10167 // HTTP/1.1 data for request.
10168 MockWrite http_writes[] = {
10169 MockWrite("GET / HTTP/1.1\r\n"
10170 "Host: alternative.example.org\r\n"
10171 "Connection: keep-alive\r\n\r\n"),
10172 };
10173
10174 MockRead http_reads[] = {
10175 MockRead("HTTP/1.1 200 OK\r\n"
10176 "Content-Type: text/html; charset=iso-8859-1\r\n"
10177 "Content-Length: 40\r\n\r\n"
10178 "first HTTP/1.1 response from alternative"),
10179 };
10180 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10181 http_writes, arraysize(http_writes));
10182 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10183
10184 StaticSocketDataProvider data_refused;
10185 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10186 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10187
zhongyi3d4a55e72016-04-22 20:36:4610188 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910189 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010190 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210191 session->http_server_properties();
10192 AlternativeService alternative_service(QUIC, alternative);
10193 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610194 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5010195 expiration);
zhongyi48704c182015-12-07 07:52:0210196 // Mark the QUIC alternative service as broken.
10197 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10198
bnc691fda62016-08-12 00:43:1610199 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210200 HttpRequestInfo request;
10201 request.method = "GET";
10202 request.url = GURL(origin_url);
10203 request.load_flags = 0;
10204 TestCompletionCallback callback;
10205 NetErrorDetails details;
10206 EXPECT_FALSE(details.quic_broken);
10207
tfarina42834112016-09-22 13:38:2010208 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610209 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210210 EXPECT_TRUE(details.quic_broken);
10211}
10212
bncd16676a2016-07-20 16:23:0110213TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610214 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210215 HostPortPair alternative1("alternative1.example.org", 443);
10216 HostPortPair alternative2("alternative2.example.org", 443);
10217 std::string origin_url = "https://origin.example.org:443";
10218 std::string alternative_url1 = "https://alternative1.example.org:443";
10219 std::string alternative_url2 = "https://alternative2.example.org:443";
10220
10221 // Negotiate HTTP/1.1 with alternative1.example.org.
10222 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610223 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210224 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10225
10226 // HTTP/1.1 data for request.
10227 MockWrite http_writes[] = {
10228 MockWrite("GET / HTTP/1.1\r\n"
10229 "Host: alternative1.example.org\r\n"
10230 "Connection: keep-alive\r\n\r\n"),
10231 };
10232
10233 MockRead http_reads[] = {
10234 MockRead("HTTP/1.1 200 OK\r\n"
10235 "Content-Type: text/html; charset=iso-8859-1\r\n"
10236 "Content-Length: 40\r\n\r\n"
10237 "first HTTP/1.1 response from alternative1"),
10238 };
10239 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10240 http_writes, arraysize(http_writes));
10241 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10242
10243 StaticSocketDataProvider data_refused;
10244 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10245 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10246
danakj1fd259a02016-04-16 03:17:0910247 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010248 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210249 session->http_server_properties();
10250
zhongyi3d4a55e72016-04-22 20:36:4610251 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210252 AlternativeServiceInfoVector alternative_service_info_vector;
10253 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10254
10255 AlternativeService alternative_service1(QUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010256 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210257 expiration);
10258 alternative_service_info_vector.push_back(alternative_service_info1);
10259 AlternativeService alternative_service2(QUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010260 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210261 expiration);
10262 alternative_service_info_vector.push_back(alternative_service_info2);
10263
10264 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610265 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210266
10267 // Mark one of the QUIC alternative service as broken.
10268 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
10269
10270 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610271 http_server_properties->GetAlternativeServices(server);
zhongyi48704c182015-12-07 07:52:0210272
bnc691fda62016-08-12 00:43:1610273 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210274 HttpRequestInfo request;
10275 request.method = "GET";
10276 request.url = GURL(origin_url);
10277 request.load_flags = 0;
10278 TestCompletionCallback callback;
10279 NetErrorDetails details;
10280 EXPECT_FALSE(details.quic_broken);
10281
tfarina42834112016-09-22 13:38:2010282 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610283 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210284 EXPECT_FALSE(details.quic_broken);
10285}
10286
bncd16676a2016-07-20 16:23:0110287TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210288 HttpRequestInfo request;
10289 request.method = "GET";
bncb26024382016-06-29 02:39:4510290 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210291 request.load_flags = 0;
10292
[email protected]d973e99a2012-02-17 21:02:3610293 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210294 StaticSocketDataProvider first_data;
10295 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710296 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510297 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610298 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510299 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210300
10301 MockRead data_reads[] = {
10302 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10303 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610304 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210305 };
10306 StaticSocketDataProvider second_data(
10307 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710308 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210309
danakj1fd259a02016-04-16 03:17:0910310 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210311
bnc525e175a2016-06-20 12:36:4010312 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310313 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610314 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110315 // Port must be < 1024, or the header will be ignored (since initial port was
10316 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010317 const AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010318 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bncd9b132e2015-07-08 05:16:1010319 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210320 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610321 http_server_properties->SetAlternativeService(server, alternative_service,
10322 expiration);
[email protected]564b4912010-03-09 16:30:4210323
bnc691fda62016-08-12 00:43:1610324 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110325 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210326
tfarina42834112016-09-22 13:38:2010327 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10329 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210330
bnc691fda62016-08-12 00:43:1610331 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210332 ASSERT_TRUE(response);
10333 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210334 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10335
10336 std::string response_data;
bnc691fda62016-08-12 00:43:1610337 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210338 EXPECT_EQ("hello world", response_data);
10339
bncd9b132e2015-07-08 05:16:1010340 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610341 http_server_properties->GetAlternativeServices(server);
bncd9b132e2015-07-08 05:16:1010342 ASSERT_EQ(1u, alternative_service_vector.size());
10343 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
10344 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
10345 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:4210346}
10347
bnc55ff9da2015-08-19 18:42:3510348// Ensure that we are not allowed to redirect traffic via an alternate protocol
10349// to an unrestricted (port >= 1024) when the original traffic was on a
10350// restricted port (port < 1024). Ensure that we can redirect in all other
10351// cases.
bncd16676a2016-07-20 16:23:0110352TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110353 HttpRequestInfo restricted_port_request;
10354 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510355 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110356 restricted_port_request.load_flags = 0;
10357
[email protected]d973e99a2012-02-17 21:02:3610358 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110359 StaticSocketDataProvider first_data;
10360 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710361 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110362
10363 MockRead data_reads[] = {
10364 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10365 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610366 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110367 };
10368 StaticSocketDataProvider second_data(
10369 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710370 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510371 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610372 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510373 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110374
danakj1fd259a02016-04-16 03:17:0910375 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110376
bnc525e175a2016-06-20 12:36:4010377 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310378 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110379 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210380 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010381 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bnccacc0992015-03-20 20:22:2210382 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210383 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210384 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610385 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010386 expiration);
[email protected]3912662a32011-10-04 00:51:1110387
bnc691fda62016-08-12 00:43:1610388 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110389 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110390
tfarina42834112016-09-22 13:38:2010391 int rv = trans.Start(&restricted_port_request, callback.callback(),
10392 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110393 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110394 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110395 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910396}
[email protected]3912662a32011-10-04 00:51:1110397
bnc55ff9da2015-08-19 18:42:3510398// Ensure that we are allowed to redirect traffic via an alternate protocol to
10399// an unrestricted (port >= 1024) when the original traffic was on a restricted
10400// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110401TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710402 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910403
10404 HttpRequestInfo restricted_port_request;
10405 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510406 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910407 restricted_port_request.load_flags = 0;
10408
10409 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10410 StaticSocketDataProvider first_data;
10411 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710412 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910413
10414 MockRead data_reads[] = {
10415 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10416 MockRead("hello world"),
10417 MockRead(ASYNC, OK),
10418 };
10419 StaticSocketDataProvider second_data(
10420 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710421 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510422 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610423 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510424 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910425
danakj1fd259a02016-04-16 03:17:0910426 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910427
bnc525e175a2016-06-20 12:36:4010428 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910429 session->http_server_properties();
10430 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210431 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010432 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bnccacc0992015-03-20 20:22:2210433 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210434 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210435 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610436 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010437 expiration);
[email protected]c54c6962013-02-01 04:53:1910438
bnc691fda62016-08-12 00:43:1610439 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910440 TestCompletionCallback callback;
10441
tfarina42834112016-09-22 13:38:2010442 EXPECT_EQ(ERR_IO_PENDING,
10443 trans.Start(&restricted_port_request, callback.callback(),
10444 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910445 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110446 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110447}
10448
bnc55ff9da2015-08-19 18:42:3510449// Ensure that we are not allowed to redirect traffic via an alternate protocol
10450// to an unrestricted (port >= 1024) when the original traffic was on a
10451// restricted port (port < 1024). Ensure that we can redirect in all other
10452// cases.
bncd16676a2016-07-20 16:23:0110453TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110454 HttpRequestInfo restricted_port_request;
10455 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510456 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110457 restricted_port_request.load_flags = 0;
10458
[email protected]d973e99a2012-02-17 21:02:3610459 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110460 StaticSocketDataProvider first_data;
10461 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710462 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110463
10464 MockRead data_reads[] = {
10465 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10466 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610467 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110468 };
10469 StaticSocketDataProvider second_data(
10470 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710471 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110472
bncb26024382016-06-29 02:39:4510473 SSLSocketDataProvider ssl(ASYNC, OK);
10474 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10475
danakj1fd259a02016-04-16 03:17:0910476 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110477
bnc525e175a2016-06-20 12:36:4010478 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310479 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110480 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210481 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010482 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bnccacc0992015-03-20 20:22:2210483 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210484 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210485 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610486 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010487 expiration);
[email protected]3912662a32011-10-04 00:51:1110488
bnc691fda62016-08-12 00:43:1610489 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110490 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110491
tfarina42834112016-09-22 13:38:2010492 int rv = trans.Start(&restricted_port_request, callback.callback(),
10493 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110494 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110495 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110496 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110497}
10498
bnc55ff9da2015-08-19 18:42:3510499// Ensure that we are not allowed to redirect traffic via an alternate protocol
10500// to an unrestricted (port >= 1024) when the original traffic was on a
10501// restricted port (port < 1024). Ensure that we can redirect in all other
10502// cases.
bncd16676a2016-07-20 16:23:0110503TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1110504 HttpRequestInfo unrestricted_port_request;
10505 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510506 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110507 unrestricted_port_request.load_flags = 0;
10508
[email protected]d973e99a2012-02-17 21:02:3610509 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110510 StaticSocketDataProvider first_data;
10511 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710512 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110513
10514 MockRead data_reads[] = {
10515 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10516 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610517 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110518 };
10519 StaticSocketDataProvider second_data(
10520 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710521 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510522 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610523 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510524 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110525
danakj1fd259a02016-04-16 03:17:0910526 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110527
bnc525e175a2016-06-20 12:36:4010528 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310529 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110530 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210531 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010532 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bnccacc0992015-03-20 20:22:2210533 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210534 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210535 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610536 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010537 expiration);
[email protected]3912662a32011-10-04 00:51:1110538
bnc691fda62016-08-12 00:43:1610539 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110540 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110541
bnc691fda62016-08-12 00:43:1610542 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010543 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110545 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110546 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110547}
10548
bnc55ff9da2015-08-19 18:42:3510549// Ensure that we are not allowed to redirect traffic via an alternate protocol
10550// to an unrestricted (port >= 1024) when the original traffic was on a
10551// restricted port (port < 1024). Ensure that we can redirect in all other
10552// cases.
bncd16676a2016-07-20 16:23:0110553TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1110554 HttpRequestInfo unrestricted_port_request;
10555 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510556 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110557 unrestricted_port_request.load_flags = 0;
10558
[email protected]d973e99a2012-02-17 21:02:3610559 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110560 StaticSocketDataProvider first_data;
10561 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710562 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110563
10564 MockRead data_reads[] = {
10565 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10566 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610567 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110568 };
10569 StaticSocketDataProvider second_data(
10570 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710571 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110572
bncb26024382016-06-29 02:39:4510573 SSLSocketDataProvider ssl(ASYNC, OK);
10574 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10575
danakj1fd259a02016-04-16 03:17:0910576 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110577
bnc525e175a2016-06-20 12:36:4010578 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310579 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210580 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:2210581 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010582 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bnccacc0992015-03-20 20:22:2210583 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210584 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210585 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610586 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010587 expiration);
[email protected]3912662a32011-10-04 00:51:1110588
bnc691fda62016-08-12 00:43:1610589 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110590 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110591
bnc691fda62016-08-12 00:43:1610592 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010593 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110594 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110595 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0110596 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110597}
10598
bnc55ff9da2015-08-19 18:42:3510599// Ensure that we are not allowed to redirect traffic via an alternate protocol
10600// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10601// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0110602TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0210603 HttpRequestInfo request;
10604 request.method = "GET";
bncce36dca22015-04-21 22:11:2310605 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210606 request.load_flags = 0;
10607
10608 // The alternate protocol request will error out before we attempt to connect,
10609 // so only the standard HTTP request will try to connect.
10610 MockRead data_reads[] = {
10611 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10612 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610613 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210614 };
10615 StaticSocketDataProvider data(
10616 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710617 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210618
danakj1fd259a02016-04-16 03:17:0910619 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210620
bnc525e175a2016-06-20 12:36:4010621 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210622 session->http_server_properties();
10623 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:2210624 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010625 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bnccacc0992015-03-20 20:22:2210626 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210627 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210628 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610629 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210630
bnc691fda62016-08-12 00:43:1610631 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0210632 TestCompletionCallback callback;
10633
tfarina42834112016-09-22 13:38:2010634 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0210636 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0110637 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210638
bnc691fda62016-08-12 00:43:1610639 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210640 ASSERT_TRUE(response);
10641 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210642 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10643
10644 std::string response_data;
bnc691fda62016-08-12 00:43:1610645 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210646 EXPECT_EQ("hello world", response_data);
10647}
10648
bncd16676a2016-07-20 16:23:0110649TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5410650 HttpRequestInfo request;
10651 request.method = "GET";
bncb26024382016-06-29 02:39:4510652 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410653 request.load_flags = 0;
10654
10655 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210656 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310657 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210658 MockRead("\r\n"),
10659 MockRead("hello world"),
10660 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10661 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410662
10663 StaticSocketDataProvider first_transaction(
10664 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710665 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4510666 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610667 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510668 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5410669
bncb26024382016-06-29 02:39:4510670 SSLSocketDataProvider ssl_http2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610671 ssl_http2.next_proto = kProtoHTTP2;
bncb26024382016-06-29 02:39:4510672 ssl_http2.cert =
10673 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10674 ASSERT_TRUE(ssl_http2.cert.get());
10675 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http2);
[email protected]2ff8b312010-04-26 22:20:5410676
bncdf80d44fd2016-07-15 20:27:4110677 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4510678 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110679 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410680
bnc42331402016-07-25 13:36:1510681 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110682 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410683 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110684 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410685 };
10686
rch8e6c6c42015-05-01 14:05:1310687 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10688 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710689 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410690
[email protected]d973e99a2012-02-17 21:02:3610691 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510692 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10693 NULL, 0, NULL, 0);
10694 hanging_non_alternate_protocol_socket.set_connect_data(
10695 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710696 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510697 &hanging_non_alternate_protocol_socket);
10698
[email protected]49639fa2011-12-20 23:22:4110699 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410700
danakj1fd259a02016-04-16 03:17:0910701 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610702 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010703 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410704
tfarina42834112016-09-22 13:38:2010705 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10707 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410708
10709 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210710 ASSERT_TRUE(response);
10711 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410712 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10713
10714 std::string response_data;
robpercival214763f2016-07-01 23:27:0110715 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410716 EXPECT_EQ("hello world", response_data);
10717
[email protected]90499482013-06-01 00:39:5010718 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410719
tfarina42834112016-09-22 13:38:2010720 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110721 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10722 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410723
10724 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210725 ASSERT_TRUE(response);
10726 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210727 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310728 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210729 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410730
robpercival214763f2016-07-01 23:27:0110731 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410732 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410733}
10734
bncd16676a2016-07-20 16:23:0110735TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5510736 HttpRequestInfo request;
10737 request.method = "GET";
bncb26024382016-06-29 02:39:4510738 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510739 request.load_flags = 0;
10740
bncb26024382016-06-29 02:39:4510741 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5510742 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210743 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310744 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210745 MockRead("\r\n"),
10746 MockRead("hello world"),
10747 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10748 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510749 };
10750
bncb26024382016-06-29 02:39:4510751 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
10752 0);
10753 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5510754
bncb26024382016-06-29 02:39:4510755 SSLSocketDataProvider ssl_http11(ASYNC, OK);
10756 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
10757
10758 // Second transaction starts an alternative and a non-alternative Job.
10759 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3610760 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810761 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10762 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1810763 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10764
10765 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10766 hanging_socket2.set_connect_data(never_finishing_connect);
10767 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510768
bncb26024382016-06-29 02:39:4510769 // Third transaction starts an alternative and a non-alternative job.
10770 // The non-alternative job hangs, but the alternative one succeeds.
10771 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4110772 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4510773 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110774 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4510775 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5510776 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110777 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5510778 };
bnc42331402016-07-25 13:36:1510779 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110780 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1510781 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4110782 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510783 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110784 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
10785 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1310786 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510787 };
10788
rch8e6c6c42015-05-01 14:05:1310789 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10790 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710791 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510792
bncb26024382016-06-29 02:39:4510793 SSLSocketDataProvider ssl_http2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610794 ssl_http2.next_proto = kProtoHTTP2;
bncb26024382016-06-29 02:39:4510795 ssl_http2.cert =
10796 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10797 ASSERT_TRUE(ssl_http2.cert);
10798 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http2);
10799
mmenkecc2298e2015-12-07 18:20:1810800 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10801 hanging_socket3.set_connect_data(never_finishing_connect);
10802 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510803
danakj1fd259a02016-04-16 03:17:0910804 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110805 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010806 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510807
tfarina42834112016-09-22 13:38:2010808 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110809 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10810 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5510811
10812 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5210813 ASSERT_TRUE(response);
10814 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510815 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10816
10817 std::string response_data;
robpercival214763f2016-07-01 23:27:0110818 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5510819 EXPECT_EQ("hello world", response_data);
10820
[email protected]49639fa2011-12-20 23:22:4110821 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5010822 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2010823 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110824 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5510825
[email protected]49639fa2011-12-20 23:22:4110826 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5010827 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2010828 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110829 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5510830
robpercival214763f2016-07-01 23:27:0110831 EXPECT_THAT(callback2.WaitForResult(), IsOk());
10832 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5510833
10834 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5210835 ASSERT_TRUE(response);
10836 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210837 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5510838 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210839 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0110840 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5510841 EXPECT_EQ("hello!", response_data);
10842
10843 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5210844 ASSERT_TRUE(response);
10845 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210846 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5510847 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210848 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0110849 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5510850 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5510851}
10852
bncd16676a2016-07-20 16:23:0110853TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5510854 HttpRequestInfo request;
10855 request.method = "GET";
bncb26024382016-06-29 02:39:4510856 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510857 request.load_flags = 0;
10858
10859 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210860 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310861 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210862 MockRead("\r\n"),
10863 MockRead("hello world"),
10864 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10865 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510866 };
10867
10868 StaticSocketDataProvider first_transaction(
10869 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710870 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510871
[email protected]8ddf8322012-02-23 18:08:0610872 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710873 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510874
[email protected]d973e99a2012-02-17 21:02:3610875 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510876 StaticSocketDataProvider hanging_alternate_protocol_socket(
10877 NULL, 0, NULL, 0);
10878 hanging_alternate_protocol_socket.set_connect_data(
10879 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710880 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510881 &hanging_alternate_protocol_socket);
10882
bncb26024382016-06-29 02:39:4510883 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1810884 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
10885 NULL, 0);
10886 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4510887 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510888
[email protected]49639fa2011-12-20 23:22:4110889 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5510890
danakj1fd259a02016-04-16 03:17:0910891 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610892 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510894
tfarina42834112016-09-22 13:38:2010895 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10897 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5510898
10899 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210900 ASSERT_TRUE(response);
10901 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510902 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10903
10904 std::string response_data;
robpercival214763f2016-07-01 23:27:0110905 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5510906 EXPECT_EQ("hello world", response_data);
10907
[email protected]90499482013-06-01 00:39:5010908 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510909
tfarina42834112016-09-22 13:38:2010910 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110911 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10912 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5510913
10914 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210915 ASSERT_TRUE(response);
10916 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510917 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10918 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210919 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5510920
robpercival214763f2016-07-01 23:27:0110921 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5510922 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5510923}
10924
[email protected]631f1322010-04-30 17:59:1110925class CapturingProxyResolver : public ProxyResolver {
10926 public:
sammce90c9212015-05-27 23:43:3510927 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2010928 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1110929
dchengb03027d2014-10-21 12:00:2010930 int GetProxyForURL(const GURL& url,
10931 ProxyInfo* results,
10932 const CompletionCallback& callback,
eroman9c8f4242016-02-29 21:16:5410933 RequestHandle* request,
tfarina42834112016-09-22 13:38:2010934 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4010935 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
10936 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4210937 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1110938 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4210939 return OK;
[email protected]631f1322010-04-30 17:59:1110940 }
10941
eroman9c8f4242016-02-29 21:16:5410942 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
10943
10944 LoadState GetLoadState(RequestHandle request) const override {
10945 NOTREACHED();
10946 return LOAD_STATE_IDLE;
10947 }
10948
[email protected]24476402010-07-20 20:55:1710949 const std::vector<GURL>& resolved() const { return resolved_; }
10950
10951 private:
[email protected]631f1322010-04-30 17:59:1110952 std::vector<GURL> resolved_;
10953
10954 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
10955};
10956
sammce64b2362015-04-29 03:50:2310957class CapturingProxyResolverFactory : public ProxyResolverFactory {
10958 public:
10959 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
10960 : ProxyResolverFactory(false), resolver_(resolver) {}
10961
10962 int CreateProxyResolver(
10963 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0910964 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2310965 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0910966 std::unique_ptr<Request>* request) override {
sammce64b2362015-04-29 03:50:2310967 resolver->reset(new ForwardingProxyResolver(resolver_));
10968 return OK;
10969 }
10970
10971 private:
10972 ProxyResolver* resolver_;
10973};
10974
bnc2e884782016-08-11 19:45:1910975// Test that proxy is resolved using the origin url,
10976// regardless of the alternative server.
10977TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
10978 // Configure proxy to bypass www.example.org, which is the origin URL.
10979 ProxyConfig proxy_config;
10980 proxy_config.proxy_rules().ParseFromString("myproxy:70");
10981 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
10982 auto proxy_config_service =
10983 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config);
10984
10985 CapturingProxyResolver capturing_proxy_resolver;
10986 auto proxy_resolver_factory = base::MakeUnique<CapturingProxyResolverFactory>(
10987 &capturing_proxy_resolver);
10988
10989 TestNetLog net_log;
10990
10991 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
10992 std::move(proxy_config_service), std::move(proxy_resolver_factory),
10993 &net_log);
10994
10995 session_deps_.net_log = &net_log;
10996
10997 // Configure alternative service with a hostname that is not bypassed by the
10998 // proxy.
10999 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11000 HttpServerProperties* http_server_properties =
11001 session->http_server_properties();
11002 url::SchemeHostPort server("https", "www.example.org", 443);
11003 HostPortPair alternative("www.example.com", 443);
11004 AlternativeService alternative_service(
11005 AlternateProtocolFromNextProto(kProtoHTTP2), alternative);
11006 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11007 http_server_properties->SetAlternativeService(server, alternative_service,
11008 expiration);
11009
11010 // Non-alternative job should hang.
11011 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11012 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11013 nullptr, 0);
11014 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11015 session_deps_.socket_factory->AddSocketDataProvider(
11016 &hanging_alternate_protocol_socket);
11017
11018 SSLSocketDataProvider ssl_http2(ASYNC, OK);
11019 ssl_http2.next_proto = kProtoHTTP2;
11020 ssl_http2.cert =
11021 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
11022 ASSERT_TRUE(ssl_http2.cert);
11023 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http2);
11024
11025 HttpRequestInfo request;
11026 request.method = "GET";
11027 request.url = GURL("https://www.example.org/");
11028 request.load_flags = 0;
11029
11030 SpdySerializedFrame req(
11031 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11032
11033 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11034
11035 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11036 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11037 MockRead spdy_reads[] = {
11038 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11039 };
11040
11041 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11042 arraysize(spdy_writes));
11043 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11044
11045 TestCompletionCallback callback;
11046
11047 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11048
tfarina42834112016-09-22 13:38:2011049 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911050 EXPECT_THAT(callback.GetResult(rv), IsOk());
11051
11052 const HttpResponseInfo* response = trans.GetResponseInfo();
11053 ASSERT_TRUE(response);
11054 ASSERT_TRUE(response->headers);
11055 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11056 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211057 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911058
11059 std::string response_data;
11060 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11061 EXPECT_EQ("hello!", response_data);
11062
11063 // Origin host bypasses proxy, no resolution should have happened.
11064 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11065}
11066
bncd16676a2016-07-20 16:23:0111067TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111068 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211069 proxy_config.set_auto_detect(true);
11070 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111071
sammc5dd160c2015-04-02 02:43:1311072 CapturingProxyResolver capturing_proxy_resolver;
ricea2deef682016-09-09 08:04:0711073 session_deps_.proxy_service.reset(
11074 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
11075 base::MakeUnique<CapturingProxyResolverFactory>(
11076 &capturing_proxy_resolver),
11077 NULL));
vishal.b62985ca92015-04-17 08:45:5111078 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711079 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111080
11081 HttpRequestInfo request;
11082 request.method = "GET";
bncb26024382016-06-29 02:39:4511083 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111084 request.load_flags = 0;
11085
11086 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211087 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311088 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211089 MockRead("\r\n"),
11090 MockRead("hello world"),
11091 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11092 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111093 };
11094
11095 StaticSocketDataProvider first_transaction(
11096 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711097 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511098 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611099 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511100 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111101
bncb26024382016-06-29 02:39:4511102 SSLSocketDataProvider ssl_http2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611103 ssl_http2.next_proto = kProtoHTTP2;
bncb26024382016-06-29 02:39:4511104 ssl_http2.cert =
11105 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
11106 ASSERT_TRUE(ssl_http2.cert);
11107 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http2);
[email protected]631f1322010-04-30 17:59:1111108
bncdf80d44fd2016-07-15 20:27:4111109 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511110 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111111 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311112 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511113 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11114 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311115 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111116 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111117 };
11118
[email protected]d911f1b2010-05-05 22:39:4211119 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11120
bnc42331402016-07-25 13:36:1511121 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111122 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111123 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111124 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11125 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111126 };
11127
rch8e6c6c42015-05-01 14:05:1311128 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11129 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711130 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111131
[email protected]d973e99a2012-02-17 21:02:3611132 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511133 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11134 NULL, 0, NULL, 0);
11135 hanging_non_alternate_protocol_socket.set_connect_data(
11136 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711137 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511138 &hanging_non_alternate_protocol_socket);
11139
[email protected]49639fa2011-12-20 23:22:4111140 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111141
danakj1fd259a02016-04-16 03:17:0911142 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611143 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011144 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111145
tfarina42834112016-09-22 13:38:2011146 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111147 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11148 EXPECT_THAT(callback.WaitForResult(), IsOk());
11149
11150 const HttpResponseInfo* response = trans->GetResponseInfo();
11151 ASSERT_TRUE(response);
11152 ASSERT_TRUE(response->headers);
11153 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11154 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211155 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111156
11157 std::string response_data;
11158 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11159 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111160
[email protected]90499482013-06-01 00:39:5011161 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111162
tfarina42834112016-09-22 13:38:2011163 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111164 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11165 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111166
mmenkea2dcd3bf2016-08-16 21:49:4111167 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211168 ASSERT_TRUE(response);
11169 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211170 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311171 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211172 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111173
robpercival214763f2016-07-01 23:27:0111174 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111175 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511176 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11177 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311178 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311179 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311180 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111181
[email protected]029c83b62013-01-24 05:28:2011182 LoadTimingInfo load_timing_info;
11183 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11184 TestLoadTimingNotReusedWithPac(load_timing_info,
11185 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111186}
[email protected]631f1322010-04-30 17:59:1111187
bncd16676a2016-07-20 16:23:0111188TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811189 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411190 HttpRequestInfo request;
11191 request.method = "GET";
bncb26024382016-06-29 02:39:4511192 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411193 request.load_flags = 0;
11194
11195 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211196 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311197 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211198 MockRead("\r\n"),
11199 MockRead("hello world"),
11200 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411201 };
11202
11203 StaticSocketDataProvider first_transaction(
11204 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711205 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511206 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611207 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511208 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411209
bncb26024382016-06-29 02:39:4511210 SSLSocketDataProvider ssl_http2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611211 ssl_http2.next_proto = kProtoHTTP2;
bncb26024382016-06-29 02:39:4511212 ssl_http2.cert =
11213 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
11214 ASSERT_TRUE(ssl_http2.cert);
11215 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http2);
[email protected]2ff8b312010-04-26 22:20:5411216
bncdf80d44fd2016-07-15 20:27:4111217 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511218 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111219 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411220
bnc42331402016-07-25 13:36:1511221 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111222 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411223 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111224 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411225 };
11226
rch8e6c6c42015-05-01 14:05:1311227 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11228 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711229 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411230
[email protected]83039bb2011-12-09 18:43:5511231 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411232
danakj1fd259a02016-04-16 03:17:0911233 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411234
bnc691fda62016-08-12 00:43:1611235 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011236 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411237
tfarina42834112016-09-22 13:38:2011238 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111239 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11240 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411241
11242 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211243 ASSERT_TRUE(response);
11244 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411245 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11246
11247 std::string response_data;
robpercival214763f2016-07-01 23:27:0111248 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411249 EXPECT_EQ("hello world", response_data);
11250
11251 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511252 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011253 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311254 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711255 base::WeakPtr<SpdySession> spdy_session =
tfarina42834112016-09-22 13:38:2011256 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811257
[email protected]90499482013-06-01 00:39:5011258 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411259
tfarina42834112016-09-22 13:38:2011260 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111261 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11262 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411263
11264 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211265 ASSERT_TRUE(response);
11266 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211267 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311268 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211269 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411270
robpercival214763f2016-07-01 23:27:0111271 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411272 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211273}
11274
[email protected]044de0642010-06-17 10:42:1511275// GenerateAuthToken is a mighty big test.
11276// It tests all permutation of GenerateAuthToken behavior:
11277// - Synchronous and Asynchronous completion.
11278// - OK or error on completion.
11279// - Direct connection, non-authenticating proxy, and authenticating proxy.
11280// - HTTP or HTTPS backend (to include proxy tunneling).
11281// - Non-authenticating and authenticating backend.
11282//
[email protected]fe3b7dc2012-02-03 19:52:0911283// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511284// problems generating an auth token for an authenticating proxy, we don't
11285// need to test all permutations of the backend server).
11286//
11287// The test proceeds by going over each of the configuration cases, and
11288// potentially running up to three rounds in each of the tests. The TestConfig
11289// specifies both the configuration for the test as well as the expectations
11290// for the results.
bncd16676a2016-07-20 16:23:0111291TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011292 static const char kServer[] = "http://www.example.com";
11293 static const char kSecureServer[] = "https://www.example.com";
11294 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511295 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
11296
11297 enum AuthTiming {
11298 AUTH_NONE,
11299 AUTH_SYNC,
11300 AUTH_ASYNC,
11301 };
11302
11303 const MockWrite kGet(
11304 "GET / HTTP/1.1\r\n"
11305 "Host: www.example.com\r\n"
11306 "Connection: keep-alive\r\n\r\n");
11307 const MockWrite kGetProxy(
11308 "GET http://www.example.com/ HTTP/1.1\r\n"
11309 "Host: www.example.com\r\n"
11310 "Proxy-Connection: keep-alive\r\n\r\n");
11311 const MockWrite kGetAuth(
11312 "GET / HTTP/1.1\r\n"
11313 "Host: www.example.com\r\n"
11314 "Connection: keep-alive\r\n"
11315 "Authorization: auth_token\r\n\r\n");
11316 const MockWrite kGetProxyAuth(
11317 "GET http://www.example.com/ HTTP/1.1\r\n"
11318 "Host: www.example.com\r\n"
11319 "Proxy-Connection: keep-alive\r\n"
11320 "Proxy-Authorization: auth_token\r\n\r\n");
11321 const MockWrite kGetAuthThroughProxy(
11322 "GET http://www.example.com/ HTTP/1.1\r\n"
11323 "Host: www.example.com\r\n"
11324 "Proxy-Connection: keep-alive\r\n"
11325 "Authorization: auth_token\r\n\r\n");
11326 const MockWrite kGetAuthWithProxyAuth(
11327 "GET http://www.example.com/ HTTP/1.1\r\n"
11328 "Host: www.example.com\r\n"
11329 "Proxy-Connection: keep-alive\r\n"
11330 "Proxy-Authorization: auth_token\r\n"
11331 "Authorization: auth_token\r\n\r\n");
11332 const MockWrite kConnect(
11333 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711334 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511335 "Proxy-Connection: keep-alive\r\n\r\n");
11336 const MockWrite kConnectProxyAuth(
11337 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711338 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511339 "Proxy-Connection: keep-alive\r\n"
11340 "Proxy-Authorization: auth_token\r\n\r\n");
11341
11342 const MockRead kSuccess(
11343 "HTTP/1.1 200 OK\r\n"
11344 "Content-Type: text/html; charset=iso-8859-1\r\n"
11345 "Content-Length: 3\r\n\r\n"
11346 "Yes");
11347 const MockRead kFailure(
11348 "Should not be called.");
11349 const MockRead kServerChallenge(
11350 "HTTP/1.1 401 Unauthorized\r\n"
11351 "WWW-Authenticate: Mock realm=server\r\n"
11352 "Content-Type: text/html; charset=iso-8859-1\r\n"
11353 "Content-Length: 14\r\n\r\n"
11354 "Unauthorized\r\n");
11355 const MockRead kProxyChallenge(
11356 "HTTP/1.1 407 Unauthorized\r\n"
11357 "Proxy-Authenticate: Mock realm=proxy\r\n"
11358 "Proxy-Connection: close\r\n"
11359 "Content-Type: text/html; charset=iso-8859-1\r\n"
11360 "Content-Length: 14\r\n\r\n"
11361 "Unauthorized\r\n");
11362 const MockRead kProxyConnected(
11363 "HTTP/1.1 200 Connection Established\r\n\r\n");
11364
11365 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11366 // no constructors, but the C++ compiler on Windows warns about
11367 // unspecified data in compound literals. So, moved to using constructors,
11368 // and TestRound's created with the default constructor should not be used.
11369 struct TestRound {
11370 TestRound()
11371 : expected_rv(ERR_UNEXPECTED),
11372 extra_write(NULL),
11373 extra_read(NULL) {
11374 }
11375 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11376 int expected_rv_arg)
11377 : write(write_arg),
11378 read(read_arg),
11379 expected_rv(expected_rv_arg),
11380 extra_write(NULL),
11381 extra_read(NULL) {
11382 }
11383 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11384 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111385 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511386 : write(write_arg),
11387 read(read_arg),
11388 expected_rv(expected_rv_arg),
11389 extra_write(extra_write_arg),
11390 extra_read(extra_read_arg) {
11391 }
11392 MockWrite write;
11393 MockRead read;
11394 int expected_rv;
11395 const MockWrite* extra_write;
11396 const MockRead* extra_read;
11397 };
11398
11399 static const int kNoSSL = 500;
11400
11401 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5111402 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511403 AuthTiming proxy_auth_timing;
11404 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5111405 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511406 AuthTiming server_auth_timing;
11407 int server_auth_rv;
11408 int num_auth_rounds;
11409 int first_ssl_round;
11410 TestRound rounds[3];
11411 } test_configs[] = {
11412 // Non-authenticating HTTP server with a direct connection.
11413 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11414 { TestRound(kGet, kSuccess, OK)}},
11415 // Authenticating HTTP server with a direct connection.
11416 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11417 { TestRound(kGet, kServerChallenge, OK),
11418 TestRound(kGetAuth, kSuccess, OK)}},
11419 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11420 { TestRound(kGet, kServerChallenge, OK),
11421 TestRound(kGetAuth, kFailure, kAuthErr)}},
11422 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11423 { TestRound(kGet, kServerChallenge, OK),
11424 TestRound(kGetAuth, kSuccess, OK)}},
11425 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11426 { TestRound(kGet, kServerChallenge, OK),
11427 TestRound(kGetAuth, kFailure, kAuthErr)}},
11428 // Non-authenticating HTTP server through a non-authenticating proxy.
11429 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11430 { TestRound(kGetProxy, kSuccess, OK)}},
11431 // Authenticating HTTP server through a non-authenticating proxy.
11432 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11433 { TestRound(kGetProxy, kServerChallenge, OK),
11434 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11435 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11436 { TestRound(kGetProxy, kServerChallenge, OK),
11437 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11438 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11439 { TestRound(kGetProxy, kServerChallenge, OK),
11440 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11441 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11442 { TestRound(kGetProxy, kServerChallenge, OK),
11443 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11444 // Non-authenticating HTTP server through an authenticating proxy.
11445 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11446 { TestRound(kGetProxy, kProxyChallenge, OK),
11447 TestRound(kGetProxyAuth, kSuccess, OK)}},
11448 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11449 { TestRound(kGetProxy, kProxyChallenge, OK),
11450 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11451 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11452 { TestRound(kGetProxy, kProxyChallenge, OK),
11453 TestRound(kGetProxyAuth, kSuccess, OK)}},
11454 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11455 { TestRound(kGetProxy, kProxyChallenge, OK),
11456 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11457 // Authenticating HTTP server through an authenticating proxy.
11458 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11459 { TestRound(kGetProxy, kProxyChallenge, OK),
11460 TestRound(kGetProxyAuth, kServerChallenge, OK),
11461 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11462 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11463 { TestRound(kGetProxy, kProxyChallenge, OK),
11464 TestRound(kGetProxyAuth, kServerChallenge, OK),
11465 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11466 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11467 { TestRound(kGetProxy, kProxyChallenge, OK),
11468 TestRound(kGetProxyAuth, kServerChallenge, OK),
11469 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11470 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11471 { TestRound(kGetProxy, kProxyChallenge, OK),
11472 TestRound(kGetProxyAuth, kServerChallenge, OK),
11473 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11474 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11475 { TestRound(kGetProxy, kProxyChallenge, OK),
11476 TestRound(kGetProxyAuth, kServerChallenge, OK),
11477 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11478 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11479 { TestRound(kGetProxy, kProxyChallenge, OK),
11480 TestRound(kGetProxyAuth, kServerChallenge, OK),
11481 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11482 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11483 { TestRound(kGetProxy, kProxyChallenge, OK),
11484 TestRound(kGetProxyAuth, kServerChallenge, OK),
11485 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11486 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11487 { TestRound(kGetProxy, kProxyChallenge, OK),
11488 TestRound(kGetProxyAuth, kServerChallenge, OK),
11489 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11490 // Non-authenticating HTTPS server with a direct connection.
11491 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11492 { TestRound(kGet, kSuccess, OK)}},
11493 // Authenticating HTTPS server with a direct connection.
11494 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11495 { TestRound(kGet, kServerChallenge, OK),
11496 TestRound(kGetAuth, kSuccess, OK)}},
11497 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11498 { TestRound(kGet, kServerChallenge, OK),
11499 TestRound(kGetAuth, kFailure, kAuthErr)}},
11500 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11501 { TestRound(kGet, kServerChallenge, OK),
11502 TestRound(kGetAuth, kSuccess, OK)}},
11503 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11504 { TestRound(kGet, kServerChallenge, OK),
11505 TestRound(kGetAuth, kFailure, kAuthErr)}},
11506 // Non-authenticating HTTPS server with a non-authenticating proxy.
11507 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11508 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11509 // Authenticating HTTPS server through a non-authenticating proxy.
11510 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11511 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11512 TestRound(kGetAuth, kSuccess, OK)}},
11513 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11514 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11515 TestRound(kGetAuth, kFailure, kAuthErr)}},
11516 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11517 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11518 TestRound(kGetAuth, kSuccess, OK)}},
11519 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11520 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11521 TestRound(kGetAuth, kFailure, kAuthErr)}},
11522 // Non-Authenticating HTTPS server through an authenticating proxy.
11523 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11524 { TestRound(kConnect, kProxyChallenge, OK),
11525 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11526 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11527 { TestRound(kConnect, kProxyChallenge, OK),
11528 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11529 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11530 { TestRound(kConnect, kProxyChallenge, OK),
11531 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11532 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11533 { TestRound(kConnect, kProxyChallenge, OK),
11534 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11535 // Authenticating HTTPS server through an authenticating proxy.
11536 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11537 { TestRound(kConnect, kProxyChallenge, OK),
11538 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11539 &kGet, &kServerChallenge),
11540 TestRound(kGetAuth, kSuccess, OK)}},
11541 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11542 { TestRound(kConnect, kProxyChallenge, OK),
11543 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11544 &kGet, &kServerChallenge),
11545 TestRound(kGetAuth, kFailure, kAuthErr)}},
11546 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11547 { TestRound(kConnect, kProxyChallenge, OK),
11548 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11549 &kGet, &kServerChallenge),
11550 TestRound(kGetAuth, kSuccess, OK)}},
11551 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11552 { TestRound(kConnect, kProxyChallenge, OK),
11553 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11554 &kGet, &kServerChallenge),
11555 TestRound(kGetAuth, kFailure, kAuthErr)}},
11556 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11557 { TestRound(kConnect, kProxyChallenge, OK),
11558 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11559 &kGet, &kServerChallenge),
11560 TestRound(kGetAuth, kSuccess, OK)}},
11561 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11562 { TestRound(kConnect, kProxyChallenge, OK),
11563 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11564 &kGet, &kServerChallenge),
11565 TestRound(kGetAuth, kFailure, kAuthErr)}},
11566 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11567 { TestRound(kConnect, kProxyChallenge, OK),
11568 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11569 &kGet, &kServerChallenge),
11570 TestRound(kGetAuth, kSuccess, OK)}},
11571 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11572 { TestRound(kConnect, kProxyChallenge, OK),
11573 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11574 &kGet, &kServerChallenge),
11575 TestRound(kGetAuth, kFailure, kAuthErr)}},
11576 };
11577
viettrungluue4a8b882014-10-16 06:17:3811578 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0811579 HttpAuthHandlerMock::Factory* auth_factory(
11580 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711581 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4911582 SSLInfo empty_ssl_info;
[email protected]044de0642010-06-17 10:42:1511583 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2611584
11585 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1511586 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0811587 for (int n = 0; n < 2; n++) {
11588 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11589 std::string auth_challenge = "Mock realm=proxy";
11590 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2411591 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11592 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0811593 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2011594 empty_ssl_info, origin,
11595 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0811596 auth_handler->SetGenerateExpectation(
11597 test_config.proxy_auth_timing == AUTH_ASYNC,
11598 test_config.proxy_auth_rv);
11599 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11600 }
[email protected]044de0642010-06-17 10:42:1511601 }
11602 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0011603 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1511604 std::string auth_challenge = "Mock realm=server";
11605 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2411606 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11607 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1511608 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2011609 empty_ssl_info, origin,
11610 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1511611 auth_handler->SetGenerateExpectation(
11612 test_config.server_auth_timing == AUTH_ASYNC,
11613 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0811614 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1511615 }
11616 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0311617 session_deps_.proxy_service =
11618 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1511619 } else {
rdsmith82957ad2015-09-16 19:42:0311620 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1511621 }
11622
11623 HttpRequestInfo request;
11624 request.method = "GET";
11625 request.url = GURL(test_config.server_url);
11626 request.load_flags = 0;
11627
danakj1fd259a02016-04-16 03:17:0911628 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1511629
rchcb68dc62015-05-21 04:45:3611630 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
11631
11632 std::vector<std::vector<MockRead>> mock_reads(1);
11633 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1511634 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11635 const TestRound& read_write_round = test_config.rounds[round];
11636
11637 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3611638 mock_reads.back().push_back(read_write_round.read);
11639 mock_writes.back().push_back(read_write_round.write);
11640
11641 // kProxyChallenge uses Proxy-Connection: close which means that the
11642 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5411643 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3611644 mock_reads.push_back(std::vector<MockRead>());
11645 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1511646 }
11647
rchcb68dc62015-05-21 04:45:3611648 if (read_write_round.extra_read) {
11649 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1511650 }
rchcb68dc62015-05-21 04:45:3611651 if (read_write_round.extra_write) {
11652 mock_writes.back().push_back(*read_write_round.extra_write);
11653 }
[email protected]044de0642010-06-17 10:42:1511654
11655 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1511656 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0711657 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1511658 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3611659 }
[email protected]044de0642010-06-17 10:42:1511660
danakj1fd259a02016-04-16 03:17:0911661 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3611662 for (size_t i = 0; i < mock_reads.size(); ++i) {
danakj1fd259a02016-04-16 03:17:0911663 data_providers.push_back(base::WrapUnique(new StaticSocketDataProvider(
davidben5f8b6bc2015-11-25 03:19:5411664 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
olli.raula525048c2015-12-10 07:38:3211665 mock_writes[i].size())));
rchcb68dc62015-05-21 04:45:3611666 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3211667 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3611668 }
11669
mmenkecc2298e2015-12-07 18:20:1811670 // Transaction must be created after DataProviders, so it's destroyed before
11671 // they are as well.
11672 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11673
rchcb68dc62015-05-21 04:45:3611674 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11675 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1511676 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4111677 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1511678 int rv;
11679 if (round == 0) {
tfarina42834112016-09-22 13:38:2011680 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1511681 } else {
[email protected]49639fa2011-12-20 23:22:4111682 rv = trans.RestartWithAuth(
11683 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1511684 }
11685 if (rv == ERR_IO_PENDING)
11686 rv = callback.WaitForResult();
11687
11688 // Compare results with expected data.
11689 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5011690 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5511691 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1511692 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
11693 continue;
11694 }
11695 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5211696 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1511697 } else {
wezca1070932016-05-26 20:30:5211698 EXPECT_FALSE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1511699 }
11700 }
[email protected]e5ae96a2010-04-14 20:12:4511701 }
11702}
11703
bncd16676a2016-07-20 16:23:0111704TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1411705 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1411706 HttpAuthHandlerMock::Factory* auth_factory(
11707 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711708 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0311709 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0711710 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
11711 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1411712
11713 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11714 auth_handler->set_connection_based(true);
11715 std::string auth_challenge = "Mock realm=server";
11716 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2411717 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11718 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4911719 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1411720 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2011721 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0811722 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1411723
[email protected]c871bce92010-07-15 21:51:1411724 int rv = OK;
11725 const HttpResponseInfo* response = NULL;
11726 HttpRequestInfo request;
11727 request.method = "GET";
11728 request.url = origin;
11729 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2711730
danakj1fd259a02016-04-16 03:17:0911731 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1011732
11733 // Use a TCP Socket Pool with only one connection per group. This is used
11734 // to validate that the TCP socket is not released to the pool between
11735 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4211736 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2811737 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1011738 50, // Max sockets for pool
11739 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2111740 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
11741 NULL, session_deps_.net_log);
danakj1fd259a02016-04-16 03:17:0911742 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:4411743 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0211744 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4811745 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1011746
bnc691fda62016-08-12 00:43:1611747 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111748 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1411749
11750 const MockWrite kGet(
11751 "GET / HTTP/1.1\r\n"
11752 "Host: www.example.com\r\n"
11753 "Connection: keep-alive\r\n\r\n");
11754 const MockWrite kGetAuth(
11755 "GET / HTTP/1.1\r\n"
11756 "Host: www.example.com\r\n"
11757 "Connection: keep-alive\r\n"
11758 "Authorization: auth_token\r\n\r\n");
11759
11760 const MockRead kServerChallenge(
11761 "HTTP/1.1 401 Unauthorized\r\n"
11762 "WWW-Authenticate: Mock realm=server\r\n"
11763 "Content-Type: text/html; charset=iso-8859-1\r\n"
11764 "Content-Length: 14\r\n\r\n"
11765 "Unauthorized\r\n");
11766 const MockRead kSuccess(
11767 "HTTP/1.1 200 OK\r\n"
11768 "Content-Type: text/html; charset=iso-8859-1\r\n"
11769 "Content-Length: 3\r\n\r\n"
11770 "Yes");
11771
11772 MockWrite writes[] = {
11773 // First round
11774 kGet,
11775 // Second round
11776 kGetAuth,
11777 // Third round
11778 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3011779 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1011780 kGetAuth,
11781 // Competing request
11782 kGet,
[email protected]c871bce92010-07-15 21:51:1411783 };
11784 MockRead reads[] = {
11785 // First round
11786 kServerChallenge,
11787 // Second round
11788 kServerChallenge,
11789 // Third round
[email protected]eca50e122010-09-11 14:03:3011790 kServerChallenge,
11791 // Fourth round
[email protected]c871bce92010-07-15 21:51:1411792 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1011793 // Competing response
11794 kSuccess,
[email protected]c871bce92010-07-15 21:51:1411795 };
11796 StaticSocketDataProvider data_provider(reads, arraysize(reads),
11797 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0711798 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1411799
thestig9d3bb0c2015-01-24 00:49:5111800 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1011801
11802 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1411803 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2011804 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1411805 if (rv == ERR_IO_PENDING)
11806 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111807 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611808 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211809 ASSERT_TRUE(response);
11810 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811811 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411812
[email protected]7ef4cbbb2011-02-06 11:19:1011813 // In between rounds, another request comes in for the same domain.
11814 // It should not be able to grab the TCP socket that trans has already
11815 // claimed.
bnc691fda62016-08-12 00:43:1611816 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111817 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2011818 rv = trans_compete.Start(&request, callback_compete.callback(),
11819 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1011821 // callback_compete.WaitForResult at this point would stall forever,
11822 // since the HttpNetworkTransaction does not release the request back to
11823 // the pool until after authentication completes.
11824
11825 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1411826 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1611827 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411828 if (rv == ERR_IO_PENDING)
11829 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111830 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611831 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211832 ASSERT_TRUE(response);
11833 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811834 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411835
[email protected]7ef4cbbb2011-02-06 11:19:1011836 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1411837 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1611838 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411839 if (rv == ERR_IO_PENDING)
11840 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111841 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611842 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211843 ASSERT_TRUE(response);
11844 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811845 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3011846
[email protected]7ef4cbbb2011-02-06 11:19:1011847 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3011848 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1611849 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3011850 if (rv == ERR_IO_PENDING)
11851 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111852 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611853 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211854 ASSERT_TRUE(response);
11855 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811856 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011857
11858 // Read the body since the fourth round was successful. This will also
11859 // release the socket back to the pool.
11860 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1611861 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011862 if (rv == ERR_IO_PENDING)
11863 rv = callback.WaitForResult();
11864 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1611865 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011866 EXPECT_EQ(0, rv);
11867 // There are still 0 idle sockets, since the trans_compete transaction
11868 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2811869 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011870
11871 // The competing request can now finish. Wait for the headers and then
11872 // read the body.
11873 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0111874 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611875 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011876 if (rv == ERR_IO_PENDING)
11877 rv = callback.WaitForResult();
11878 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1611879 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011880 EXPECT_EQ(0, rv);
11881
11882 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2811883 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411884}
11885
[email protected]65041fa2010-05-21 06:56:5311886// This tests the case that a request is issued via http instead of spdy after
11887// npn is negotiated.
bncd16676a2016-07-20 16:23:0111888TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5311889 HttpRequestInfo request;
11890 request.method = "GET";
bncce36dca22015-04-21 22:11:2311891 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5311892 request.load_flags = 0;
11893
11894 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2311895 MockWrite(
11896 "GET / HTTP/1.1\r\n"
11897 "Host: www.example.org\r\n"
11898 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5311899 };
11900
11901 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211902 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311903 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211904 MockRead("\r\n"),
11905 MockRead("hello world"),
11906 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5311907 };
11908
[email protected]8ddf8322012-02-23 18:08:0611909 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611910 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5311911
[email protected]bb88e1d32013-05-03 23:11:0711912 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5311913
11914 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11915 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711916 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5311917
[email protected]49639fa2011-12-20 23:22:4111918 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5311919
danakj1fd259a02016-04-16 03:17:0911920 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611921 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5311922
tfarina42834112016-09-22 13:38:2011923 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5311924
robpercival214763f2016-07-01 23:27:0111925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11926 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5311927
bnc691fda62016-08-12 00:43:1611928 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211929 ASSERT_TRUE(response);
11930 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5311931 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11932
11933 std::string response_data;
bnc691fda62016-08-12 00:43:1611934 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5311935 EXPECT_EQ("hello world", response_data);
11936
11937 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211938 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5311939}
[email protected]26ef6582010-06-24 02:30:4711940
bnc55ff9da2015-08-19 18:42:3511941// Simulate the SSL handshake completing with an NPN negotiation followed by an
11942// immediate server closing of the socket.
11943// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0111944TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4711945 HttpRequestInfo request;
11946 request.method = "GET";
bncce36dca22015-04-21 22:11:2311947 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4711948 request.load_flags = 0;
11949
[email protected]8ddf8322012-02-23 18:08:0611950 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611951 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0711952 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4711953
bncdf80d44fd2016-07-15 20:27:4111954 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4911955 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4111956 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4711957
11958 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611959 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4711960 };
11961
rch8e6c6c42015-05-01 14:05:1311962 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11963 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711964 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4711965
[email protected]49639fa2011-12-20 23:22:4111966 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4711967
danakj1fd259a02016-04-16 03:17:0911968 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611969 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4711970
tfarina42834112016-09-22 13:38:2011971 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111972 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11973 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4711974}
[email protected]65d34382010-07-01 18:12:2611975
[email protected]795cbf82013-07-22 09:37:2711976// A subclass of HttpAuthHandlerMock that records the request URL when
11977// it gets it. This is needed since the auth handler may get destroyed
11978// before we get a chance to query it.
11979class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
11980 public:
11981 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
11982
dchengb03027d2014-10-21 12:00:2011983 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2711984
11985 protected:
dchengb03027d2014-10-21 12:00:2011986 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
11987 const HttpRequestInfo* request,
11988 const CompletionCallback& callback,
11989 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2711990 *url_ = request->url;
11991 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
11992 credentials, request, callback, auth_token);
11993 }
11994
11995 private:
11996 GURL* url_;
11997};
11998
[email protected]8e6441ca2010-08-19 05:56:3811999// Test that if we cancel the transaction as the connection is completing, that
12000// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112001TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812002 // Setup everything about the connection to complete synchronously, so that
12003 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12004 // for is the callback from the HttpStreamRequest.
12005 // Then cancel the transaction.
12006 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612007 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812008 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612009 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12010 MockRead(SYNCHRONOUS, "hello world"),
12011 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812012 };
12013
[email protected]8e6441ca2010-08-19 05:56:3812014 HttpRequestInfo request;
12015 request.method = "GET";
bncce36dca22015-04-21 22:11:2312016 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812017 request.load_flags = 0;
12018
[email protected]bb88e1d32013-05-03 23:11:0712019 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912020 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612021 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112022 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2712023
[email protected]8e6441ca2010-08-19 05:56:3812024 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12025 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712026 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812027
[email protected]49639fa2011-12-20 23:22:4112028 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812029
vishal.b62985ca92015-04-17 08:45:5112030 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112031 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112032 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3812033 trans.reset(); // Cancel the transaction here.
12034
fdoray92e35a72016-06-10 15:54:5512035 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012036}
12037
[email protected]ecab6e052014-05-16 14:58:1212038// Test that if a transaction is cancelled after receiving the headers, the
12039// stream is drained properly and added back to the socket pool. The main
12040// purpose of this test is to make sure that an HttpStreamParser can be read
12041// from after the HttpNetworkTransaction and the objects it owns have been
12042// deleted.
12043// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0112044TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1212045 MockRead data_reads[] = {
12046 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12047 MockRead(ASYNC, "Content-Length: 2\r\n"),
12048 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12049 MockRead(ASYNC, "1"),
12050 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12051 // HttpNetworkTransaction has been deleted.
12052 MockRead(ASYNC, "2"),
12053 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12054 };
12055 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12056 session_deps_.socket_factory->AddSocketDataProvider(&data);
12057
danakj1fd259a02016-04-16 03:17:0912058 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212059
12060 {
12061 HttpRequestInfo request;
12062 request.method = "GET";
bncce36dca22015-04-21 22:11:2312063 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212064 request.load_flags = 0;
12065
dcheng48459ac22014-08-26 00:46:4112066 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212067 TestCompletionCallback callback;
12068
tfarina42834112016-09-22 13:38:2012069 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112070 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1212071 callback.WaitForResult();
12072
12073 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212074 ASSERT_TRUE(response);
12075 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212076 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12077
12078 // The transaction and HttpRequestInfo are deleted.
12079 }
12080
12081 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512082 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212083
12084 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112085 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212086}
12087
[email protected]76a505b2010-08-25 06:23:0012088// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0112089TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312090 session_deps_.proxy_service =
12091 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112092 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712093 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912094 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012095
[email protected]76a505b2010-08-25 06:23:0012096 HttpRequestInfo request;
12097 request.method = "GET";
bncce36dca22015-04-21 22:11:2312098 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012099
12100 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312101 MockWrite(
12102 "GET http://www.example.org/ HTTP/1.1\r\n"
12103 "Host: www.example.org\r\n"
12104 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012105 };
12106
12107 MockRead data_reads1[] = {
12108 MockRead("HTTP/1.1 200 OK\r\n"),
12109 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12110 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612111 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012112 };
12113
12114 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12115 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712116 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012117
[email protected]49639fa2011-12-20 23:22:4112118 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012119
bnc691fda62016-08-12 00:43:1612120 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912121 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612122 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912123 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12124 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012125
bnc691fda62016-08-12 00:43:1612126 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112127 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012128
12129 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112130 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0012131
bnc691fda62016-08-12 00:43:1612132 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212133 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012134
12135 EXPECT_TRUE(response->headers->IsKeepAlive());
12136 EXPECT_EQ(200, response->headers->response_code());
12137 EXPECT_EQ(100, response->headers->GetContentLength());
12138 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1512139 EXPECT_TRUE(
12140 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
ryansturm49a8cb12016-06-15 16:51:0912141 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12142 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12143 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012144 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012145
12146 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612147 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012148 TestLoadTimingNotReusedWithPac(load_timing_info,
12149 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012150}
12151
12152// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0112153TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312154 session_deps_.proxy_service =
12155 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112156 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712157 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912158 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012159
[email protected]76a505b2010-08-25 06:23:0012160 HttpRequestInfo request;
12161 request.method = "GET";
bncce36dca22015-04-21 22:11:2312162 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012163
12164 // Since we have proxy, should try to establish tunnel.
12165 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712166 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12167 "Host: www.example.org:443\r\n"
12168 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012169
rsleevidb16bb02015-11-12 23:47:1712170 MockWrite("GET / HTTP/1.1\r\n"
12171 "Host: www.example.org\r\n"
12172 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012173 };
12174
12175 MockRead data_reads1[] = {
12176 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12177
12178 MockRead("HTTP/1.1 200 OK\r\n"),
12179 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12180 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612181 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012182 };
12183
12184 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12185 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712186 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612187 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712188 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012189
[email protected]49639fa2011-12-20 23:22:4112190 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012191
bnc691fda62016-08-12 00:43:1612192 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912193 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612194 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912195 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12196 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012197
bnc691fda62016-08-12 00:43:1612198 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112199 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012200
12201 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112202 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4612203 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012204 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012205 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012206 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12207 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012208 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012209 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012210 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12211 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012212
bnc691fda62016-08-12 00:43:1612213 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212214 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012215
12216 EXPECT_TRUE(response->headers->IsKeepAlive());
12217 EXPECT_EQ(200, response->headers->response_code());
12218 EXPECT_EQ(100, response->headers->GetContentLength());
12219 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12220 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1512221 EXPECT_TRUE(
12222 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
ryansturm49a8cb12016-06-15 16:51:0912223 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12224 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12225 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012226
12227 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612228 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012229 TestLoadTimingNotReusedWithPac(load_timing_info,
12230 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012231}
12232
rsleevidb16bb02015-11-12 23:47:1712233// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12234// literal host.
bncd16676a2016-07-20 16:23:0112235TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1712236 session_deps_.proxy_service =
12237 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12238 BoundTestNetLog log;
12239 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912240 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712241
12242 HttpRequestInfo request;
12243 request.method = "GET";
12244 request.url = GURL("https://[::1]:443/");
12245
12246 // Since we have proxy, should try to establish tunnel.
12247 MockWrite data_writes1[] = {
12248 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12249 "Host: [::1]:443\r\n"
12250 "Proxy-Connection: keep-alive\r\n\r\n"),
12251
12252 MockWrite("GET / HTTP/1.1\r\n"
12253 "Host: [::1]\r\n"
12254 "Connection: keep-alive\r\n\r\n"),
12255 };
12256
12257 MockRead data_reads1[] = {
12258 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12259
12260 MockRead("HTTP/1.1 200 OK\r\n"),
12261 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12262 MockRead("Content-Length: 100\r\n\r\n"),
12263 MockRead(SYNCHRONOUS, OK),
12264 };
12265
12266 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12267 data_writes1, arraysize(data_writes1));
12268 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12269 SSLSocketDataProvider ssl(ASYNC, OK);
12270 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12271
12272 TestCompletionCallback callback1;
12273
bnc691fda62016-08-12 00:43:1612274 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1712275
bnc691fda62016-08-12 00:43:1612276 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1712278
12279 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112280 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1712281 TestNetLogEntry::List entries;
12282 log.GetEntries(&entries);
12283 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012284 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12285 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712286 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012287 entries, pos,
12288 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12289 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712290
bnc691fda62016-08-12 00:43:1612291 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212292 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712293
12294 EXPECT_TRUE(response->headers->IsKeepAlive());
12295 EXPECT_EQ(200, response->headers->response_code());
12296 EXPECT_EQ(100, response->headers->GetContentLength());
12297 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12298 EXPECT_TRUE(response->was_fetched_via_proxy);
12299 EXPECT_TRUE(
12300 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
12301
12302 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612303 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1712304 TestLoadTimingNotReusedWithPac(load_timing_info,
12305 CONNECT_TIMING_HAS_SSL_TIMES);
12306}
12307
[email protected]76a505b2010-08-25 06:23:0012308// Test a basic HTTPS GET request through a proxy, but the server hangs up
12309// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0112310TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312311 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112312 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712313 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912314 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012315
[email protected]76a505b2010-08-25 06:23:0012316 HttpRequestInfo request;
12317 request.method = "GET";
bncce36dca22015-04-21 22:11:2312318 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012319
12320 // Since we have proxy, should try to establish tunnel.
12321 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712322 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12323 "Host: www.example.org:443\r\n"
12324 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012325
rsleevidb16bb02015-11-12 23:47:1712326 MockWrite("GET / HTTP/1.1\r\n"
12327 "Host: www.example.org\r\n"
12328 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012329 };
12330
12331 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0612332 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0012333 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612334 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0012335 };
12336
12337 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12338 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712339 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612340 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712341 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012342
[email protected]49639fa2011-12-20 23:22:4112343 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012344
bnc691fda62016-08-12 00:43:1612345 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5012346
bnc691fda62016-08-12 00:43:1612347 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112348 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012349
12350 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112351 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4612352 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012353 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012354 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012355 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12356 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012357 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012358 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012359 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12360 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012361}
12362
[email protected]749eefa82010-09-13 22:14:0312363// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0112364TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4112365 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912366 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112367 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0312368
bnc42331402016-07-25 13:36:1512369 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112370 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0312371 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112372 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0312373 };
12374
rch8e6c6c42015-05-01 14:05:1312375 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12376 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712377 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0312378
[email protected]8ddf8322012-02-23 18:08:0612379 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612380 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712381 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0312382
danakj1fd259a02016-04-16 03:17:0912383 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0312384
12385 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2312386 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012387 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5312388 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2712389 base::WeakPtr<SpdySession> spdy_session =
tfarina42834112016-09-22 13:38:2012390 CreateInsecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0312391
12392 HttpRequestInfo request;
12393 request.method = "GET";
bncce36dca22015-04-21 22:11:2312394 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0312395 request.load_flags = 0;
12396
12397 // This is the important line that marks this as a preconnect.
12398 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
12399
bnc691fda62016-08-12 00:43:1612400 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0312401
[email protected]41d64e82013-07-03 22:44:2612402 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2012403 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112404 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12405 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0312406}
12407
[email protected]73b8dd222010-11-11 19:55:2412408// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1612409// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0212410void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0712411 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2912412 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712413 request_info.url = GURL("https://www.example.com/");
12414 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912415 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712416
[email protected]8ddf8322012-02-23 18:08:0612417 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2912418 MockWrite data_writes[] = {
12419 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2412420 };
ttuttle859dc7a2015-04-23 19:42:2912421 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712422 session_deps_.socket_factory->AddSocketDataProvider(&data);
12423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2412424
danakj1fd259a02016-04-16 03:17:0912425 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612426 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2412427
[email protected]49639fa2011-12-20 23:22:4112428 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2012429 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2912430 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2412431 rv = callback.WaitForResult();
12432 ASSERT_EQ(error, rv);
12433}
12434
bncd16676a2016-07-20 16:23:0112435TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2412436 // Just check a grab bag of cert errors.
12437 static const int kErrors[] = {
12438 ERR_CERT_COMMON_NAME_INVALID,
12439 ERR_CERT_AUTHORITY_INVALID,
12440 ERR_CERT_DATE_INVALID,
12441 };
12442 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0612443 CheckErrorIsPassedBack(kErrors[i], ASYNC);
12444 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2412445 }
12446}
12447
[email protected]bd0b6772011-01-11 19:59:3012448// Ensure that a client certificate is removed from the SSL client auth
12449// cache when:
12450// 1) No proxy is involved.
12451// 2) TLS False Start is disabled.
12452// 3) The initial TLS handshake requests a client certificate.
12453// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0112454TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912455 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712456 request_info.url = GURL("https://www.example.com/");
12457 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912458 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712459
[email protected]bd0b6772011-01-11 19:59:3012460 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112461 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012462
12463 // [ssl_]data1 contains the data for the first SSL handshake. When a
12464 // CertificateRequest is received for the first time, the handshake will
12465 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2912466 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012467 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912469 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712470 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012471
12472 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
12473 // False Start is not being used, the result of the SSL handshake will be
12474 // returned as part of the SSLClientSocket::Connect() call. This test
12475 // matches the result of a server sending a handshake_failure alert,
12476 // rather than a Finished message, because it requires a client
12477 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2912478 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012479 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712480 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912481 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712482 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012483
12484 // [ssl_]data3 contains the data for the third SSL handshake. When a
12485 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212486 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
12487 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3012488 // of the HttpNetworkTransaction. Because this test failure is due to
12489 // requiring a client certificate, this fallback handshake should also
12490 // fail.
ttuttle859dc7a2015-04-23 19:42:2912491 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012492 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712493 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912494 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712495 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012496
[email protected]80c75f682012-05-26 16:22:1712497 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
12498 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212499 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
12500 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1712501 // of the HttpNetworkTransaction. Because this test failure is due to
12502 // requiring a client certificate, this fallback handshake should also
12503 // fail.
ttuttle859dc7a2015-04-23 19:42:2912504 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1712505 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712506 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912507 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712508 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712509
danakj1fd259a02016-04-16 03:17:0912510 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612511 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3012512
[email protected]bd0b6772011-01-11 19:59:3012513 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4112514 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2012515 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112516 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3012517
12518 // Complete the SSL handshake, which should abort due to requiring a
12519 // client certificate.
12520 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112521 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3012522
12523 // Indicate that no certificate should be supplied. From the perspective
12524 // of SSLClientCertCache, NULL is just as meaningful as a real
12525 // certificate, so this is the same as supply a
12526 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1612527 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0112528 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3012529
12530 // Ensure the certificate was added to the client auth cache before
12531 // allowing the connection to continue restarting.
12532 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412533 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112534 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412535 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212536 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3012537
12538 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712539 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12540 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012541 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112542 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3012543
12544 // Ensure that the client certificate is removed from the cache on a
12545 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112546 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412547 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012548}
12549
12550// Ensure that a client certificate is removed from the SSL client auth
12551// cache when:
12552// 1) No proxy is involved.
12553// 2) TLS False Start is enabled.
12554// 3) The initial TLS handshake requests a client certificate.
12555// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0112556TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912557 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712558 request_info.url = GURL("https://www.example.com/");
12559 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912560 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712561
[email protected]bd0b6772011-01-11 19:59:3012562 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112563 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012564
12565 // When TLS False Start is used, SSLClientSocket::Connect() calls will
12566 // return successfully after reading up to the peer's Certificate message.
12567 // This is to allow the caller to call SSLClientSocket::Write(), which can
12568 // enqueue application data to be sent in the same packet as the
12569 // ChangeCipherSpec and Finished messages.
12570 // The actual handshake will be finished when SSLClientSocket::Read() is
12571 // called, which expects to process the peer's ChangeCipherSpec and
12572 // Finished messages. If there was an error negotiating with the peer,
12573 // such as due to the peer requiring a client certificate when none was
12574 // supplied, the alert sent by the peer won't be processed until Read() is
12575 // called.
12576
12577 // Like the non-False Start case, when a client certificate is requested by
12578 // the peer, the handshake is aborted during the Connect() call.
12579 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2912580 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012581 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712582 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912583 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712584 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012585
12586 // When a client certificate is supplied, Connect() will not be aborted
12587 // when the peer requests the certificate. Instead, the handshake will
12588 // artificially succeed, allowing the caller to write the HTTP request to
12589 // the socket. The handshake messages are not processed until Read() is
12590 // called, which then detects that the handshake was aborted, due to the
12591 // peer sending a handshake_failure because it requires a client
12592 // certificate.
ttuttle859dc7a2015-04-23 19:42:2912593 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012594 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712595 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912596 MockRead data2_reads[] = {
12597 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3012598 };
ttuttle859dc7a2015-04-23 19:42:2912599 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712600 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012601
12602 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1712603 // the data for the SSL handshake once the TLSv1.1 connection falls back to
12604 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912605 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012606 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712607 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912608 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712609 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012610
[email protected]80c75f682012-05-26 16:22:1712611 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
12612 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912613 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1712614 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712615 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912616 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712617 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712618
[email protected]7799de12013-05-30 05:52:5112619 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2912620 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5112621 ssl_data5.cert_request_info = cert_request.get();
12622 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2912623 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5112624 session_deps_.socket_factory->AddSocketDataProvider(&data5);
12625
danakj1fd259a02016-04-16 03:17:0912626 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612627 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3012628
[email protected]bd0b6772011-01-11 19:59:3012629 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4112630 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2012631 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112632 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3012633
12634 // Complete the SSL handshake, which should abort due to requiring a
12635 // client certificate.
12636 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112637 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3012638
12639 // Indicate that no certificate should be supplied. From the perspective
12640 // of SSLClientCertCache, NULL is just as meaningful as a real
12641 // certificate, so this is the same as supply a
12642 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1612643 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0112644 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3012645
12646 // Ensure the certificate was added to the client auth cache before
12647 // allowing the connection to continue restarting.
12648 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412649 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112650 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412651 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212652 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3012653
[email protected]bd0b6772011-01-11 19:59:3012654 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712655 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12656 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012657 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112658 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3012659
12660 // Ensure that the client certificate is removed from the cache on a
12661 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112662 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412663 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012664}
12665
[email protected]8c405132011-01-11 22:03:1812666// Ensure that a client certificate is removed from the SSL client auth
12667// cache when:
12668// 1) An HTTPS proxy is involved.
12669// 3) The HTTPS proxy requests a client certificate.
12670// 4) The client supplies an invalid/unacceptable certificate for the
12671// proxy.
12672// The test is repeated twice, first for connecting to an HTTPS endpoint,
12673// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0112674TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0312675 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5112676 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712677 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1812678
12679 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112680 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1812681
12682 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
12683 // [ssl_]data[1-3]. Rather than represending the endpoint
12684 // (www.example.com:443), they represent failures with the HTTPS proxy
12685 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2912686 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1812687 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712688 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912689 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712690 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1812691
ttuttle859dc7a2015-04-23 19:42:2912692 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812693 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712694 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912695 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712696 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1812697
[email protected]80c75f682012-05-26 16:22:1712698 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
12699#if 0
ttuttle859dc7a2015-04-23 19:42:2912700 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812701 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712702 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912703 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712704 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1712705#endif
[email protected]8c405132011-01-11 22:03:1812706
ttuttle859dc7a2015-04-23 19:42:2912707 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1812708 requests[0].url = GURL("https://www.example.com/");
12709 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912710 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812711
12712 requests[1].url = GURL("http://www.example.com/");
12713 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912714 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812715
12716 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0712717 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0912718 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612719 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1812720
12721 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4112722 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2012723 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112724 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1812725
12726 // Complete the SSL handshake, which should abort due to requiring a
12727 // client certificate.
12728 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112729 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1812730
12731 // Indicate that no certificate should be supplied. From the perspective
12732 // of SSLClientCertCache, NULL is just as meaningful as a real
12733 // certificate, so this is the same as supply a
12734 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1612735 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0112736 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1812737
12738 // Ensure the certificate was added to the client auth cache before
12739 // allowing the connection to continue restarting.
12740 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412741 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112742 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412743 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212744 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1812745 // Ensure the certificate was NOT cached for the endpoint. This only
12746 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4112747 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412748 HostPortPair("www.example.com", 443), &client_cert,
12749 &client_private_key));
[email protected]8c405132011-01-11 22:03:1812750
12751 // Restart the handshake. This will consume ssl_data2, which fails, and
12752 // then consume ssl_data3, which should also fail. The result code is
12753 // checked against what ssl_data3 should return.
12754 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112755 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1812756
12757 // Now that the new handshake has failed, ensure that the client
12758 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4112759 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412760 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4112761 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412762 HostPortPair("www.example.com", 443), &client_cert,
12763 &client_private_key));
[email protected]8c405132011-01-11 22:03:1812764 }
12765}
12766
bncd16676a2016-07-20 16:23:0112767TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4612768 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712769 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0912770 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612771 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12772 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612773
[email protected]8ddf8322012-02-23 18:08:0612774 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612775 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712776 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612777
bncdf80d44fd2016-07-15 20:27:4112778 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4912779 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812780 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4112781 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4912782 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612783 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112784 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612785 };
bnc42331402016-07-25 13:36:1512786 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112787 SpdySerializedFrame host1_resp_body(
12788 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1512789 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4112790 SpdySerializedFrame host2_resp_body(
12791 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612792 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112793 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
12794 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1312795 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612796 };
12797
eroman36d84e54432016-03-17 03:23:0212798 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0212799 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312800 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12801 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712802 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612803
[email protected]aa22b242011-11-16 18:58:2912804 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612805 HttpRequestInfo request1;
12806 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312807 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612808 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012809 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612810
tfarina42834112016-09-22 13:38:2012811 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12813 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4612814
12815 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212816 ASSERT_TRUE(response);
12817 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212818 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612819
12820 std::string response_data;
robpercival214763f2016-07-01 23:27:0112821 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4612822 EXPECT_EQ("hello!", response_data);
12823
12824 // Preload www.gmail.com into HostCache.
12825 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1012826 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4612827 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1012828 std::unique_ptr<HostResolver::Request> request;
12829 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
12830 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2012831 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4712833 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112834 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4612835
12836 HttpRequestInfo request2;
12837 request2.method = "GET";
12838 request2.url = GURL("https://www.gmail.com/");
12839 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012840 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612841
tfarina42834112016-09-22 13:38:2012842 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112843 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12844 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4612845
12846 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212847 ASSERT_TRUE(response);
12848 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212849 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612850 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212851 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112852 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4612853 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612854}
12855
bncd16676a2016-07-20 16:23:0112856TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0212857 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712858 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0912859 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0212860 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12861 pool_peer.DisableDomainAuthenticationVerification();
12862
12863 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612864 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712865 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0212866
bncdf80d44fd2016-07-15 20:27:4112867 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4912868 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812869 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4112870 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4912871 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0212872 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112873 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0212874 };
bnc42331402016-07-25 13:36:1512875 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112876 SpdySerializedFrame host1_resp_body(
12877 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1512878 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4112879 SpdySerializedFrame host2_resp_body(
12880 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0212881 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112882 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
12883 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1312884 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0212885 };
12886
eroman36d84e54432016-03-17 03:23:0212887 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0212888 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312889 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12890 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712891 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0212892
12893 TestCompletionCallback callback;
12894 HttpRequestInfo request1;
12895 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312896 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0212897 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012898 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212899
tfarina42834112016-09-22 13:38:2012900 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12902 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0212903
12904 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212905 ASSERT_TRUE(response);
12906 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212907 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0212908
12909 std::string response_data;
robpercival214763f2016-07-01 23:27:0112910 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0212911 EXPECT_EQ("hello!", response_data);
12912
12913 HttpRequestInfo request2;
12914 request2.method = "GET";
12915 request2.url = GURL("https://www.gmail.com/");
12916 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012917 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212918
tfarina42834112016-09-22 13:38:2012919 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12921 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0212922
12923 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212924 ASSERT_TRUE(response);
12925 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212926 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0212927 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212928 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112929 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0212930 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0212931}
12932
ttuttle859dc7a2015-04-23 19:42:2912933class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4612934 public:
12935 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
12936 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2012937 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4612938
12939 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
12940
12941 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2012942 int Resolve(const RequestInfo& info,
12943 RequestPriority priority,
12944 AddressList* addresses,
12945 const CompletionCallback& callback,
maksim.sisov31452af2016-07-27 06:38:1012946 std::unique_ptr<Request>* out_req,
tfarina42834112016-09-22 13:38:2012947 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012948 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1012949 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4012950 }
12951
dchengb03027d2014-10-21 12:00:2012952 int ResolveFromCache(const RequestInfo& info,
12953 AddressList* addresses,
tfarina42834112016-09-22 13:38:2012954 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012955 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
12956 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0912957 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4612958 return rv;
12959 }
12960
[email protected]46da33be2011-07-19 21:58:0412961 MockCachingHostResolver* GetMockHostResolver() {
12962 return &host_resolver_;
12963 }
12964
[email protected]e3ceb682011-06-28 23:55:4612965 private:
12966 MockCachingHostResolver host_resolver_;
12967 const HostPortPair host_port_;
12968};
12969
bncd16676a2016-07-20 16:23:0112970TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1312971 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4612972 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4612973 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3412974 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0712975 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4612976 params.host_resolver = &host_resolver;
danakj1fd259a02016-04-16 03:17:0912977 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612978 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12979 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612980
[email protected]8ddf8322012-02-23 18:08:0612981 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612982 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712983 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612984
bncdf80d44fd2016-07-15 20:27:4112985 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4912986 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812987 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4112988 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4912989 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612990 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112991 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612992 };
bnc42331402016-07-25 13:36:1512993 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112994 SpdySerializedFrame host1_resp_body(
12995 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1512996 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4112997 SpdySerializedFrame host2_resp_body(
12998 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612999 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113000 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13001 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313002 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613003 };
13004
eroman36d84e54432016-03-17 03:23:0213005 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213006 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313007 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13008 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713009 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613010
[email protected]aa22b242011-11-16 18:58:2913011 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613012 HttpRequestInfo request1;
13013 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313014 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613015 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013016 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613017
tfarina42834112016-09-22 13:38:2013018 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113019 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13020 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613021
13022 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213023 ASSERT_TRUE(response);
13024 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213025 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613026
13027 std::string response_data;
robpercival214763f2016-07-01 23:27:0113028 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613029 EXPECT_EQ("hello!", response_data);
13030
13031 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1013032 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613033 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013034 std::unique_ptr<HostResolver::Request> request;
13035 rv = host_resolver.Resolve(resolve_info, DEFAULT_PRIORITY, &ignored,
tfarina42834112016-09-22 13:38:2013036 callback.callback(), &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113037 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713038 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113039 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613040
13041 HttpRequestInfo request2;
13042 request2.method = "GET";
13043 request2.url = GURL("https://www.gmail.com/");
13044 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013045 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613046
tfarina42834112016-09-22 13:38:2013047 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113048 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13049 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613050
13051 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213052 ASSERT_TRUE(response);
13053 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213054 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613055 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213056 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113057 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613058 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613059}
13060
bncd16676a2016-07-20 16:23:0113061TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313062 const std::string https_url = "https://www.example.org:8080/";
13063 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413064
13065 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4113066 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4913067 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413068
13069 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113070 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0413071 };
13072
bnc42331402016-07-25 13:36:1513073 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113074 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13075 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5913076 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413077
rch8e6c6c42015-05-01 14:05:1313078 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13079 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413080 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713081 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413082
13083 // HTTP GET for the HTTP URL
13084 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313085 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413086 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313087 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413088 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413089 };
13090
13091 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313092 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13093 MockRead(ASYNC, 2, "hello"),
13094 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413095 };
13096
rch8e6c6c42015-05-01 14:05:1313097 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13098 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0413099
[email protected]8450d722012-07-02 19:14:0413100 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613101 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713102 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13103 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13104 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0413105
danakj1fd259a02016-04-16 03:17:0913106 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413107
13108 // Start the first transaction to set up the SpdySession
13109 HttpRequestInfo request1;
13110 request1.method = "GET";
13111 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413112 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013113 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413114 TestCompletionCallback callback1;
13115 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013116 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5513117 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413118
robpercival214763f2016-07-01 23:27:0113119 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0413120 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13121
13122 // Now, start the HTTP request
13123 HttpRequestInfo request2;
13124 request2.method = "GET";
13125 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413126 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013127 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413128 TestCompletionCallback callback2;
13129 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013130 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5513131 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413132
robpercival214763f2016-07-01 23:27:0113133 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0413134 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13135}
13136
bnc5452e2a2015-05-08 16:27:4213137// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
13138// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0113139TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2513140 url::SchemeHostPort server("https", "www.example.org", 443);
13141 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4213142
bnc8bef8da22016-05-30 01:28:2513143 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4213144 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613145 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4213146 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13147
13148 // No data should be read from the alternative, because HTTP/1.1 is
13149 // negotiated.
13150 StaticSocketDataProvider data;
13151 session_deps_.socket_factory->AddSocketDataProvider(&data);
13152
13153 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4613154 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4213155 // mocked. This way the request relies on the alternate Job.
13156 StaticSocketDataProvider data_refused;
13157 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13158 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13159
zhongyi3d4a55e72016-04-22 20:36:4613160 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913161 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013162 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4213163 session->http_server_properties();
13164 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4013165 AlternateProtocolFromNextProto(kProtoHTTP2), alternative);
bnc7dc7e1b42015-07-28 14:43:1213166 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613167 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013168 expiration);
bnc5452e2a2015-05-08 16:27:4213169
bnc691fda62016-08-12 00:43:1613170 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4213171 HttpRequestInfo request;
13172 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2513173 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4213174 request.load_flags = 0;
13175 TestCompletionCallback callback;
13176
13177 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5213178 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2013179 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5213180 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4213181}
13182
bnc40448a532015-05-11 19:13:1413183// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4613184// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1413185// succeeds, the request should succeed, even if the latter fails because
13186// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0113187TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2513188 url::SchemeHostPort server("https", "www.example.org", 443);
13189 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1413190
13191 // Negotiate HTTP/1.1 with alternative.
13192 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613193 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1413194 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13195
13196 // No data should be read from the alternative, because HTTP/1.1 is
13197 // negotiated.
13198 StaticSocketDataProvider data;
13199 session_deps_.socket_factory->AddSocketDataProvider(&data);
13200
zhongyi3d4a55e72016-04-22 20:36:4613201 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1413202 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613203 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1413204 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13205
13206 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2513207 MockWrite("GET / HTTP/1.1\r\n"
13208 "Host: www.example.org\r\n"
13209 "Connection: keep-alive\r\n\r\n"),
13210 MockWrite("GET /second HTTP/1.1\r\n"
13211 "Host: www.example.org\r\n"
13212 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1413213 };
13214
13215 MockRead http_reads[] = {
13216 MockRead("HTTP/1.1 200 OK\r\n"),
13217 MockRead("Content-Type: text/html\r\n"),
13218 MockRead("Content-Length: 6\r\n\r\n"),
13219 MockRead("foobar"),
13220 MockRead("HTTP/1.1 200 OK\r\n"),
13221 MockRead("Content-Type: text/html\r\n"),
13222 MockRead("Content-Length: 7\r\n\r\n"),
13223 MockRead("another"),
13224 };
13225 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13226 http_writes, arraysize(http_writes));
13227 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13228
zhongyi3d4a55e72016-04-22 20:36:4613229 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913230 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013231 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1413232 session->http_server_properties();
13233 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4013234 AlternateProtocolFromNextProto(kProtoHTTP2), alternative);
bnc7dc7e1b42015-07-28 14:43:1213235 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613236 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013237 expiration);
bnc40448a532015-05-11 19:13:1413238
13239 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13240 HttpRequestInfo request1;
13241 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2513242 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1413243 request1.load_flags = 0;
13244 TestCompletionCallback callback1;
13245
tfarina42834112016-09-22 13:38:2013246 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1413247 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0113248 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1413249
13250 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213251 ASSERT_TRUE(response1);
13252 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1413253 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13254
13255 std::string response_data1;
robpercival214763f2016-07-01 23:27:0113256 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1413257 EXPECT_EQ("foobar", response_data1);
13258
13259 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13260 // for alternative service.
13261 EXPECT_TRUE(
13262 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13263
zhongyi3d4a55e72016-04-22 20:36:4613264 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1413265 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4613266 // to server.
bnc40448a532015-05-11 19:13:1413267 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13268 HttpRequestInfo request2;
13269 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2513270 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1413271 request2.load_flags = 0;
13272 TestCompletionCallback callback2;
13273
tfarina42834112016-09-22 13:38:2013274 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1413275 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0113276 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1413277
13278 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213279 ASSERT_TRUE(response2);
13280 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1413281 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13282
13283 std::string response_data2;
robpercival214763f2016-07-01 23:27:0113284 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1413285 EXPECT_EQ("another", response_data2);
13286}
13287
bnc5452e2a2015-05-08 16:27:4213288// Alternative service requires HTTP/2 (or SPDY), but there is already a
13289// HTTP/1.1 socket open to the alternative server. That socket should not be
13290// used.
bncd16676a2016-07-20 16:23:0113291TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4613292 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4213293 HostPortPair alternative("alternative.example.org", 443);
13294 std::string origin_url = "https://origin.example.org:443";
13295 std::string alternative_url = "https://alternative.example.org:443";
13296
13297 // Negotiate HTTP/1.1 with alternative.example.org.
13298 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613299 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4213300 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13301
13302 // HTTP/1.1 data for |request1| and |request2|.
13303 MockWrite http_writes[] = {
13304 MockWrite(
13305 "GET / HTTP/1.1\r\n"
13306 "Host: alternative.example.org\r\n"
13307 "Connection: keep-alive\r\n\r\n"),
13308 MockWrite(
13309 "GET / HTTP/1.1\r\n"
13310 "Host: alternative.example.org\r\n"
13311 "Connection: keep-alive\r\n\r\n"),
13312 };
13313
13314 MockRead http_reads[] = {
13315 MockRead(
13316 "HTTP/1.1 200 OK\r\n"
13317 "Content-Type: text/html; charset=iso-8859-1\r\n"
13318 "Content-Length: 40\r\n\r\n"
13319 "first HTTP/1.1 response from alternative"),
13320 MockRead(
13321 "HTTP/1.1 200 OK\r\n"
13322 "Content-Type: text/html; charset=iso-8859-1\r\n"
13323 "Content-Length: 41\r\n\r\n"
13324 "second HTTP/1.1 response from alternative"),
13325 };
13326 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13327 http_writes, arraysize(http_writes));
13328 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13329
13330 // This test documents that an alternate Job should not pool to an already
13331 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4613332 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4213333 StaticSocketDataProvider data_refused;
13334 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13335 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13336
zhongyi3d4a55e72016-04-22 20:36:4613337 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913338 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013339 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4213340 session->http_server_properties();
13341 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4013342 AlternateProtocolFromNextProto(kProtoHTTP2), alternative);
bnc7dc7e1b42015-07-28 14:43:1213343 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613344 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013345 expiration);
bnc5452e2a2015-05-08 16:27:4213346
13347 // First transaction to alternative to open an HTTP/1.1 socket.
bnc691fda62016-08-12 00:43:1613348 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4213349 HttpRequestInfo request1;
13350 request1.method = "GET";
13351 request1.url = GURL(alternative_url);
13352 request1.load_flags = 0;
13353 TestCompletionCallback callback1;
13354
tfarina42834112016-09-22 13:38:2013355 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113356 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1613357 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4213358 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5213359 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4213360 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5213361 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4213362 EXPECT_FALSE(response1->was_fetched_via_spdy);
13363 std::string response_data1;
bnc691fda62016-08-12 00:43:1613364 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4213365 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
13366
13367 // Request for origin.example.org, which has an alternative service. This
13368 // will start two Jobs: the alternative looks for connections to pool to,
13369 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4613370 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4213371 // this request fails.
bnc691fda62016-08-12 00:43:1613372 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4213373 HttpRequestInfo request2;
13374 request2.method = "GET";
13375 request2.url = GURL(origin_url);
13376 request2.load_flags = 0;
13377 TestCompletionCallback callback2;
13378
tfarina42834112016-09-22 13:38:2013379 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113380 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4213381
13382 // Another transaction to alternative. This is to test that the HTTP/1.1
13383 // socket is still open and in the pool.
bnc691fda62016-08-12 00:43:1613384 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4213385 HttpRequestInfo request3;
13386 request3.method = "GET";
13387 request3.url = GURL(alternative_url);
13388 request3.load_flags = 0;
13389 TestCompletionCallback callback3;
13390
tfarina42834112016-09-22 13:38:2013391 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113392 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1613393 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4213394 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5213395 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4213396 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5213397 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4213398 EXPECT_FALSE(response3->was_fetched_via_spdy);
13399 std::string response_data3;
bnc691fda62016-08-12 00:43:1613400 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4213401 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
13402}
13403
bncd16676a2016-07-20 16:23:0113404TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2313405 const std::string https_url = "https://www.example.org:8080/";
13406 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413407
rdsmithebb50aa2015-11-12 03:44:3813408 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0113409 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3813410
[email protected]8450d722012-07-02 19:14:0413411 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2313412 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4113413 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3413414 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4113415 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4913416 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113417 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0213418 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3913419
13420 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2913421 SpdyHeaderBlock req2_block;
13422 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2313423 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2913424 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4913425 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4113426 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1513427 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0413428
13429 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113430 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
13431 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0413432 };
13433
bncdf80d44fd2016-07-15 20:27:4113434 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1513435 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113436 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1513437 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113438 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
13439 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3813440 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4113441 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3813442 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1513443 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113444 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3313445 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4113446 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3313447 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4113448 CreateMockRead(wrapped_resp1, 4),
13449 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3313450 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4113451 CreateMockRead(resp2, 8),
13452 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3313453 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
13454 };
[email protected]8450d722012-07-02 19:14:0413455
mmenke666a6fea2015-12-19 04:16:3313456 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13457 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413458 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713459 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413460
rdsmith82957ad2015-09-16 19:42:0313461 session_deps_.proxy_service =
13462 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5113463 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713464 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0413465 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3613466 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3313467 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0413468 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3613469 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3313470 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13471 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0413472
danakj1fd259a02016-04-16 03:17:0913473 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0413474
13475 // Start the first transaction to set up the SpdySession
13476 HttpRequestInfo request1;
13477 request1.method = "GET";
13478 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413479 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013480 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413481 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2013482 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0413483
mmenke666a6fea2015-12-19 04:16:3313484 // This pause is a hack to avoid running into https://crbug.com/497228.
13485 data1.RunUntilPaused();
13486 base::RunLoop().RunUntilIdle();
13487 data1.Resume();
robpercival214763f2016-07-01 23:27:0113488 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0413489 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13490
[email protected]f6c63db52013-02-02 00:35:2213491 LoadTimingInfo load_timing_info1;
13492 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
13493 TestLoadTimingNotReusedWithPac(load_timing_info1,
13494 CONNECT_TIMING_HAS_SSL_TIMES);
13495
mmenke666a6fea2015-12-19 04:16:3313496 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0413497 HttpRequestInfo request2;
13498 request2.method = "GET";
13499 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413500 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013501 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413502 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2013503 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0413504
mmenke666a6fea2015-12-19 04:16:3313505 // This pause is a hack to avoid running into https://crbug.com/497228.
13506 data1.RunUntilPaused();
13507 base::RunLoop().RunUntilIdle();
13508 data1.Resume();
robpercival214763f2016-07-01 23:27:0113509 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3313510
[email protected]8450d722012-07-02 19:14:0413511 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2213512
13513 LoadTimingInfo load_timing_info2;
13514 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
13515 // The established SPDY sessions is considered reused by the HTTP request.
13516 TestLoadTimingReusedWithPac(load_timing_info2);
13517 // HTTP requests over a SPDY session should have a different connection
13518 // socket_log_id than requests over a tunnel.
13519 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0413520}
13521
[email protected]2d88e7d2012-07-19 17:55:1713522// Test that in the case where we have a SPDY session to a SPDY proxy
13523// that we do not pool other origins that resolve to the same IP when
13524// the certificate does not match the new origin.
13525// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0113526TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2313527 const std::string url1 = "http://www.example.org/";
13528 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1713529 const std::string ip_addr = "1.2.3.4";
13530
rdsmithebb50aa2015-11-12 03:44:3813531 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0113532 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3813533
[email protected]2d88e7d2012-07-19 17:55:1713534 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2613535 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2313536 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4113537 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1513538 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1713539
13540 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113541 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1713542 };
13543
bnc42331402016-07-25 13:36:1513544 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113545 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1713546 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4113547 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
13548 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1713549 };
13550
mmenke666a6fea2015-12-19 04:16:3313551 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13552 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3213553 IPAddress ip;
martijn654c8c42016-02-10 22:10:5913554 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1713555 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13556 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3313557 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1713558
13559 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4113560 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4913561 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1713562
13563 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4113564 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1713565 };
13566
bnc42331402016-07-25 13:36:1513567 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113568 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
13569 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3313570 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1713571
mmenke666a6fea2015-12-19 04:16:3313572 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13573 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1713574 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3313575 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1713576
13577 // Set up a proxy config that sends HTTP requests to a proxy, and
13578 // all others direct.
13579 ProxyConfig proxy_config;
13580 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0713581 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0913582 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), nullptr,
csharrisonb7e3a082015-09-22 19:13:0413583 NULL));
[email protected]2d88e7d2012-07-19 17:55:1713584
bncce36dca22015-04-21 22:11:2313585 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3613586 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1713587 // Load a valid cert. Note, that this does not need to
13588 // be valid for proxy because the MockSSLClientSocket does
13589 // not actually verify it. But SpdySession will use this
13590 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2313591 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5213592 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3313593 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13594 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1713595
13596 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3613597 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3313598 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13599 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1713600
[email protected]bb88e1d32013-05-03 23:11:0713601 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2313602 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0713603 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1713604
danakj1fd259a02016-04-16 03:17:0913605 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1713606
13607 // Start the first transaction to set up the SpdySession
13608 HttpRequestInfo request1;
13609 request1.method = "GET";
13610 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1713611 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013612 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713613 TestCompletionCallback callback1;
13614 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013615 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3313616 // This pause is a hack to avoid running into https://crbug.com/497228.
13617 data1.RunUntilPaused();
13618 base::RunLoop().RunUntilIdle();
13619 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1713620
robpercival214763f2016-07-01 23:27:0113621 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1713622 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13623
13624 // Now, start the HTTP request
13625 HttpRequestInfo request2;
13626 request2.method = "GET";
13627 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1713628 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013629 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713630 TestCompletionCallback callback2;
13631 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013632 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5513633 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1713634
13635 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0113636 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1713637 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13638}
13639
[email protected]85f97342013-04-17 06:12:2413640// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
13641// error) in SPDY session, removes the socket from pool and closes the SPDY
13642// session. Verify that new url's from the same HttpNetworkSession (and a new
13643// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0113644TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2313645 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2413646
13647 MockRead reads1[] = {
13648 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
13649 };
13650
mmenke11eb5152015-06-09 14:50:5013651 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2413652
bncdf80d44fd2016-07-15 20:27:4113653 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4913654 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2413655 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4113656 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2413657 };
13658
bnc42331402016-07-25 13:36:1513659 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113660 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2413661 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4113662 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
13663 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2413664 };
13665
mmenke11eb5152015-06-09 14:50:5013666 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13667 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2413668
[email protected]85f97342013-04-17 06:12:2413669 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613670 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5013671 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13672 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2413673
13674 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613675 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5013676 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13677 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2413678
danakj1fd259a02016-04-16 03:17:0913679 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5013680 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2413681
13682 // Start the first transaction to set up the SpdySession and verify that
13683 // connection was closed.
13684 HttpRequestInfo request1;
13685 request1.method = "GET";
13686 request1.url = GURL(https_url);
13687 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013688 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413689 TestCompletionCallback callback1;
13690 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013691 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0113692 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2413693
13694 // Now, start the second request and make sure it succeeds.
13695 HttpRequestInfo request2;
13696 request2.method = "GET";
13697 request2.url = GURL(https_url);
13698 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013699 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413700 TestCompletionCallback callback2;
13701 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013702 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2413703
robpercival214763f2016-07-01 23:27:0113704 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2413705 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13706}
13707
bncd16676a2016-07-20 16:23:0113708TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0313709 ClientSocketPoolManager::set_max_sockets_per_group(
13710 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13711 ClientSocketPoolManager::set_max_sockets_per_pool(
13712 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13713
13714 // Use two different hosts with different IPs so they don't get pooled.
13715 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
13716 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0913717 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0313718
13719 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613720 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0313721 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613722 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0313723 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13724 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13725
bncdf80d44fd2016-07-15 20:27:4113726 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913727 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0313728 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113729 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0313730 };
bnc42331402016-07-25 13:36:1513731 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113732 SpdySerializedFrame host1_resp_body(
13733 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313734 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113735 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5913736 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313737 };
13738
rdsmithebb50aa2015-11-12 03:44:3813739 // Use a separate test instance for the separate SpdySession that will be
13740 // created.
bncd16676a2016-07-20 16:23:0113741 SpdyTestUtil spdy_util_2;
danakj1fd259a02016-04-16 03:17:0913742 std::unique_ptr<SequencedSocketData> spdy1_data(
rch8e6c6c42015-05-01 14:05:1313743 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
13744 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0313745 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
13746
bncdf80d44fd2016-07-15 20:27:4113747 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4913748 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0313749 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113750 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0313751 };
bnc42331402016-07-25 13:36:1513752 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113753 SpdySerializedFrame host2_resp_body(
13754 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313755 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113756 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5913757 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313758 };
13759
danakj1fd259a02016-04-16 03:17:0913760 std::unique_ptr<SequencedSocketData> spdy2_data(
rch8e6c6c42015-05-01 14:05:1313761 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
13762 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0313763 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
13764
13765 MockWrite http_write[] = {
13766 MockWrite("GET / HTTP/1.1\r\n"
13767 "Host: www.a.com\r\n"
13768 "Connection: keep-alive\r\n\r\n"),
13769 };
13770
13771 MockRead http_read[] = {
13772 MockRead("HTTP/1.1 200 OK\r\n"),
13773 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13774 MockRead("Content-Length: 6\r\n\r\n"),
13775 MockRead("hello!"),
13776 };
13777 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
13778 http_write, arraysize(http_write));
13779 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13780
13781 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4013782 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5313783 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313784 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613785 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313786
13787 TestCompletionCallback callback;
13788 HttpRequestInfo request1;
13789 request1.method = "GET";
13790 request1.url = GURL("https://www.a.com/");
13791 request1.load_flags = 0;
danakj1fd259a02016-04-16 03:17:0913792 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5013793 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313794
tfarina42834112016-09-22 13:38:2013795 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113796 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13797 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0313798
13799 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213800 ASSERT_TRUE(response);
13801 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213802 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0313803 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213804 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0313805
13806 std::string response_data;
robpercival214763f2016-07-01 23:27:0113807 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0313808 EXPECT_EQ("hello!", response_data);
13809 trans.reset();
13810 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613811 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313812
13813 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4013814 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5313815 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313816 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613817 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313818 HttpRequestInfo request2;
13819 request2.method = "GET";
13820 request2.url = GURL("https://www.b.com/");
13821 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013822 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313823
tfarina42834112016-09-22 13:38:2013824 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13826 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0313827
13828 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213829 ASSERT_TRUE(response);
13830 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213831 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0313832 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213833 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113834 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0313835 EXPECT_EQ("hello!", response_data);
13836 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613837 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313838 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613839 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313840
13841 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4013842 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5313843 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313844 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613845 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0313846 HttpRequestInfo request3;
13847 request3.method = "GET";
13848 request3.url = GURL("http://www.a.com/");
13849 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013850 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313851
tfarina42834112016-09-22 13:38:2013852 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13854 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0313855
13856 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213857 ASSERT_TRUE(response);
13858 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0313859 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13860 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213861 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113862 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0313863 EXPECT_EQ("hello!", response_data);
13864 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613865 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313866 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613867 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313868}
13869
bncd16676a2016-07-20 16:23:0113870TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0413871 HttpRequestInfo request;
13872 request.method = "GET";
bncce36dca22015-04-21 22:11:2313873 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413874 request.load_flags = 0;
13875
danakj1fd259a02016-04-16 03:17:0913876 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613877 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0413878
ttuttled9dbc652015-09-29 20:00:5913879 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413880 StaticSocketDataProvider data;
13881 data.set_connect_data(mock_connect);
13882 session_deps_.socket_factory->AddSocketDataProvider(&data);
13883
13884 TestCompletionCallback callback;
13885
tfarina42834112016-09-22 13:38:2013886 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113887 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0413888
13889 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113890 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0413891
[email protected]79e1fd62013-06-20 06:50:0413892 // We don't care whether this succeeds or fails, but it shouldn't crash.
13893 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1613894 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713895
13896 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1613897 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4713898 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0113899 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5913900
13901 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1613902 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5913903 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413904}
13905
bncd16676a2016-07-20 16:23:0113906TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0413907 HttpRequestInfo request;
13908 request.method = "GET";
bncce36dca22015-04-21 22:11:2313909 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413910 request.load_flags = 0;
13911
danakj1fd259a02016-04-16 03:17:0913912 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613913 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0413914
ttuttled9dbc652015-09-29 20:00:5913915 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413916 StaticSocketDataProvider data;
13917 data.set_connect_data(mock_connect);
13918 session_deps_.socket_factory->AddSocketDataProvider(&data);
13919
13920 TestCompletionCallback callback;
13921
tfarina42834112016-09-22 13:38:2013922 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0413924
13925 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113926 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0413927
[email protected]79e1fd62013-06-20 06:50:0413928 // We don't care whether this succeeds or fails, but it shouldn't crash.
13929 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1613930 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713931
13932 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1613933 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4713934 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0113935 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5913936
13937 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1613938 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5913939 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413940}
13941
bncd16676a2016-07-20 16:23:0113942TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0413943 HttpRequestInfo request;
13944 request.method = "GET";
bncce36dca22015-04-21 22:11:2313945 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413946 request.load_flags = 0;
13947
danakj1fd259a02016-04-16 03:17:0913948 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613949 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0413950
13951 MockWrite data_writes[] = {
13952 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13953 };
13954 MockRead data_reads[] = {
13955 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13956 };
13957
13958 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13959 data_writes, arraysize(data_writes));
13960 session_deps_.socket_factory->AddSocketDataProvider(&data);
13961
13962 TestCompletionCallback callback;
13963
tfarina42834112016-09-22 13:38:2013964 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113965 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0413966
13967 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113968 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0413969
[email protected]79e1fd62013-06-20 06:50:0413970 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1613971 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0413972 EXPECT_TRUE(request_headers.HasHeader("Host"));
13973}
13974
bncd16676a2016-07-20 16:23:0113975TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0413976 HttpRequestInfo request;
13977 request.method = "GET";
bncce36dca22015-04-21 22:11:2313978 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413979 request.load_flags = 0;
13980
danakj1fd259a02016-04-16 03:17:0913981 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613982 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0413983
13984 MockWrite data_writes[] = {
13985 MockWrite(ASYNC, ERR_CONNECTION_RESET),
13986 };
13987 MockRead data_reads[] = {
13988 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13989 };
13990
13991 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13992 data_writes, arraysize(data_writes));
13993 session_deps_.socket_factory->AddSocketDataProvider(&data);
13994
13995 TestCompletionCallback callback;
13996
tfarina42834112016-09-22 13:38:2013997 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113998 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0413999
14000 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114001 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414002
[email protected]79e1fd62013-06-20 06:50:0414003 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614004 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414005 EXPECT_TRUE(request_headers.HasHeader("Host"));
14006}
14007
bncd16676a2016-07-20 16:23:0114008TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414009 HttpRequestInfo request;
14010 request.method = "GET";
bncce36dca22015-04-21 22:11:2314011 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414012 request.load_flags = 0;
14013
danakj1fd259a02016-04-16 03:17:0914014 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614015 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414016
14017 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314018 MockWrite(
14019 "GET / HTTP/1.1\r\n"
14020 "Host: www.example.org\r\n"
14021 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414022 };
14023 MockRead data_reads[] = {
14024 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14025 };
14026
14027 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14028 data_writes, arraysize(data_writes));
14029 session_deps_.socket_factory->AddSocketDataProvider(&data);
14030
14031 TestCompletionCallback callback;
14032
tfarina42834112016-09-22 13:38:2014033 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414035
14036 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114037 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414038
[email protected]79e1fd62013-06-20 06:50:0414039 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614040 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414041 EXPECT_TRUE(request_headers.HasHeader("Host"));
14042}
14043
bncd16676a2016-07-20 16:23:0114044TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414045 HttpRequestInfo request;
14046 request.method = "GET";
bncce36dca22015-04-21 22:11:2314047 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414048 request.load_flags = 0;
14049
danakj1fd259a02016-04-16 03:17:0914050 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614051 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414052
14053 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314054 MockWrite(
14055 "GET / HTTP/1.1\r\n"
14056 "Host: www.example.org\r\n"
14057 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414058 };
14059 MockRead data_reads[] = {
14060 MockRead(ASYNC, ERR_CONNECTION_RESET),
14061 };
14062
14063 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14064 data_writes, arraysize(data_writes));
14065 session_deps_.socket_factory->AddSocketDataProvider(&data);
14066
14067 TestCompletionCallback callback;
14068
tfarina42834112016-09-22 13:38:2014069 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114070 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414071
14072 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114073 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414074
[email protected]79e1fd62013-06-20 06:50:0414075 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614076 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414077 EXPECT_TRUE(request_headers.HasHeader("Host"));
14078}
14079
bncd16676a2016-07-20 16:23:0114080TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0414081 HttpRequestInfo request;
14082 request.method = "GET";
bncce36dca22015-04-21 22:11:2314083 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414084 request.load_flags = 0;
14085 request.extra_headers.SetHeader("X-Foo", "bar");
14086
danakj1fd259a02016-04-16 03:17:0914087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614088 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414089
14090 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314091 MockWrite(
14092 "GET / HTTP/1.1\r\n"
14093 "Host: www.example.org\r\n"
14094 "Connection: keep-alive\r\n"
14095 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414096 };
14097 MockRead data_reads[] = {
14098 MockRead("HTTP/1.1 200 OK\r\n"
14099 "Content-Length: 5\r\n\r\n"
14100 "hello"),
14101 MockRead(ASYNC, ERR_UNEXPECTED),
14102 };
14103
14104 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14105 data_writes, arraysize(data_writes));
14106 session_deps_.socket_factory->AddSocketDataProvider(&data);
14107
14108 TestCompletionCallback callback;
14109
tfarina42834112016-09-22 13:38:2014110 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414112
14113 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114114 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0414115
14116 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614117 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414118 std::string foo;
14119 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14120 EXPECT_EQ("bar", foo);
14121}
14122
[email protected]bf828982013-08-14 18:01:4714123namespace {
14124
yhiranoa7e05bb2014-11-06 05:40:3914125// Fake HttpStream that simply records calls to SetPriority().
14126class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0314127 public base::SupportsWeakPtr<FakeStream> {
14128 public:
14129 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2014130 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0314131
14132 RequestPriority priority() const { return priority_; }
14133
dchengb03027d2014-10-21 12:00:2014134 int InitializeStream(const HttpRequestInfo* request_info,
14135 RequestPriority priority,
tfarina42834112016-09-22 13:38:2014136 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2014137 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314138 return ERR_IO_PENDING;
14139 }
14140
dchengb03027d2014-10-21 12:00:2014141 int SendRequest(const HttpRequestHeaders& request_headers,
14142 HttpResponseInfo* response,
14143 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314144 ADD_FAILURE();
14145 return ERR_UNEXPECTED;
14146 }
14147
dchengb03027d2014-10-21 12:00:2014148 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314149 ADD_FAILURE();
14150 return ERR_UNEXPECTED;
14151 }
14152
dchengb03027d2014-10-21 12:00:2014153 int ReadResponseBody(IOBuffer* buf,
14154 int buf_len,
14155 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314156 ADD_FAILURE();
14157 return ERR_UNEXPECTED;
14158 }
14159
dchengb03027d2014-10-21 12:00:2014160 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0314161
dchengb03027d2014-10-21 12:00:2014162 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0314163 ADD_FAILURE();
14164 return false;
14165 }
14166
dchengb03027d2014-10-21 12:00:2014167 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0314168 ADD_FAILURE();
14169 return false;
14170 }
14171
dchengb03027d2014-10-21 12:00:2014172 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314173
mmenkebd84c392015-09-02 14:12:3414174 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314175
sclittle4de1bab92015-09-22 21:28:2414176 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914177 ADD_FAILURE();
14178 return 0;
14179 }
14180
sclittlebe1ccf62015-09-02 19:40:3614181 int64_t GetTotalSentBytes() const override {
14182 ADD_FAILURE();
14183 return 0;
14184 }
14185
dchengb03027d2014-10-21 12:00:2014186 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314187 ADD_FAILURE();
14188 return false;
14189 }
14190
dchengb03027d2014-10-21 12:00:2014191 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14192
14193 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314194 ADD_FAILURE();
14195 }
14196
ttuttled9dbc652015-09-29 20:00:5914197 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14198
nharper78e6d2b2016-09-21 05:42:3514199 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
14200 TokenBindingType tb_type,
14201 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1414202 ADD_FAILURE();
14203 return ERR_NOT_IMPLEMENTED;
14204 }
14205
dchengb03027d2014-10-21 12:00:2014206 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314207
zhongyica364fbb2015-12-12 03:39:1214208 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14209
dchengb03027d2014-10-21 12:00:2014210 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314211
yhiranoa7e05bb2014-11-06 05:40:3914212 HttpStream* RenewStreamForAuth() override { return NULL; }
14213
[email protected]e86839fd2013-08-14 18:29:0314214 private:
14215 RequestPriority priority_;
14216
14217 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14218};
14219
14220// Fake HttpStreamRequest that simply records calls to SetPriority()
14221// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714222class FakeStreamRequest : public HttpStreamRequest,
14223 public base::SupportsWeakPtr<FakeStreamRequest> {
14224 public:
[email protected]e86839fd2013-08-14 18:29:0314225 FakeStreamRequest(RequestPriority priority,
14226 HttpStreamRequest::Delegate* delegate)
14227 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414228 delegate_(delegate),
14229 websocket_stream_create_helper_(NULL) {}
14230
14231 FakeStreamRequest(RequestPriority priority,
14232 HttpStreamRequest::Delegate* delegate,
14233 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14234 : priority_(priority),
14235 delegate_(delegate),
14236 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314237
dchengb03027d2014-10-21 12:00:2014238 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714239
14240 RequestPriority priority() const { return priority_; }
14241
[email protected]831e4a32013-11-14 02:14:4414242 const WebSocketHandshakeStreamBase::CreateHelper*
14243 websocket_stream_create_helper() const {
14244 return websocket_stream_create_helper_;
14245 }
14246
[email protected]e86839fd2013-08-14 18:29:0314247 // Create a new FakeStream and pass it to the request's
14248 // delegate. Returns a weak pointer to the FakeStream.
14249 base::WeakPtr<FakeStream> FinishStreamRequest() {
14250 FakeStream* fake_stream = new FakeStream(priority_);
14251 // Do this before calling OnStreamReady() as OnStreamReady() may
14252 // immediately delete |fake_stream|.
14253 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14254 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14255 return weak_stream;
14256 }
14257
dchengb03027d2014-10-21 12:00:2014258 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714259 ADD_FAILURE();
14260 return ERR_UNEXPECTED;
14261 }
14262
dchengb03027d2014-10-21 12:00:2014263 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714264 ADD_FAILURE();
14265 return LoadState();
14266 }
14267
dchengb03027d2014-10-21 12:00:2014268 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714269
bnc94c92842016-09-21 15:22:5214270 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714271
bnc6227b26e2016-08-12 02:00:4314272 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714273
dchengb03027d2014-10-21 12:00:2014274 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714275
ttuttle1f2d7e92015-04-28 16:17:4714276 const ConnectionAttempts& connection_attempts() const override {
14277 static ConnectionAttempts no_attempts;
14278 return no_attempts;
14279 }
14280
[email protected]bf828982013-08-14 18:01:4714281 private:
14282 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314283 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414284 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714285
14286 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14287};
14288
14289// Fake HttpStreamFactory that vends FakeStreamRequests.
14290class FakeStreamFactory : public HttpStreamFactory {
14291 public:
14292 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014293 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714294
14295 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14296 // RequestStream() (which may be NULL if it was destroyed already).
14297 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14298 return last_stream_request_;
14299 }
14300
dchengb03027d2014-10-21 12:00:2014301 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14302 RequestPriority priority,
14303 const SSLConfig& server_ssl_config,
14304 const SSLConfig& proxy_ssl_config,
14305 HttpStreamRequest::Delegate* delegate,
tfarina42834112016-09-22 13:38:2014306 const NetLogWithSource& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314307 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714308 last_stream_request_ = fake_request->AsWeakPtr();
14309 return fake_request;
14310 }
14311
xunjieli5749218c2016-03-22 16:43:0614312 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0814313 const HttpRequestInfo& info,
14314 RequestPriority priority,
14315 const SSLConfig& server_ssl_config,
14316 const SSLConfig& proxy_ssl_config,
14317 HttpStreamRequest::Delegate* delegate,
tfarina42834112016-09-22 13:38:2014318 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0814319 NOTREACHED();
14320 return nullptr;
14321 }
14322
dchengb03027d2014-10-21 12:00:2014323 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714324 const HttpRequestInfo& info,
14325 RequestPriority priority,
14326 const SSLConfig& server_ssl_config,
14327 const SSLConfig& proxy_ssl_config,
14328 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614329 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
tfarina42834112016-09-22 13:38:2014330 const NetLogWithSource& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414331 FakeStreamRequest* fake_request =
14332 new FakeStreamRequest(priority, delegate, create_helper);
14333 last_stream_request_ = fake_request->AsWeakPtr();
14334 return fake_request;
[email protected]bf828982013-08-14 18:01:4714335 }
14336
dchengb03027d2014-10-21 12:00:2014337 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5914338 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4714339 ADD_FAILURE();
14340 }
14341
dchengb03027d2014-10-21 12:00:2014342 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714343 ADD_FAILURE();
14344 return NULL;
14345 }
14346
14347 private:
14348 base::WeakPtr<FakeStreamRequest> last_stream_request_;
14349
14350 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
14351};
14352
Adam Rice425cf122015-01-19 06:18:2414353// TODO(ricea): Maybe unify this with the one in
14354// url_request_http_job_unittest.cc ?
14355class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
14356 public:
danakj1fd259a02016-04-16 03:17:0914357 FakeWebSocketBasicHandshakeStream(
14358 std::unique_ptr<ClientSocketHandle> connection,
14359 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5214360 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2414361
14362 // Fake implementation of HttpStreamBase methods.
14363 // This ends up being quite "real" because this object has to really send data
14364 // on the mock socket. It might be easier to use the real implementation, but
14365 // the fact that the WebSocket code is not compiled on iOS makes that
14366 // difficult.
14367 int InitializeStream(const HttpRequestInfo* request_info,
14368 RequestPriority priority,
tfarina42834112016-09-22 13:38:2014369 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2414370 const CompletionCallback& callback) override {
14371 state_.Initialize(request_info, priority, net_log, callback);
14372 return OK;
14373 }
14374
14375 int SendRequest(const HttpRequestHeaders& request_headers,
14376 HttpResponseInfo* response,
14377 const CompletionCallback& callback) override {
14378 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
14379 response, callback);
14380 }
14381
14382 int ReadResponseHeaders(const CompletionCallback& callback) override {
14383 return parser()->ReadResponseHeaders(callback);
14384 }
14385
14386 int ReadResponseBody(IOBuffer* buf,
14387 int buf_len,
14388 const CompletionCallback& callback) override {
14389 NOTREACHED();
14390 return ERR_IO_PENDING;
14391 }
14392
14393 void Close(bool not_reusable) override {
14394 if (parser())
14395 parser()->Close(true);
14396 }
14397
14398 bool IsResponseBodyComplete() const override {
14399 NOTREACHED();
14400 return false;
14401 }
14402
Adam Rice425cf122015-01-19 06:18:2414403 bool IsConnectionReused() const override {
14404 NOTREACHED();
14405 return false;
14406 }
14407 void SetConnectionReused() override { NOTREACHED(); }
14408
mmenkebd84c392015-09-02 14:12:3414409 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2414410
sclittle4de1bab92015-09-22 21:28:2414411 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2414412 NOTREACHED();
14413 return 0;
14414 }
14415
sclittlebe1ccf62015-09-02 19:40:3614416 int64_t GetTotalSentBytes() const override {
14417 NOTREACHED();
14418 return 0;
14419 }
14420
Adam Rice425cf122015-01-19 06:18:2414421 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
14422 NOTREACHED();
14423 return false;
14424 }
14425
Adam Ricecb76ac62015-02-20 05:33:2514426 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2414427
14428 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
14429 NOTREACHED();
14430 }
14431
ttuttled9dbc652015-09-29 20:00:5914432 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14433
nharper78e6d2b2016-09-21 05:42:3514434 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
14435 TokenBindingType tb_type,
14436 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1414437 ADD_FAILURE();
14438 return ERR_NOT_IMPLEMENTED;
14439 }
14440
Adam Rice425cf122015-01-19 06:18:2414441 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
14442
zhongyica364fbb2015-12-12 03:39:1214443 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14444
Adam Rice425cf122015-01-19 06:18:2414445 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
14446
Adam Rice425cf122015-01-19 06:18:2414447 HttpStream* RenewStreamForAuth() override {
14448 NOTREACHED();
14449 return nullptr;
14450 }
14451
14452 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0914453 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2414454 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0914455 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2414456 }
14457
14458 private:
14459 HttpStreamParser* parser() const { return state_.parser(); }
14460 HttpBasicState state_;
14461
14462 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
14463};
14464
[email protected]831e4a32013-11-14 02:14:4414465// TODO(yhirano): Split this class out into a net/websockets file, if it is
14466// worth doing.
14467class FakeWebSocketStreamCreateHelper :
14468 public WebSocketHandshakeStreamBase::CreateHelper {
14469 public:
dchengb03027d2014-10-21 12:00:2014470 WebSocketHandshakeStreamBase* CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0914471 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1314472 bool using_proxy) override {
dchengc7eeda422015-12-26 03:56:4814473 return new FakeWebSocketBasicHandshakeStream(std::move(connection),
Adam Rice425cf122015-01-19 06:18:2414474 using_proxy);
[email protected]831e4a32013-11-14 02:14:4414475 }
14476
dchengb03027d2014-10-21 12:00:2014477 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4414478 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1314479 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4414480 NOTREACHED();
14481 return NULL;
14482 };
14483
dchengb03027d2014-10-21 12:00:2014484 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4414485
danakj1fd259a02016-04-16 03:17:0914486 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4414487 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0914488 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4414489 }
14490};
14491
[email protected]bf828982013-08-14 18:01:4714492} // namespace
14493
14494// Make sure that HttpNetworkTransaction passes on its priority to its
14495// stream request on start.
bncd16676a2016-07-20 16:23:0114496TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0914497 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4214498 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714499 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0914500 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714501
dcheng48459ac22014-08-26 00:46:4114502 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714503
wezca1070932016-05-26 20:30:5214504 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4714505
14506 HttpRequestInfo request;
14507 TestCompletionCallback callback;
14508 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014509 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4714510
14511 base::WeakPtr<FakeStreamRequest> fake_request =
14512 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5214513 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4714514 EXPECT_EQ(LOW, fake_request->priority());
14515}
14516
14517// Make sure that HttpNetworkTransaction passes on its priority
14518// updates to its stream request.
bncd16676a2016-07-20 16:23:0114519TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0914520 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4214521 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714522 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0914523 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714524
dcheng48459ac22014-08-26 00:46:4114525 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714526
14527 HttpRequestInfo request;
14528 TestCompletionCallback callback;
14529 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014530 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4714531
14532 base::WeakPtr<FakeStreamRequest> fake_request =
14533 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5214534 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4714535 EXPECT_EQ(LOW, fake_request->priority());
14536
14537 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5214538 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4714539 EXPECT_EQ(LOWEST, fake_request->priority());
14540}
14541
[email protected]e86839fd2013-08-14 18:29:0314542// Make sure that HttpNetworkTransaction passes on its priority
14543// updates to its stream.
bncd16676a2016-07-20 16:23:0114544TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0914545 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4214546 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0314547 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0914548 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0314549
dcheng48459ac22014-08-26 00:46:4114550 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0314551
14552 HttpRequestInfo request;
14553 TestCompletionCallback callback;
14554 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014555 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0314556
14557 base::WeakPtr<FakeStreamRequest> fake_request =
14558 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5214559 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0314560 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5214561 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0314562 EXPECT_EQ(LOW, fake_stream->priority());
14563
14564 trans.SetPriority(LOWEST);
14565 EXPECT_EQ(LOWEST, fake_stream->priority());
14566}
14567
bncd16676a2016-07-20 16:23:0114568TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4414569 // The same logic needs to be tested for both ws: and wss: schemes, but this
14570 // test is already parameterised on NextProto, so it uses a loop to verify
14571 // that the different schemes work.
bncce36dca22015-04-21 22:11:2314572 std::string test_cases[] = {"ws://www.example.org/",
14573 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4414574 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0914575 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4214576 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4414577 FakeStreamFactory* fake_factory = new FakeStreamFactory();
14578 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2314579 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0914580 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4414581
dcheng48459ac22014-08-26 00:46:4114582 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4414583 trans.SetWebSocketHandshakeStreamCreateHelper(
14584 &websocket_stream_create_helper);
14585
14586 HttpRequestInfo request;
14587 TestCompletionCallback callback;
14588 request.method = "GET";
14589 request.url = GURL(test_cases[i]);
14590
14591 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014592 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4414593
14594 base::WeakPtr<FakeStreamRequest> fake_request =
14595 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5214596 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4414597 EXPECT_EQ(&websocket_stream_create_helper,
14598 fake_request->websocket_stream_create_helper());
14599 }
14600}
14601
[email protected]043b68c82013-08-22 23:41:5214602// Tests that when a used socket is returned to the SSL socket pool, it's closed
14603// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0114604TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5214605 ClientSocketPoolManager::set_max_sockets_per_group(
14606 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14607 ClientSocketPoolManager::set_max_sockets_per_pool(
14608 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14609
14610 // Set up SSL request.
14611
14612 HttpRequestInfo ssl_request;
14613 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2314614 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214615
14616 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2314617 MockWrite(
14618 "GET / HTTP/1.1\r\n"
14619 "Host: www.example.org\r\n"
14620 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214621 };
14622 MockRead ssl_reads[] = {
14623 MockRead("HTTP/1.1 200 OK\r\n"),
14624 MockRead("Content-Length: 11\r\n\r\n"),
14625 MockRead("hello world"),
14626 MockRead(SYNCHRONOUS, OK),
14627 };
14628 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
14629 ssl_writes, arraysize(ssl_writes));
14630 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14631
14632 SSLSocketDataProvider ssl(ASYNC, OK);
14633 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14634
14635 // Set up HTTP request.
14636
14637 HttpRequestInfo http_request;
14638 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314639 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214640
14641 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314642 MockWrite(
14643 "GET / HTTP/1.1\r\n"
14644 "Host: www.example.org\r\n"
14645 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214646 };
14647 MockRead http_reads[] = {
14648 MockRead("HTTP/1.1 200 OK\r\n"),
14649 MockRead("Content-Length: 7\r\n\r\n"),
14650 MockRead("falafel"),
14651 MockRead(SYNCHRONOUS, OK),
14652 };
14653 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14654 http_writes, arraysize(http_writes));
14655 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14656
danakj1fd259a02016-04-16 03:17:0914657 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5214658
14659 // Start the SSL request.
14660 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1614661 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2014662 ASSERT_EQ(ERR_IO_PENDING,
14663 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
14664 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5214665
14666 // Start the HTTP request. Pool should stall.
14667 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1614668 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2014669 ASSERT_EQ(ERR_IO_PENDING,
14670 http_trans.Start(&http_request, http_callback.callback(),
14671 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4114672 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214673
14674 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0114675 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5214676 std::string response_data;
bnc691fda62016-08-12 00:43:1614677 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5214678 EXPECT_EQ("hello world", response_data);
14679
14680 // The SSL socket should automatically be closed, so the HTTP request can
14681 // start.
dcheng48459ac22014-08-26 00:46:4114682 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
14683 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214684
14685 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0114686 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1614687 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5214688 EXPECT_EQ("falafel", response_data);
14689
dcheng48459ac22014-08-26 00:46:4114690 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214691}
14692
14693// Tests that when a SSL connection is established but there's no corresponding
14694// request that needs it, the new socket is closed if the transport socket pool
14695// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0114696TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5214697 ClientSocketPoolManager::set_max_sockets_per_group(
14698 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14699 ClientSocketPoolManager::set_max_sockets_per_pool(
14700 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14701
14702 // Set up an ssl request.
14703
14704 HttpRequestInfo ssl_request;
14705 ssl_request.method = "GET";
14706 ssl_request.url = GURL("https://www.foopy.com/");
14707
14708 // No data will be sent on the SSL socket.
14709 StaticSocketDataProvider ssl_data;
14710 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14711
14712 SSLSocketDataProvider ssl(ASYNC, OK);
14713 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14714
14715 // Set up HTTP request.
14716
14717 HttpRequestInfo http_request;
14718 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314719 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214720
14721 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314722 MockWrite(
14723 "GET / HTTP/1.1\r\n"
14724 "Host: www.example.org\r\n"
14725 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214726 };
14727 MockRead http_reads[] = {
14728 MockRead("HTTP/1.1 200 OK\r\n"),
14729 MockRead("Content-Length: 7\r\n\r\n"),
14730 MockRead("falafel"),
14731 MockRead(SYNCHRONOUS, OK),
14732 };
14733 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14734 http_writes, arraysize(http_writes));
14735 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14736
danakj1fd259a02016-04-16 03:17:0914737 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5214738
14739 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
14740 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2914741 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5914742 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4114743 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214744
14745 // Start the HTTP request. Pool should stall.
14746 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1614747 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2014748 ASSERT_EQ(ERR_IO_PENDING,
14749 http_trans.Start(&http_request, http_callback.callback(),
14750 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4114751 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214752
14753 // The SSL connection will automatically be closed once the connection is
14754 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0114755 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5214756 std::string response_data;
bnc691fda62016-08-12 00:43:1614757 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5214758 EXPECT_EQ("falafel", response_data);
14759
dcheng48459ac22014-08-26 00:46:4114760 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214761}
14762
bncd16676a2016-07-20 16:23:0114763TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0914764 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2214765 element_readers.push_back(
ricea2deef682016-09-09 08:04:0714766 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2214767 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5414768
14769 HttpRequestInfo request;
14770 request.method = "POST";
14771 request.url = GURL("http://www.foo.com/");
14772 request.upload_data_stream = &upload_data_stream;
14773 request.load_flags = 0;
14774
danakj1fd259a02016-04-16 03:17:0914775 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5414777 // Send headers successfully, but get an error while sending the body.
14778 MockWrite data_writes[] = {
14779 MockWrite("POST / HTTP/1.1\r\n"
14780 "Host: www.foo.com\r\n"
14781 "Connection: keep-alive\r\n"
14782 "Content-Length: 3\r\n\r\n"),
14783 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14784 };
14785
14786 MockRead data_reads[] = {
14787 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14788 MockRead("hello world"),
14789 MockRead(SYNCHRONOUS, OK),
14790 };
14791 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14792 arraysize(data_writes));
14793 session_deps_.socket_factory->AddSocketDataProvider(&data);
14794
14795 TestCompletionCallback callback;
14796
tfarina42834112016-09-22 13:38:2014797 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5414799
14800 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114801 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5414802
bnc691fda62016-08-12 00:43:1614803 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214804 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5414805
wezca1070932016-05-26 20:30:5214806 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5414807 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14808
14809 std::string response_data;
bnc691fda62016-08-12 00:43:1614810 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0114811 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5414812 EXPECT_EQ("hello world", response_data);
14813}
14814
14815// This test makes sure the retry logic doesn't trigger when reading an error
14816// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0114817TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5414818 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0914819 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414820 MockWrite data_writes[] = {
14821 MockWrite("GET / HTTP/1.1\r\n"
14822 "Host: www.foo.com\r\n"
14823 "Connection: keep-alive\r\n\r\n"),
14824 MockWrite("POST / HTTP/1.1\r\n"
14825 "Host: www.foo.com\r\n"
14826 "Connection: keep-alive\r\n"
14827 "Content-Length: 3\r\n\r\n"),
14828 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14829 };
14830
14831 MockRead data_reads[] = {
14832 MockRead("HTTP/1.1 200 Peachy\r\n"
14833 "Content-Length: 14\r\n\r\n"),
14834 MockRead("first response"),
14835 MockRead("HTTP/1.1 400 Not OK\r\n"
14836 "Content-Length: 15\r\n\r\n"),
14837 MockRead("second response"),
14838 MockRead(SYNCHRONOUS, OK),
14839 };
14840 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14841 arraysize(data_writes));
14842 session_deps_.socket_factory->AddSocketDataProvider(&data);
14843
14844 TestCompletionCallback callback;
14845 HttpRequestInfo request1;
14846 request1.method = "GET";
14847 request1.url = GURL("http://www.foo.com/");
14848 request1.load_flags = 0;
14849
bnc691fda62016-08-12 00:43:1614850 std::unique_ptr<HttpNetworkTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4114851 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:2014852 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5414854
14855 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114856 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5414857
14858 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5214859 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5414860
wezca1070932016-05-26 20:30:5214861 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5414862 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
14863
14864 std::string response_data1;
14865 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0114866 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5414867 EXPECT_EQ("first response", response_data1);
14868 // Delete the transaction to release the socket back into the socket pool.
14869 trans1.reset();
14870
danakj1fd259a02016-04-16 03:17:0914871 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2214872 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0914873 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2214874 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5414875
14876 HttpRequestInfo request2;
14877 request2.method = "POST";
14878 request2.url = GURL("http://www.foo.com/");
14879 request2.upload_data_stream = &upload_data_stream;
14880 request2.load_flags = 0;
14881
bnc691fda62016-08-12 00:43:1614882 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2014883 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5414885
14886 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114887 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5414888
bnc691fda62016-08-12 00:43:1614889 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214890 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5414891
wezca1070932016-05-26 20:30:5214892 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5414893 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
14894
14895 std::string response_data2;
bnc691fda62016-08-12 00:43:1614896 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0114897 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5414898 EXPECT_EQ("second response", response_data2);
14899}
14900
bncd16676a2016-07-20 16:23:0114901TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5414902 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0914903 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2214904 element_readers.push_back(
ricea2deef682016-09-09 08:04:0714905 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2214906 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5414907
14908 HttpRequestInfo request;
14909 request.method = "POST";
14910 request.url = GURL("http://www.foo.com/");
14911 request.upload_data_stream = &upload_data_stream;
14912 request.load_flags = 0;
14913
danakj1fd259a02016-04-16 03:17:0914914 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614915 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5414916 // Send headers successfully, but get an error while sending the body.
14917 MockWrite data_writes[] = {
14918 MockWrite("POST / HTTP/1.1\r\n"
14919 "Host: www.foo.com\r\n"
14920 "Connection: keep-alive\r\n"
14921 "Content-Length: 3\r\n\r\n"
14922 "fo"),
14923 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14924 };
14925
14926 MockRead data_reads[] = {
14927 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14928 MockRead("hello world"),
14929 MockRead(SYNCHRONOUS, OK),
14930 };
14931 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14932 arraysize(data_writes));
14933 session_deps_.socket_factory->AddSocketDataProvider(&data);
14934
14935 TestCompletionCallback callback;
14936
tfarina42834112016-09-22 13:38:2014937 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114938 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5414939
14940 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114941 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5414942
bnc691fda62016-08-12 00:43:1614943 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214944 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5414945
wezca1070932016-05-26 20:30:5214946 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5414947 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14948
14949 std::string response_data;
bnc691fda62016-08-12 00:43:1614950 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0114951 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5414952 EXPECT_EQ("hello world", response_data);
14953}
14954
14955// This tests the more common case than the previous test, where headers and
14956// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0114957TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0714958 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5414959
14960 HttpRequestInfo request;
14961 request.method = "POST";
14962 request.url = GURL("http://www.foo.com/");
14963 request.upload_data_stream = &upload_data_stream;
14964 request.load_flags = 0;
14965
danakj1fd259a02016-04-16 03:17:0914966 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614967 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5414968 // Send headers successfully, but get an error while sending the body.
14969 MockWrite data_writes[] = {
14970 MockWrite("POST / HTTP/1.1\r\n"
14971 "Host: www.foo.com\r\n"
14972 "Connection: keep-alive\r\n"
14973 "Transfer-Encoding: chunked\r\n\r\n"),
14974 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14975 };
14976
14977 MockRead data_reads[] = {
14978 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14979 MockRead("hello world"),
14980 MockRead(SYNCHRONOUS, OK),
14981 };
14982 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14983 arraysize(data_writes));
14984 session_deps_.socket_factory->AddSocketDataProvider(&data);
14985
14986 TestCompletionCallback callback;
14987
tfarina42834112016-09-22 13:38:2014988 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114989 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5414990 // Make sure the headers are sent before adding a chunk. This ensures that
14991 // they can't be merged with the body in a single send. Not currently
14992 // necessary since a chunked body is never merged with headers, but this makes
14993 // the test more future proof.
14994 base::RunLoop().RunUntilIdle();
14995
mmenkecbc2b712014-10-09 20:29:0714996 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5414997
14998 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114999 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415000
bnc691fda62016-08-12 00:43:1615001 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215002 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415003
wezca1070932016-05-26 20:30:5215004 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415005 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15006
15007 std::string response_data;
bnc691fda62016-08-12 00:43:1615008 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115009 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415010 EXPECT_EQ("hello world", response_data);
15011}
15012
bncd16676a2016-07-20 16:23:0115013TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915014 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215015 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715016 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215017 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415018
15019 HttpRequestInfo request;
15020 request.method = "POST";
15021 request.url = GURL("http://www.foo.com/");
15022 request.upload_data_stream = &upload_data_stream;
15023 request.load_flags = 0;
15024
danakj1fd259a02016-04-16 03:17:0915025 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615026 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415027
15028 MockWrite data_writes[] = {
15029 MockWrite("POST / HTTP/1.1\r\n"
15030 "Host: www.foo.com\r\n"
15031 "Connection: keep-alive\r\n"
15032 "Content-Length: 3\r\n\r\n"),
15033 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15034 };
15035
15036 MockRead data_reads[] = {
15037 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15038 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15039 MockRead("hello world"),
15040 MockRead(SYNCHRONOUS, OK),
15041 };
15042 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15043 arraysize(data_writes));
15044 session_deps_.socket_factory->AddSocketDataProvider(&data);
15045
15046 TestCompletionCallback callback;
15047
tfarina42834112016-09-22 13:38:2015048 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115049 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415050
15051 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115052 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415053
bnc691fda62016-08-12 00:43:1615054 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215055 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415056
wezca1070932016-05-26 20:30:5215057 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415058 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15059
15060 std::string response_data;
bnc691fda62016-08-12 00:43:1615061 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115062 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415063 EXPECT_EQ("hello world", response_data);
15064}
15065
bncd16676a2016-07-20 16:23:0115066TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915067 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215068 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715069 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215070 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415071
15072 HttpRequestInfo request;
15073 request.method = "POST";
15074 request.url = GURL("http://www.foo.com/");
15075 request.upload_data_stream = &upload_data_stream;
15076 request.load_flags = 0;
15077
danakj1fd259a02016-04-16 03:17:0915078 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615079 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415080 // Send headers successfully, but get an error while sending the body.
15081 MockWrite data_writes[] = {
15082 MockWrite("POST / HTTP/1.1\r\n"
15083 "Host: www.foo.com\r\n"
15084 "Connection: keep-alive\r\n"
15085 "Content-Length: 3\r\n\r\n"),
15086 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15087 };
15088
15089 MockRead data_reads[] = {
15090 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15091 MockRead("hello world"),
15092 MockRead(SYNCHRONOUS, OK),
15093 };
15094 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15095 arraysize(data_writes));
15096 session_deps_.socket_factory->AddSocketDataProvider(&data);
15097
15098 TestCompletionCallback callback;
15099
tfarina42834112016-09-22 13:38:2015100 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115101 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415102
15103 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115104 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415105}
15106
bncd16676a2016-07-20 16:23:0115107TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415108 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915109 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215110 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715111 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215112 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415113
15114 HttpRequestInfo request;
15115 request.method = "POST";
15116 request.url = GURL("http://www.foo.com/");
15117 request.upload_data_stream = &upload_data_stream;
15118 request.load_flags = 0;
15119
danakj1fd259a02016-04-16 03:17:0915120 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615121 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415122 // Send headers successfully, but get an error while sending the body.
15123 MockWrite data_writes[] = {
15124 MockWrite("POST / HTTP/1.1\r\n"
15125 "Host: www.foo.com\r\n"
15126 "Connection: keep-alive\r\n"
15127 "Content-Length: 3\r\n\r\n"),
15128 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15129 };
15130
15131 MockRead data_reads[] = {
15132 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15133 MockRead("HTTP/1.0 302 Redirect\r\n"),
15134 MockRead("Location: http://somewhere-else.com/\r\n"),
15135 MockRead("Content-Length: 0\r\n\r\n"),
15136 MockRead(SYNCHRONOUS, OK),
15137 };
15138 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15139 arraysize(data_writes));
15140 session_deps_.socket_factory->AddSocketDataProvider(&data);
15141
15142 TestCompletionCallback callback;
15143
tfarina42834112016-09-22 13:38:2015144 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115145 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415146
15147 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115148 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415149}
15150
bncd16676a2016-07-20 16:23:0115151TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915152 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215153 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715154 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215155 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415156
15157 HttpRequestInfo request;
15158 request.method = "POST";
15159 request.url = GURL("http://www.foo.com/");
15160 request.upload_data_stream = &upload_data_stream;
15161 request.load_flags = 0;
15162
danakj1fd259a02016-04-16 03:17:0915163 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615164 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415165 // Send headers successfully, but get an error while sending the body.
15166 MockWrite data_writes[] = {
15167 MockWrite("POST / HTTP/1.1\r\n"
15168 "Host: www.foo.com\r\n"
15169 "Connection: keep-alive\r\n"
15170 "Content-Length: 3\r\n\r\n"),
15171 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15172 };
15173
15174 MockRead data_reads[] = {
15175 MockRead("HTTP 0.9 rocks!"),
15176 MockRead(SYNCHRONOUS, OK),
15177 };
15178 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15179 arraysize(data_writes));
15180 session_deps_.socket_factory->AddSocketDataProvider(&data);
15181
15182 TestCompletionCallback callback;
15183
tfarina42834112016-09-22 13:38:2015184 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115185 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415186
15187 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115188 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415189}
15190
bncd16676a2016-07-20 16:23:0115191TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0915192 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215193 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715194 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215195 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415196
15197 HttpRequestInfo request;
15198 request.method = "POST";
15199 request.url = GURL("http://www.foo.com/");
15200 request.upload_data_stream = &upload_data_stream;
15201 request.load_flags = 0;
15202
danakj1fd259a02016-04-16 03:17:0915203 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615204 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415205 // Send headers successfully, but get an error while sending the body.
15206 MockWrite data_writes[] = {
15207 MockWrite("POST / HTTP/1.1\r\n"
15208 "Host: www.foo.com\r\n"
15209 "Connection: keep-alive\r\n"
15210 "Content-Length: 3\r\n\r\n"),
15211 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15212 };
15213
15214 MockRead data_reads[] = {
15215 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15216 MockRead(SYNCHRONOUS, OK),
15217 };
15218 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15219 arraysize(data_writes));
15220 session_deps_.socket_factory->AddSocketDataProvider(&data);
15221
15222 TestCompletionCallback callback;
15223
tfarina42834112016-09-22 13:38:2015224 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115225 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415226
15227 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115228 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415229}
15230
Adam Rice425cf122015-01-19 06:18:2415231// Verify that proxy headers are not sent to the destination server when
15232// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0115233TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2415234 HttpRequestInfo request;
15235 request.method = "GET";
bncce36dca22015-04-21 22:11:2315236 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415237 AddWebSocketHeaders(&request.extra_headers);
15238
15239 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315240 session_deps_.proxy_service =
15241 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415242
danakj1fd259a02016-04-16 03:17:0915243 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415244
15245 // Since a proxy is configured, try to establish a tunnel.
15246 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1715247 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15248 "Host: www.example.org:443\r\n"
15249 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415250
15251 // After calling trans->RestartWithAuth(), this is the request we should
15252 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1715253 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15254 "Host: www.example.org:443\r\n"
15255 "Proxy-Connection: keep-alive\r\n"
15256 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415257
rsleevidb16bb02015-11-12 23:47:1715258 MockWrite("GET / HTTP/1.1\r\n"
15259 "Host: www.example.org\r\n"
15260 "Connection: Upgrade\r\n"
15261 "Upgrade: websocket\r\n"
15262 "Origin: http://www.example.org\r\n"
15263 "Sec-WebSocket-Version: 13\r\n"
15264 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415265 };
15266
15267 // The proxy responds to the connect with a 407, using a persistent
15268 // connection.
15269 MockRead data_reads[] = {
15270 // No credentials.
15271 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15272 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415273 MockRead("Content-Length: 0\r\n"),
15274 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415275
15276 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15277
15278 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15279 MockRead("Upgrade: websocket\r\n"),
15280 MockRead("Connection: Upgrade\r\n"),
15281 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15282 };
15283
15284 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15285 arraysize(data_writes));
15286 session_deps_.socket_factory->AddSocketDataProvider(&data);
15287 SSLSocketDataProvider ssl(ASYNC, OK);
15288 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15289
bnc691fda62016-08-12 00:43:1615290 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415291 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15292 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15293 trans->SetWebSocketHandshakeStreamCreateHelper(
15294 &websocket_stream_create_helper);
15295
15296 {
15297 TestCompletionCallback callback;
15298
tfarina42834112016-09-22 13:38:2015299 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115300 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2415301
15302 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115303 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2415304 }
15305
15306 const HttpResponseInfo* response = trans->GetResponseInfo();
15307 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215308 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415309 EXPECT_EQ(407, response->headers->response_code());
15310
15311 {
15312 TestCompletionCallback callback;
15313
15314 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15315 callback.callback());
robpercival214763f2016-07-01 23:27:0115316 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2415317
15318 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115319 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2415320 }
15321
15322 response = trans->GetResponseInfo();
15323 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215324 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415325
15326 EXPECT_EQ(101, response->headers->response_code());
15327
15328 trans.reset();
15329 session->CloseAllConnections();
15330}
15331
15332// Verify that proxy headers are not sent to the destination server when
15333// establishing a tunnel for an insecure WebSocket connection.
15334// This requires the authentication info to be injected into the auth cache
15335// due to crbug.com/395064
15336// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0115337TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2415338 HttpRequestInfo request;
15339 request.method = "GET";
bncce36dca22015-04-21 22:11:2315340 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415341 AddWebSocketHeaders(&request.extra_headers);
15342
15343 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315344 session_deps_.proxy_service =
15345 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415346
danakj1fd259a02016-04-16 03:17:0915347 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415348
15349 MockWrite data_writes[] = {
15350 // Try to establish a tunnel for the WebSocket connection, with
15351 // credentials. Because WebSockets have a separate set of socket pools,
15352 // they cannot and will not use the same TCP/IP connection as the
15353 // preflight HTTP request.
15354 MockWrite(
bncce36dca22015-04-21 22:11:2315355 "CONNECT www.example.org:80 HTTP/1.1\r\n"
15356 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2415357 "Proxy-Connection: keep-alive\r\n"
15358 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15359
15360 MockWrite(
15361 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315362 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415363 "Connection: Upgrade\r\n"
15364 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315365 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415366 "Sec-WebSocket-Version: 13\r\n"
15367 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
15368 };
15369
15370 MockRead data_reads[] = {
15371 // HTTP CONNECT with credentials.
15372 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15373
15374 // WebSocket connection established inside tunnel.
15375 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15376 MockRead("Upgrade: websocket\r\n"),
15377 MockRead("Connection: Upgrade\r\n"),
15378 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15379 };
15380
15381 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15382 arraysize(data_writes));
15383 session_deps_.socket_factory->AddSocketDataProvider(&data);
15384
15385 session->http_auth_cache()->Add(
15386 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
15387 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
15388
bnc691fda62016-08-12 00:43:1615389 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415390 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15391 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15392 trans->SetWebSocketHandshakeStreamCreateHelper(
15393 &websocket_stream_create_helper);
15394
15395 TestCompletionCallback callback;
15396
tfarina42834112016-09-22 13:38:2015397 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115398 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2415399
15400 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115401 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2415402
15403 const HttpResponseInfo* response = trans->GetResponseInfo();
15404 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215405 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415406
15407 EXPECT_EQ(101, response->headers->response_code());
15408
15409 trans.reset();
15410 session->CloseAllConnections();
15411}
15412
bncd16676a2016-07-20 16:23:0115413TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0915414 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215415 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715416 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215417 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215418
15419 HttpRequestInfo request;
15420 request.method = "POST";
15421 request.url = GURL("http://www.foo.com/");
15422 request.upload_data_stream = &upload_data_stream;
15423
danakj1fd259a02016-04-16 03:17:0915424 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615425 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2215426 MockWrite data_writes[] = {
15427 MockWrite("POST / HTTP/1.1\r\n"
15428 "Host: www.foo.com\r\n"
15429 "Connection: keep-alive\r\n"
15430 "Content-Length: 3\r\n\r\n"),
15431 MockWrite("foo"),
15432 };
15433
15434 MockRead data_reads[] = {
15435 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15436 MockRead(SYNCHRONOUS, OK),
15437 };
15438 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15439 arraysize(data_writes));
15440 session_deps_.socket_factory->AddSocketDataProvider(&data);
15441
15442 TestCompletionCallback callback;
15443
15444 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015445 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115446 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2215447
15448 std::string response_data;
bnc691fda62016-08-12 00:43:1615449 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2215450
15451 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1615452 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2215453 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1615454 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2215455}
15456
bncd16676a2016-07-20 16:23:0115457TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0915458 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215459 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715460 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215461 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215462
15463 HttpRequestInfo request;
15464 request.method = "POST";
15465 request.url = GURL("http://www.foo.com/");
15466 request.upload_data_stream = &upload_data_stream;
15467
danakj1fd259a02016-04-16 03:17:0915468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615469 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2215470 MockWrite data_writes[] = {
15471 MockWrite("POST / HTTP/1.1\r\n"
15472 "Host: www.foo.com\r\n"
15473 "Connection: keep-alive\r\n"
15474 "Content-Length: 3\r\n\r\n"),
15475 MockWrite("foo"),
15476 };
15477
15478 MockRead data_reads[] = {
15479 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
15480 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15481 MockRead(SYNCHRONOUS, OK),
15482 };
15483 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15484 arraysize(data_writes));
15485 session_deps_.socket_factory->AddSocketDataProvider(&data);
15486
15487 TestCompletionCallback callback;
15488
15489 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015490 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115491 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2215492
15493 std::string response_data;
bnc691fda62016-08-12 00:43:1615494 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2215495
15496 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1615497 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2215498 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1615499 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2215500}
15501
bncd16676a2016-07-20 16:23:0115502TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2215503 ChunkedUploadDataStream upload_data_stream(0);
15504
15505 HttpRequestInfo request;
15506 request.method = "POST";
15507 request.url = GURL("http://www.foo.com/");
15508 request.upload_data_stream = &upload_data_stream;
15509
danakj1fd259a02016-04-16 03:17:0915510 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615511 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2215512 // Send headers successfully, but get an error while sending the body.
15513 MockWrite data_writes[] = {
15514 MockWrite("POST / HTTP/1.1\r\n"
15515 "Host: www.foo.com\r\n"
15516 "Connection: keep-alive\r\n"
15517 "Transfer-Encoding: chunked\r\n\r\n"),
15518 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
15519 };
15520
15521 MockRead data_reads[] = {
15522 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15523 MockRead(SYNCHRONOUS, OK),
15524 };
15525 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15526 arraysize(data_writes));
15527 session_deps_.socket_factory->AddSocketDataProvider(&data);
15528
15529 TestCompletionCallback callback;
15530
15531 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015532 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2215533
15534 base::RunLoop().RunUntilIdle();
15535 upload_data_stream.AppendData("f", 1, false);
15536
15537 base::RunLoop().RunUntilIdle();
15538 upload_data_stream.AppendData("oo", 2, true);
15539
robpercival214763f2016-07-01 23:27:0115540 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2215541
15542 std::string response_data;
bnc691fda62016-08-12 00:43:1615543 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2215544
15545 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1615546 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2215547 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1615548 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2215549}
15550
nharperb7441ef2016-01-25 23:54:1415551#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0115552TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1415553 const std::string https_url = "https://www.example.com";
15554 HttpRequestInfo request;
15555 request.url = GURL(https_url);
15556 request.method = "GET";
15557
15558 SSLSocketDataProvider ssl(ASYNC, OK);
15559 ssl.token_binding_negotiated = true;
15560 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3615561 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1415562 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15563
bnc42331402016-07-25 13:36:1515564 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4115565 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
15566 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1415567 MockRead(ASYNC, ERR_IO_PENDING)};
15568 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
15569 session_deps_.socket_factory->AddSocketDataProvider(&data);
15570 session_deps_.channel_id_service.reset(new ChannelIDService(
15571 new DefaultChannelIDStore(nullptr), base::ThreadTaskRunnerHandle::Get()));
danakj1fd259a02016-04-16 03:17:0915572 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1415573
15574 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15575 TestCompletionCallback callback;
15576 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015577 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515578 base::RunLoop().RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1415579
15580 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
15581 HttpRequestHeaders headers;
15582 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
15583 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
15584}
15585#endif // !defined(OS_IOS)
15586
[email protected]89ceba9a2009-03-21 03:46:0615587} // namespace net