blob: 20ea0d411e55d66cfd97fa7c47d90991d64a1144 [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
sclittlebe1ccf62015-09-02 19:40:369#include <stdint.h>
10
[email protected]5285d972011-10-18 18:56:3411#include <string>
[email protected]95d88ffe2010-02-04 21:25:3312#include <vector>
[email protected]77848d12008-11-14 00:00:2213
[email protected]2d731a32010-04-29 01:04:0614#include "base/basictypes.h"
[email protected]68bf9152008-09-25 19:47:3015#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5216#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2917#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5718#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2419#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1520#include "base/memory/scoped_ptr.h"
[email protected]bf828982013-08-14 18:01:4721#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4922#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4723#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0524#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3325#include "base/test/test_file_util.h"
skyostil4891b25b2015-06-11 11:43:4526#include "base/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3527#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0728#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3329#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0730#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2531#include "net/base/load_timing_info.h"
32#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2433#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3134#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5235#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4036#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0637#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2138#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1139#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1640#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5341#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2442#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1243#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0044#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2945#include "net/http/http_auth_handler_ntlm.h"
Adam Rice425cf122015-01-19 06:18:2446#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5747#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5248#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5649#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2450#include "net/http/http_request_headers.h"
[email protected]17291a022011-10-10 07:32:5351#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5752#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3853#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2454#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1955#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0756#include "net/log/net_log.h"
vishal.b62985ca92015-04-17 08:45:5157#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4658#include "net/log/test_net_log_entry.h"
59#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1360#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5361#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0362#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1163#include "net/proxy/proxy_resolver.h"
64#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4465#include "net/socket/client_socket_factory.h"
[email protected]483fa202013-05-14 01:07:0366#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4767#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0268#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0769#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4470#include "net/socket/socket_test_util.h"
71#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5472#include "net/spdy/spdy_framer.h"
73#include "net/spdy/spdy_session.h"
74#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0275#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5776#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0377#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5778#include "net/ssl/ssl_config_service_defaults.h"
79#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5480#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1181#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4482#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:1883#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:5284#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1585#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2786#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5287
[email protected]ad65a3e2013-12-25 18:18:0188using base::ASCIIToUTF16;
89
initial.commit586acc5fe2008-07-26 22:42:5290//-----------------------------------------------------------------------------
91
ttuttle859dc7a2015-04-23 19:42:2992namespace net {
93
[email protected]13c8a092010-07-29 06:15:4494namespace {
95
rdsmithebb50aa2015-11-12 03:44:3896enum TestCase {
97 // Test using the SPDY/3.1 protocol.
98 kTestCaseSPDY31,
99
100 // Test using the HTTP/2 protocol, without specifying a stream
101 // dependency based on the RequestPriority.
102 kTestCaseHTTP2NoPriorityDependencies,
103
104 // Test using the HTTP/2 protocol, specifying a stream
105 // dependency based on the RequestPriority.
106 kTestCaseHTTP2PriorityDependencies
107};
108
[email protected]42cba2fb2013-03-29 19:58:57109const base::string16 kBar(ASCIIToUTF16("bar"));
110const base::string16 kBar2(ASCIIToUTF16("bar2"));
111const base::string16 kBar3(ASCIIToUTF16("bar3"));
112const base::string16 kBaz(ASCIIToUTF16("baz"));
113const base::string16 kFirst(ASCIIToUTF16("first"));
114const base::string16 kFoo(ASCIIToUTF16("foo"));
115const base::string16 kFoo2(ASCIIToUTF16("foo2"));
116const base::string16 kFoo3(ASCIIToUTF16("foo3"));
117const base::string16 kFou(ASCIIToUTF16("fou"));
118const base::string16 kSecond(ASCIIToUTF16("second"));
119const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
120const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44121
ttuttle859dc7a2015-04-23 19:42:29122int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
123 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
124 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02125}
126
ttuttle859dc7a2015-04-23 19:42:29127int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
128 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
129 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02130}
131
ttuttle859dc7a2015-04-23 19:42:29132bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
133 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
134 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52135}
136
[email protected]f3da152d2012-06-02 01:00:57137// Takes in a Value created from a NetLogHttpResponseParameter, and returns
138// a JSONified list of headers as a single string. Uses single quotes instead
139// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27140bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57141 if (!params)
142 return false;
[email protected]ea5ef4c2013-06-13 22:50:27143 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57144 if (!params->GetList("headers", &header_list))
145 return false;
146 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34147 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28148 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57149 return true;
150}
151
[email protected]029c83b62013-01-24 05:28:20152// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
153// used.
ttuttle859dc7a2015-04-23 19:42:29154void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20155 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29156 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25157
[email protected]029c83b62013-01-24 05:28:20158 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
159 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
160
ttuttle859dc7a2015-04-23 19:42:29161 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20162 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25163
164 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25165
[email protected]3b23a222013-05-15 21:33:25166 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25167 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
168 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25169 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25170}
171
[email protected]029c83b62013-01-24 05:28:20172// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
173// used.
ttuttle859dc7a2015-04-23 19:42:29174void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25175 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20176 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29177 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20178
179 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
180 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
181
ttuttle859dc7a2015-04-23 19:42:29182 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
183 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20184 EXPECT_LE(load_timing_info.connect_timing.connect_end,
185 load_timing_info.send_start);
186
187 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20188
[email protected]3b23a222013-05-15 21:33:25189 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20190 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
191 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25192 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20193}
194
195// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
196// used.
ttuttle859dc7a2015-04-23 19:42:29197void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20198 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29199 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20200
ttuttle859dc7a2015-04-23 19:42:29201 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20202
203 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
204 EXPECT_LE(load_timing_info.proxy_resolve_start,
205 load_timing_info.proxy_resolve_end);
206 EXPECT_LE(load_timing_info.proxy_resolve_end,
207 load_timing_info.send_start);
208 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20209
[email protected]3b23a222013-05-15 21:33:25210 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20211 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
212 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25213 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20214}
215
216// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
217// used.
ttuttle859dc7a2015-04-23 19:42:29218void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20219 int connect_timing_flags) {
220 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29221 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20222
223 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
224 EXPECT_LE(load_timing_info.proxy_resolve_start,
225 load_timing_info.proxy_resolve_end);
226 EXPECT_LE(load_timing_info.proxy_resolve_end,
227 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29228 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
229 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20230 EXPECT_LE(load_timing_info.connect_timing.connect_end,
231 load_timing_info.send_start);
232
233 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20234
[email protected]3b23a222013-05-15 21:33:25235 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20236 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
237 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25238 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25239}
240
ttuttle859dc7a2015-04-23 19:42:29241void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24242 headers->SetHeader("Connection", "Upgrade");
243 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23244 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24245 headers->SetHeader("Sec-WebSocket-Version", "13");
246 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
247}
248
mmenkee65e7af2015-10-13 17:16:42249scoped_ptr<HttpNetworkSession> CreateSession(
250 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34251 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14252}
253
[email protected]448d4ca52012-03-04 04:12:23254} // namespace
255
[email protected]23e482282013-06-14 16:08:02256class HttpNetworkTransactionTest
257 : public PlatformTest,
rdsmithebb50aa2015-11-12 03:44:38258 public ::testing::WithParamInterface<TestCase> {
[email protected]483fa202013-05-14 01:07:03259 public:
[email protected]23e482282013-06-14 16:08:02260 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03261 // Important to restore the per-pool limit first, since the pool limit must
262 // always be greater than group limit, and the tests reduce both limits.
263 ClientSocketPoolManager::set_max_sockets_per_pool(
264 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
265 ClientSocketPoolManager::set_max_sockets_per_group(
266 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
rdsmithebb50aa2015-11-12 03:44:38267 SpdySession::SetPriorityDependencyDefaultForTesting(false);
[email protected]483fa202013-05-14 01:07:03268 }
269
[email protected]e3ceb682011-06-28 23:55:46270 protected:
[email protected]23e482282013-06-14 16:08:02271 HttpNetworkTransactionTest()
rdsmithebb50aa2015-11-12 03:44:38272 : spdy_util_(GetProtocol(), GetDependenciesFromPriority()),
273 session_deps_(GetProtocol()),
[email protected]483fa202013-05-14 01:07:03274 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
275 HttpNetworkSession::NORMAL_SOCKET_POOL)),
276 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
277 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
rdsmithebb50aa2015-11-12 03:44:38278 SpdySession::SetPriorityDependencyDefaultForTesting(
279 GetDependenciesFromPriority());
[email protected]483fa202013-05-14 01:07:03280 }
[email protected]bb88e1d32013-05-03 23:11:07281
[email protected]e3ceb682011-06-28 23:55:46282 struct SimpleGetHelperResult {
283 int rv;
284 std::string status_line;
285 std::string response_data;
sclittlefb249892015-09-10 21:33:22286 int64_t total_received_bytes;
287 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25288 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47289 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59290 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46291 };
292
dcheng67be2b1f2014-10-27 21:47:29293 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50294 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34295 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54296 }
297
dcheng67be2b1f2014-10-27 21:47:29298 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50299 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34300 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09301 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34302 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09303 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50304 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34305 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09306 }
307
rdsmithebb50aa2015-11-12 03:44:38308 NextProto GetProtocol() const {
309 return GetParam() == kTestCaseSPDY31 ? kProtoSPDY31 : kProtoHTTP2;
310 }
311
312 bool GetDependenciesFromPriority() const {
313 return GetParam() == kTestCaseHTTP2PriorityDependencies;
314 }
315
bnc33b8cef42014-11-19 17:30:38316 const char* GetAlternateProtocolFromParam() {
rdsmithebb50aa2015-11-12 03:44:38317 return AlternateProtocolToString(
318 AlternateProtocolFromNextProto(GetProtocol()));
bnc33b8cef42014-11-19 17:30:38319 }
320
bncc958faa2015-07-31 18:14:52321 std::string GetAlternativeServiceHttpHeader() {
322 return std::string("Alt-Svc: ") + GetAlternateProtocolFromParam() +
323 "=\"www.example.com:443\"\r\n";
324 }
325
[email protected]8a0fc822013-06-27 20:52:43326 std::string GetAlternateProtocolHttpHeader() {
bnc33b8cef42014-11-19 17:30:38327 return std::string("Alternate-Protocol: 443:") +
bncc958faa2015-07-31 18:14:52328 GetAlternateProtocolFromParam() + "\r\n";
[email protected]8a0fc822013-06-27 20:52:43329 }
330
[email protected]202965992011-12-07 23:04:51331 // Either |write_failure| specifies a write failure or |read_failure|
332 // specifies a read failure when using a reused socket. In either case, the
333 // failure should cause the network transaction to resend the request, and the
334 // other argument should be NULL.
335 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
336 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52337
[email protected]a34f61ee2014-03-18 20:59:49338 // Either |write_failure| specifies a write failure or |read_failure|
339 // specifies a read failure when using a reused socket. In either case, the
340 // failure should cause the network transaction to resend the request, and the
341 // other argument should be NULL.
342 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10343 const MockRead* read_failure,
344 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49345
[email protected]5a60c8b2011-10-19 20:14:29346 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
347 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15348 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52349
[email protected]ff007e162009-05-23 09:13:15350 HttpRequestInfo request;
351 request.method = "GET";
bncce36dca22015-04-21 22:11:23352 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15353 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52354
vishal.b62985ca92015-04-17 08:45:51355 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07356 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:42357 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27358 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41359 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27360
[email protected]5a60c8b2011-10-19 20:14:29361 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07362 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29363 }
initial.commit586acc5fe2008-07-26 22:42:52364
[email protected]49639fa2011-12-20 23:22:41365 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52366
eroman24bc6a12015-05-06 19:55:48367 EXPECT_TRUE(log.bound().IsCapturing());
[email protected]49639fa2011-12-20 23:22:41368 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15369 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52370
[email protected]ff007e162009-05-23 09:13:15371 out.rv = callback.WaitForResult();
sclittlefb249892015-09-10 21:33:22372 out.total_received_bytes = trans->GetTotalReceivedBytes();
373 out.total_sent_bytes = trans->GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25374
375 // Even in the failure cases that use this function, connections are always
376 // successfully established before the error.
377 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
378 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
379
[email protected]ff007e162009-05-23 09:13:15380 if (out.rv != OK)
381 return out;
382
383 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50384 // Can't use ASSERT_* inside helper functions like this, so
385 // return an error.
[email protected]90499482013-06-01 00:39:50386 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50387 out.rv = ERR_UNEXPECTED;
388 return out;
389 }
[email protected]ff007e162009-05-23 09:13:15390 out.status_line = response->headers->GetStatusLine();
391
[email protected]80a09a82012-11-16 17:40:06392 EXPECT_EQ("127.0.0.1", response->socket_address.host());
393 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19394
ttuttled9dbc652015-09-29 20:00:59395 bool got_endpoint =
396 trans->GetRemoteEndpoint(&out.remote_endpoint_after_start);
397 EXPECT_EQ(got_endpoint,
398 out.remote_endpoint_after_start.address().size() > 0);
399
[email protected]ff007e162009-05-23 09:13:15400 rv = ReadTransaction(trans.get(), &out.response_data);
401 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40402
mmenke43758e62015-05-04 21:09:46403 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40404 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39405 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40406 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12407 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39408 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40409 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39410 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
411 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15412
[email protected]f3da152d2012-06-02 01:00:57413 std::string line;
414 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
415 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
416
[email protected]79e1fd62013-06-20 06:50:04417 HttpRequestHeaders request_headers;
418 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
419 std::string value;
420 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23421 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04422 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
423 EXPECT_EQ("keep-alive", value);
424
425 std::string response_headers;
426 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23427 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04428 response_headers);
[email protected]3deb9a52010-11-11 00:24:40429
sclittlefb249892015-09-10 21:33:22430 out.total_received_bytes = trans->GetTotalReceivedBytes();
431 // The total number of sent bytes should not have changed.
432 EXPECT_EQ(out.total_sent_bytes, trans->GetTotalSentBytes());
433
ttuttle1f2d7e92015-04-28 16:17:47434 trans->GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47435 return out;
[email protected]ff007e162009-05-23 09:13:15436 }
initial.commit586acc5fe2008-07-26 22:42:52437
[email protected]5a60c8b2011-10-19 20:14:29438 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
439 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22440 MockWrite data_writes[] = {
441 MockWrite("GET / HTTP/1.1\r\n"
442 "Host: www.example.org\r\n"
443 "Connection: keep-alive\r\n\r\n"),
444 };
[email protected]5a60c8b2011-10-19 20:14:29445
sclittlefb249892015-09-10 21:33:22446 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
447 arraysize(data_writes));
448 StaticSocketDataProvider* data[] = {&reads};
449 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
450
451 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
452 out.total_sent_bytes);
453 return out;
[email protected]b8015c42013-12-24 15:18:19454 }
455
[email protected]ff007e162009-05-23 09:13:15456 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
457 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52458
[email protected]ff007e162009-05-23 09:13:15459 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07460
461 void BypassHostCacheOnRefreshHelper(int load_flags);
462
463 void CheckErrorIsPassedBack(int error, IoMode mode);
464
[email protected]4bd46222013-05-14 19:32:23465 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07466 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03467
468 // Original socket limits. Some tests set these. Safest to always restore
469 // them once each test has been run.
470 int old_max_group_sockets_;
471 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15472};
[email protected]231d5a32008-09-13 00:45:27473
rdsmithebb50aa2015-11-12 03:44:38474INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
bnc57685ae62015-03-10 21:27:20475 HttpNetworkTransactionTest,
rdsmithebb50aa2015-11-12 03:44:38476 testing::Values(kTestCaseSPDY31,
477 kTestCaseHTTP2NoPriorityDependencies,
478 kTestCaseHTTP2PriorityDependencies));
[email protected]23e482282013-06-14 16:08:02479
[email protected]448d4ca52012-03-04 04:12:23480namespace {
481
[email protected]1826a402014-01-08 15:40:48482class BeforeNetworkStartHandler {
483 public:
484 explicit BeforeNetworkStartHandler(bool defer)
485 : defer_on_before_network_start_(defer),
486 observed_before_network_start_(false) {}
487
488 void OnBeforeNetworkStart(bool* defer) {
489 *defer = defer_on_before_network_start_;
490 observed_before_network_start_ = true;
491 }
492
493 bool observed_before_network_start() const {
494 return observed_before_network_start_;
495 }
496
497 private:
498 const bool defer_on_before_network_start_;
499 bool observed_before_network_start_;
500
501 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
502};
503
[email protected]597a1ab2014-06-26 08:12:27504class BeforeProxyHeadersSentHandler {
505 public:
506 BeforeProxyHeadersSentHandler()
507 : observed_before_proxy_headers_sent_(false) {}
508
[email protected]1252d42f2014-07-01 21:20:20509 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
510 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27511 observed_before_proxy_headers_sent_ = true;
512 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
513 }
514
515 bool observed_before_proxy_headers_sent() const {
516 return observed_before_proxy_headers_sent_;
517 }
518
519 std::string observed_proxy_server_uri() const {
520 return observed_proxy_server_uri_;
521 }
522
523 private:
524 bool observed_before_proxy_headers_sent_;
525 std::string observed_proxy_server_uri_;
526
527 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
528};
529
[email protected]15a5ccf82008-10-23 19:57:43530// Fill |str| with a long header list that consumes >= |size| bytes.
531void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51532 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19533 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
534 const int sizeof_row = strlen(row);
535 const int num_rows = static_cast<int>(
536 ceil(static_cast<float>(size) / sizeof_row));
537 const int sizeof_data = num_rows * sizeof_row;
538 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43539 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51540
[email protected]4ddaf2502008-10-23 18:26:19541 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43542 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19543}
544
thakis84dff942015-07-28 20:47:38545#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29546// Alternative functions that eliminate randomness and dependency on the local
547// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20548void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29549 static const uint8 bytes[] = {
550 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
551 };
552 static size_t current_byte = 0;
553 for (size_t i = 0; i < n; ++i) {
554 output[i] = bytes[current_byte++];
555 current_byte %= arraysize(bytes);
556 }
557}
558
[email protected]fe2bc6a2009-03-23 16:52:20559void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29560 static const uint8 bytes[] = {
561 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
562 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
563 };
564 static size_t current_byte = 0;
565 for (size_t i = 0; i < n; ++i) {
566 output[i] = bytes[current_byte++];
567 current_byte %= arraysize(bytes);
568 }
569}
570
[email protected]fe2bc6a2009-03-23 16:52:20571std::string MockGetHostName() {
572 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29573}
thakis84dff942015-07-28 20:47:38574#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29575
[email protected]e60e47a2010-07-14 03:37:18576template<typename ParentPool>
577class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31578 public:
[email protected]9e1bdd32011-02-03 21:48:34579 CaptureGroupNameSocketPool(HostResolver* host_resolver,
580 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18581
[email protected]d80a4322009-08-14 07:07:49582 const std::string last_group_name_received() const {
583 return last_group_name_;
584 }
585
dmichaeld6e570d2014-12-18 22:30:57586 int RequestSocket(const std::string& group_name,
587 const void* socket_params,
588 RequestPriority priority,
589 ClientSocketHandle* handle,
590 const CompletionCallback& callback,
591 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31592 last_group_name_ = group_name;
593 return ERR_IO_PENDING;
594 }
dmichaeld6e570d2014-12-18 22:30:57595 void CancelRequest(const std::string& group_name,
596 ClientSocketHandle* handle) override {}
597 void ReleaseSocket(const std::string& group_name,
598 scoped_ptr<StreamSocket> socket,
599 int id) override {}
600 void CloseIdleSockets() override {}
601 int IdleSocketCount() const override { return 0; }
602 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31603 return 0;
604 }
dmichaeld6e570d2014-12-18 22:30:57605 LoadState GetLoadState(const std::string& group_name,
606 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31607 return LOAD_STATE_IDLE;
608 }
dmichaeld6e570d2014-12-18 22:30:57609 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26610 return base::TimeDelta();
611 }
[email protected]d80a4322009-08-14 07:07:49612
613 private:
[email protected]04e5be32009-06-26 20:00:31614 std::string last_group_name_;
615};
616
[email protected]ab739042011-04-07 15:22:28617typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
618CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13619typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
620CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06621typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11622CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18623typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
624CaptureGroupNameSSLSocketPool;
625
rkaplowd90695c2015-03-25 22:12:41626template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18627CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34628 HostResolver* host_resolver,
629 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41630 : ParentPool(0, 0, host_resolver, NULL, NULL) {
631}
[email protected]e60e47a2010-07-14 03:37:18632
hashimoto0d3e4fb2015-01-09 05:02:50633template <>
[email protected]2df19bb2010-08-25 20:13:46634CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21635 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34636 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41637 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50638}
[email protected]2df19bb2010-08-25 20:13:46639
[email protected]007b3f82013-04-09 08:46:45640template <>
[email protected]e60e47a2010-07-14 03:37:18641CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21642 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34643 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45644 : SSLClientSocketPool(0,
645 0,
[email protected]007b3f82013-04-09 08:46:45646 cert_verifier,
647 NULL,
648 NULL,
[email protected]284303b62013-11-28 15:11:54649 NULL,
eranm6571b2b2014-12-03 15:53:23650 NULL,
[email protected]007b3f82013-04-09 08:46:45651 std::string(),
652 NULL,
653 NULL,
654 NULL,
655 NULL,
656 NULL,
[email protected]8e458552014-08-05 00:02:15657 NULL) {
658}
[email protected]2227c692010-05-04 15:36:11659
[email protected]231d5a32008-09-13 00:45:27660//-----------------------------------------------------------------------------
661
[email protected]79cb5c12011-09-12 13:12:04662// Helper functions for validating that AuthChallengeInfo's are correctly
663// configured for common cases.
664bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
665 if (!auth_challenge)
666 return false;
667 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23668 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04669 EXPECT_EQ("MyRealm1", auth_challenge->realm);
670 EXPECT_EQ("basic", auth_challenge->scheme);
671 return true;
672}
673
674bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
675 if (!auth_challenge)
676 return false;
677 EXPECT_TRUE(auth_challenge->is_proxy);
678 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
679 EXPECT_EQ("MyRealm1", auth_challenge->realm);
680 EXPECT_EQ("basic", auth_challenge->scheme);
681 return true;
682}
683
684bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
685 if (!auth_challenge)
686 return false;
687 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23688 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04689 EXPECT_EQ("digestive", auth_challenge->realm);
690 EXPECT_EQ("digest", auth_challenge->scheme);
691 return true;
692}
693
thakis84dff942015-07-28 20:47:38694#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04695bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
696 if (!auth_challenge)
697 return false;
698 EXPECT_FALSE(auth_challenge->is_proxy);
699 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
700 EXPECT_EQ(std::string(), auth_challenge->realm);
701 EXPECT_EQ("ntlm", auth_challenge->scheme);
702 return true;
703}
thakis84dff942015-07-28 20:47:38704#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04705
[email protected]448d4ca52012-03-04 04:12:23706} // namespace
707
[email protected]23e482282013-06-14 16:08:02708TEST_P(HttpNetworkTransactionTest, Basic) {
mmenkee65e7af2015-10-13 17:16:42709 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40710 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41711 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27712}
713
[email protected]23e482282013-06-14 16:08:02714TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27715 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35716 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
717 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06718 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27719 };
[email protected]31a2bfe2010-02-09 08:03:39720 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
721 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42722 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27723 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
724 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22725 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
726 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47727 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59728
729 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27730}
731
732// Response with no status line.
[email protected]23e482282013-06-14 16:08:02733TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27734 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35735 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06736 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27737 };
[email protected]31a2bfe2010-02-09 08:03:39738 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
739 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42740 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27741 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
742 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22743 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
744 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27745}
746
747// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02748TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27749 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35750 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06751 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27752 };
[email protected]31a2bfe2010-02-09 08:03:39753 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
754 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42755 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27756 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
757 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22758 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
759 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27760}
761
762// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02763TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27764 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35765 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06766 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27767 };
[email protected]31a2bfe2010-02-09 08:03:39768 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
769 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42770 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27771 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
772 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22773 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
774 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27775}
776
777// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02778TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27779 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35780 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06781 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27782 };
[email protected]31a2bfe2010-02-09 08:03:39783 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
784 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42785 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25786 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
787 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
sclittlefb249892015-09-10 21:33:22788 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
789 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27790}
791
792// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02793TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27794 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35795 MockRead("\n"),
796 MockRead("\n"),
797 MockRead("Q"),
798 MockRead("J"),
799 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06800 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27801 };
[email protected]31a2bfe2010-02-09 08:03:39802 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
803 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42804 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27805 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
806 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22807 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
808 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27809}
810
811// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02812TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27813 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35814 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06815 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27816 };
[email protected]31a2bfe2010-02-09 08:03:39817 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
818 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42819 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27820 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
821 EXPECT_EQ("HTT", out.response_data);
sclittlefb249892015-09-10 21:33:22822 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
823 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52824}
825
[email protected]f9d44aa2008-09-23 23:57:17826// Simulate a 204 response, lacking a Content-Length header, sent over a
827// persistent connection. The response should still terminate since a 204
828// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02829TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19830 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17831 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35832 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19833 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06834 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17835 };
[email protected]31a2bfe2010-02-09 08:03:39836 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
837 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42838 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17839 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
840 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22841 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
842 int64_t response_size = reads_size - strlen(junk);
843 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17844}
845
[email protected]0877e3d2009-10-17 22:29:57846// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02847TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19848 std::string final_chunk = "0\r\n\r\n";
849 std::string extra_data = "HTTP/1.1 200 OK\r\n";
850 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57851 MockRead data_reads[] = {
852 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
853 MockRead("5\r\nHello\r\n"),
854 MockRead("1\r\n"),
855 MockRead(" \r\n"),
856 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19857 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06858 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57859 };
[email protected]31a2bfe2010-02-09 08:03:39860 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
861 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57862 EXPECT_EQ(OK, out.rv);
863 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
864 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22865 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
866 int64_t response_size = reads_size - extra_data.size();
867 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57868}
869
[email protected]9fe44f52010-09-23 18:36:00870// Next tests deal with http://crbug.com/56344.
871
[email protected]23e482282013-06-14 16:08:02872TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00873 MultipleContentLengthHeadersNoTransferEncoding) {
874 MockRead data_reads[] = {
875 MockRead("HTTP/1.1 200 OK\r\n"),
876 MockRead("Content-Length: 10\r\n"),
877 MockRead("Content-Length: 5\r\n\r\n"),
878 };
879 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
880 arraysize(data_reads));
881 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
882}
883
[email protected]23e482282013-06-14 16:08:02884TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04885 DuplicateContentLengthHeadersNoTransferEncoding) {
886 MockRead data_reads[] = {
887 MockRead("HTTP/1.1 200 OK\r\n"),
888 MockRead("Content-Length: 5\r\n"),
889 MockRead("Content-Length: 5\r\n\r\n"),
890 MockRead("Hello"),
891 };
892 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
893 arraysize(data_reads));
894 EXPECT_EQ(OK, out.rv);
895 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
896 EXPECT_EQ("Hello", out.response_data);
897}
898
[email protected]23e482282013-06-14 16:08:02899TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04900 ComplexContentLengthHeadersNoTransferEncoding) {
901 // More than 2 dupes.
902 {
903 MockRead data_reads[] = {
904 MockRead("HTTP/1.1 200 OK\r\n"),
905 MockRead("Content-Length: 5\r\n"),
906 MockRead("Content-Length: 5\r\n"),
907 MockRead("Content-Length: 5\r\n\r\n"),
908 MockRead("Hello"),
909 };
910 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
911 arraysize(data_reads));
912 EXPECT_EQ(OK, out.rv);
913 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
914 EXPECT_EQ("Hello", out.response_data);
915 }
916 // HTTP/1.0
917 {
918 MockRead data_reads[] = {
919 MockRead("HTTP/1.0 200 OK\r\n"),
920 MockRead("Content-Length: 5\r\n"),
921 MockRead("Content-Length: 5\r\n"),
922 MockRead("Content-Length: 5\r\n\r\n"),
923 MockRead("Hello"),
924 };
925 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
926 arraysize(data_reads));
927 EXPECT_EQ(OK, out.rv);
928 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
929 EXPECT_EQ("Hello", out.response_data);
930 }
931 // 2 dupes and one mismatched.
932 {
933 MockRead data_reads[] = {
934 MockRead("HTTP/1.1 200 OK\r\n"),
935 MockRead("Content-Length: 10\r\n"),
936 MockRead("Content-Length: 10\r\n"),
937 MockRead("Content-Length: 5\r\n\r\n"),
938 };
939 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
940 arraysize(data_reads));
941 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
942 }
943}
944
[email protected]23e482282013-06-14 16:08:02945TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00946 MultipleContentLengthHeadersTransferEncoding) {
947 MockRead data_reads[] = {
948 MockRead("HTTP/1.1 200 OK\r\n"),
949 MockRead("Content-Length: 666\r\n"),
950 MockRead("Content-Length: 1337\r\n"),
951 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
952 MockRead("5\r\nHello\r\n"),
953 MockRead("1\r\n"),
954 MockRead(" \r\n"),
955 MockRead("5\r\nworld\r\n"),
956 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06957 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00958 };
959 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
960 arraysize(data_reads));
961 EXPECT_EQ(OK, out.rv);
962 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
963 EXPECT_EQ("Hello world", out.response_data);
964}
965
[email protected]1628fe92011-10-04 23:04:55966// Next tests deal with http://crbug.com/98895.
967
968// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02969TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55970 MockRead data_reads[] = {
971 MockRead("HTTP/1.1 200 OK\r\n"),
972 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
973 MockRead("Content-Length: 5\r\n\r\n"),
974 MockRead("Hello"),
975 };
976 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
977 arraysize(data_reads));
978 EXPECT_EQ(OK, out.rv);
979 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
980 EXPECT_EQ("Hello", out.response_data);
981}
982
[email protected]54a9c6e52012-03-21 20:10:59983// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02984TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59985 TwoIdenticalContentDispositionHeaders) {
[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=\"greetings.txt\"r\n"),
989 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
990 MockRead("Content-Length: 5\r\n\r\n"),
991 MockRead("Hello"),
992 };
993 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
994 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59995 EXPECT_EQ(OK, out.rv);
996 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
997 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55998}
999
1000// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:021001TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551002 MockRead data_reads[] = {
1003 MockRead("HTTP/1.1 200 OK\r\n"),
1004 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1005 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1006 MockRead("Content-Length: 5\r\n\r\n"),
1007 MockRead("Hello"),
1008 };
1009 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1010 arraysize(data_reads));
1011 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
1012}
1013
[email protected]54a9c6e52012-03-21 20:10:591014// Checks that two identical Location headers result in no error.
1015// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:021016TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551017 MockRead data_reads[] = {
1018 MockRead("HTTP/1.1 302 Redirect\r\n"),
1019 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591020 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551021 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061022 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551023 };
1024
1025 HttpRequestInfo request;
1026 request.method = "GET";
1027 request.url = GURL("http://redirect.com/");
1028 request.load_flags = 0;
1029
mmenkee65e7af2015-10-13 17:16:421030 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:551031 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411032 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:551033
1034 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071035 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551036
[email protected]49639fa2011-12-20 23:22:411037 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551038
[email protected]49639fa2011-12-20 23:22:411039 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:551040 EXPECT_EQ(ERR_IO_PENDING, rv);
1041
1042 EXPECT_EQ(OK, callback.WaitForResult());
1043
1044 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:501045 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:551046 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1047 std::string url;
1048 EXPECT_TRUE(response->headers->IsRedirect(&url));
1049 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:151050 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:551051}
1052
[email protected]1628fe92011-10-04 23:04:551053// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:021054TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551055 MockRead data_reads[] = {
1056 MockRead("HTTP/1.1 302 Redirect\r\n"),
1057 MockRead("Location: http://good.com/\r\n"),
1058 MockRead("Location: http://evil.com/\r\n"),
1059 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061060 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551061 };
1062 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1063 arraysize(data_reads));
1064 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1065}
1066
[email protected]ef0faf2e72009-03-05 23:27:231067// Do a request using the HEAD method. Verify that we don't try to read the
1068// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021069TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421070 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231071 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231072 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231073 request.load_flags = 0;
1074
mmenkee65e7af2015-10-13 17:16:421075 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271076 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411077 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271078 BeforeProxyHeadersSentHandler proxy_headers_handler;
1079 trans->SetBeforeProxyHeadersSentCallback(
1080 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1081 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271082
[email protected]ef0faf2e72009-03-05 23:27:231083 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131084 MockWrite("HEAD / HTTP/1.1\r\n"
1085 "Host: www.example.org\r\n"
1086 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231087 };
1088 MockRead data_reads1[] = {
1089 MockRead("HTTP/1.1 404 Not Found\r\n"),
1090 MockRead("Server: Blah\r\n"),
1091 MockRead("Content-Length: 1234\r\n\r\n"),
1092
1093 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061094 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231095 };
1096
[email protected]31a2bfe2010-02-09 08:03:391097 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1098 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071099 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231100
[email protected]49639fa2011-12-20 23:22:411101 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231102
[email protected]49639fa2011-12-20 23:22:411103 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421104 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231105
1106 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421107 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231108
[email protected]1c773ea12009-04-28 19:58:421109 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501110 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231111
1112 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501113 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231114 EXPECT_EQ(1234, response->headers->GetContentLength());
1115 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151116 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271117 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231118
1119 std::string server_header;
1120 void* iter = NULL;
1121 bool has_server_header = response->headers->EnumerateHeader(
1122 &iter, "Server", &server_header);
1123 EXPECT_TRUE(has_server_header);
1124 EXPECT_EQ("Blah", server_header);
1125
1126 // Reading should give EOF right away, since there is no message body
1127 // (despite non-zero content-length).
1128 std::string response_data;
1129 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421130 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231131 EXPECT_EQ("", response_data);
1132}
1133
[email protected]23e482282013-06-14 16:08:021134TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
mmenkee65e7af2015-10-13 17:16:421135 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521136
1137 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351138 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1139 MockRead("hello"),
1140 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1141 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061142 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521143 };
[email protected]31a2bfe2010-02-09 08:03:391144 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071145 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521146
[email protected]0b0bf032010-09-21 18:08:501147 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521148 "hello", "world"
1149 };
1150
1151 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421152 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521153 request.method = "GET";
bncce36dca22015-04-21 22:11:231154 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521155 request.load_flags = 0;
1156
[email protected]262eec82013-03-19 21:01:361157 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501158 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271159
[email protected]49639fa2011-12-20 23:22:411160 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521161
[email protected]49639fa2011-12-20 23:22:411162 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421163 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521164
1165 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421166 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521167
[email protected]1c773ea12009-04-28 19:58:421168 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501169 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521170
[email protected]90499482013-06-01 00:39:501171 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251172 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151173 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521174
1175 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571176 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421177 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251178 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521179 }
1180}
1181
[email protected]23e482282013-06-14 16:08:021182TEST_P(HttpNetworkTransactionTest, Ignores100) {
olli.raula6df48b2a2015-11-26 07:40:221183 std::vector<scoped_ptr<UploadElementReader>> element_readers;
1184 element_readers.push_back(
1185 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
1186 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271187
[email protected]1c773ea12009-04-28 19:58:421188 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521189 request.method = "POST";
1190 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271191 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521192 request.load_flags = 0;
1193
mmenkee65e7af2015-10-13 17:16:421194 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271195 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411196 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271197
initial.commit586acc5fe2008-07-26 22:42:521198 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351199 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1200 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1201 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061202 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521203 };
[email protected]31a2bfe2010-02-09 08:03:391204 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071205 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521206
[email protected]49639fa2011-12-20 23:22:411207 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521208
[email protected]49639fa2011-12-20 23:22:411209 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421210 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521211
1212 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421213 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521214
[email protected]1c773ea12009-04-28 19:58:421215 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501216 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521217
[email protected]90499482013-06-01 00:39:501218 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251219 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521220
1221 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571222 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421223 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251224 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521225}
1226
[email protected]3a2d3662009-03-27 03:49:141227// This test is almost the same as Ignores100 above, but the response contains
1228// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571229// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021230TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421231 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141232 request.method = "GET";
1233 request.url = GURL("http://www.foo.com/");
1234 request.load_flags = 0;
1235
mmenkee65e7af2015-10-13 17:16:421236 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271237 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411238 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271239
[email protected]3a2d3662009-03-27 03:49:141240 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571241 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1242 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141243 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061244 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141245 };
[email protected]31a2bfe2010-02-09 08:03:391246 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071247 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141248
[email protected]49639fa2011-12-20 23:22:411249 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141250
[email protected]49639fa2011-12-20 23:22:411251 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421252 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141253
1254 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421255 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141256
[email protected]1c773ea12009-04-28 19:58:421257 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501258 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141259
[email protected]90499482013-06-01 00:39:501260 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141261 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1262
1263 std::string response_data;
1264 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421265 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141266 EXPECT_EQ("hello world", response_data);
1267}
1268
[email protected]23e482282013-06-14 16:08:021269TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081270 HttpRequestInfo request;
1271 request.method = "POST";
1272 request.url = GURL("http://www.foo.com/");
1273 request.load_flags = 0;
1274
mmenkee65e7af2015-10-13 17:16:421275 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
zmo9528c9f42015-08-04 22:12:081276 scoped_ptr<HttpTransaction> trans(
1277 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1278
1279 MockRead data_reads[] = {
1280 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1281 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381282 };
zmo9528c9f42015-08-04 22:12:081283 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1284 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381285
zmo9528c9f42015-08-04 22:12:081286 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381287
zmo9528c9f42015-08-04 22:12:081288 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1289 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ee9410e72010-01-07 01:42:381290
zmo9528c9f42015-08-04 22:12:081291 rv = callback.WaitForResult();
1292 EXPECT_EQ(OK, rv);
[email protected]ee9410e72010-01-07 01:42:381293
zmo9528c9f42015-08-04 22:12:081294 std::string response_data;
1295 rv = ReadTransaction(trans.get(), &response_data);
1296 EXPECT_EQ(OK, rv);
1297 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381298}
1299
[email protected]23e482282013-06-14 16:08:021300TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381301 HttpRequestInfo request;
1302 request.method = "POST";
1303 request.url = GURL("http://www.foo.com/");
1304 request.load_flags = 0;
1305
mmenkee65e7af2015-10-13 17:16:421306 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271307 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411308 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271309
[email protected]ee9410e72010-01-07 01:42:381310 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061311 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381312 };
[email protected]31a2bfe2010-02-09 08:03:391313 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071314 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381315
[email protected]49639fa2011-12-20 23:22:411316 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381317
[email protected]49639fa2011-12-20 23:22:411318 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381319 EXPECT_EQ(ERR_IO_PENDING, rv);
1320
1321 rv = callback.WaitForResult();
1322 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1323}
1324
[email protected]23e482282013-06-14 16:08:021325void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511326 const MockWrite* write_failure,
1327 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421328 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521329 request.method = "GET";
1330 request.url = GURL("http://www.foo.com/");
1331 request.load_flags = 0;
1332
vishal.b62985ca92015-04-17 08:45:511333 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071334 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:421335 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271336
[email protected]202965992011-12-07 23:04:511337 // Written data for successfully sending both requests.
1338 MockWrite data1_writes[] = {
1339 MockWrite("GET / HTTP/1.1\r\n"
1340 "Host: www.foo.com\r\n"
1341 "Connection: keep-alive\r\n\r\n"),
1342 MockWrite("GET / HTTP/1.1\r\n"
1343 "Host: www.foo.com\r\n"
1344 "Connection: keep-alive\r\n\r\n")
1345 };
1346
1347 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521348 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351349 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1350 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061351 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521352 };
[email protected]202965992011-12-07 23:04:511353
1354 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491355 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511356 data1_writes[1] = *write_failure;
1357 } else {
1358 ASSERT_TRUE(read_failure);
1359 data1_reads[2] = *read_failure;
1360 }
1361
1362 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1363 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071364 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521365
1366 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351367 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1368 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061369 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521370 };
[email protected]31a2bfe2010-02-09 08:03:391371 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071372 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521373
thestig9d3bb0c2015-01-24 00:49:511374 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521375 "hello", "world"
1376 };
1377
[email protected]58e32bb2013-01-21 18:23:251378 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521379 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411380 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521381
[email protected]262eec82013-03-19 21:01:361382 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501383 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521384
[email protected]49639fa2011-12-20 23:22:411385 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421386 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521387
1388 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421389 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521390
[email protected]58e32bb2013-01-21 18:23:251391 LoadTimingInfo load_timing_info;
1392 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1393 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1394 if (i == 0) {
1395 first_socket_log_id = load_timing_info.socket_log_id;
1396 } else {
1397 // The second request should be using a new socket.
1398 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1399 }
1400
[email protected]1c773ea12009-04-28 19:58:421401 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501402 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521403
[email protected]90499482013-06-01 00:39:501404 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251405 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521406
1407 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571408 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421409 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251410 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521411 }
1412}
[email protected]3d2a59b2008-09-26 19:44:251413
[email protected]a34f61ee2014-03-18 20:59:491414void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1415 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101416 const MockRead* read_failure,
1417 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491418 HttpRequestInfo request;
1419 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101420 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491421 request.load_flags = 0;
1422
vishal.b62985ca92015-04-17 08:45:511423 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491424 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:421425 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491426
[email protected]09356c652014-03-25 15:36:101427 SSLSocketDataProvider ssl1(ASYNC, OK);
1428 SSLSocketDataProvider ssl2(ASYNC, OK);
1429 if (use_spdy) {
rdsmithebb50aa2015-11-12 03:44:381430 ssl1.SetNextProto(GetProtocol());
1431 ssl2.SetNextProto(GetProtocol());
[email protected]09356c652014-03-25 15:36:101432 }
1433 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1434 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491435
[email protected]09356c652014-03-25 15:36:101436 // SPDY versions of the request and response.
1437 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1438 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1439 scoped_ptr<SpdyFrame> spdy_response(
1440 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1441 scoped_ptr<SpdyFrame> spdy_data(
1442 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491443
[email protected]09356c652014-03-25 15:36:101444 // HTTP/1.1 versions of the request and response.
1445 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1446 "Host: www.foo.com\r\n"
1447 "Connection: keep-alive\r\n\r\n";
1448 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1449 const char kHttpData[] = "hello";
1450
1451 std::vector<MockRead> data1_reads;
1452 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491453 if (write_failure) {
1454 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101455 data1_writes.push_back(*write_failure);
1456 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491457 } else {
1458 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101459 if (use_spdy) {
1460 data1_writes.push_back(CreateMockWrite(*spdy_request));
1461 } else {
1462 data1_writes.push_back(MockWrite(kHttpRequest));
1463 }
1464 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491465 }
1466
[email protected]09356c652014-03-25 15:36:101467 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1468 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491469 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1470
[email protected]09356c652014-03-25 15:36:101471 std::vector<MockRead> data2_reads;
1472 std::vector<MockWrite> data2_writes;
1473
1474 if (use_spdy) {
1475 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1476
1477 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1478 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1479 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1480 } else {
1481 data2_writes.push_back(
1482 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1483
1484 data2_reads.push_back(
1485 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1486 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1487 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1488 }
rch8e6c6c42015-05-01 14:05:131489 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1490 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491491 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1492
1493 // Preconnect a socket.
ttuttle859dc7a2015-04-23 19:42:291494 SSLConfig ssl_config;
[email protected]a34f61ee2014-03-18 20:59:491495 session->ssl_config_service()->GetSSLConfig(&ssl_config);
bnc1f295372015-10-21 23:24:221496 session->GetAlpnProtos(&ssl_config.alpn_protos);
1497 session->GetNpnProtos(&ssl_config.npn_protos);
mmenked1205bd2015-07-15 22:26:351498 session->http_stream_factory()->PreconnectStreams(1, request, ssl_config,
1499 ssl_config);
[email protected]a34f61ee2014-03-18 20:59:491500 // Wait for the preconnect to complete.
1501 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1502 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101503 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491504
1505 // Make the request.
1506 TestCompletionCallback callback;
1507
1508 scoped_ptr<HttpTransaction> trans(
1509 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1510
1511 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1512 EXPECT_EQ(ERR_IO_PENDING, rv);
1513
1514 rv = callback.WaitForResult();
1515 EXPECT_EQ(OK, rv);
1516
1517 LoadTimingInfo load_timing_info;
1518 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101519 TestLoadTimingNotReused(
1520 load_timing_info,
1521 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491522
1523 const HttpResponseInfo* response = trans->GetResponseInfo();
1524 ASSERT_TRUE(response != NULL);
1525
1526 EXPECT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:021527 if (response->was_fetched_via_spdy) {
1528 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1529 } else {
1530 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1531 }
[email protected]a34f61ee2014-03-18 20:59:491532
1533 std::string response_data;
1534 rv = ReadTransaction(trans.get(), &response_data);
1535 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101536 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491537}
1538
[email protected]23e482282013-06-14 16:08:021539TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231540 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061541 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511542 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1543}
1544
[email protected]23e482282013-06-14 16:08:021545TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061546 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511547 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251548}
1549
[email protected]23e482282013-06-14 16:08:021550TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061551 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511552 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251553}
1554
[email protected]d58ceea82014-06-04 10:55:541555// Make sure that on a 408 response (Request Timeout), the request is retried,
1556// if the socket was a reused keep alive socket.
1557TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1558 MockRead read_failure(SYNCHRONOUS,
1559 "HTTP/1.1 408 Request Timeout\r\n"
1560 "Connection: Keep-Alive\r\n"
1561 "Content-Length: 6\r\n\r\n"
1562 "Pickle");
1563 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1564}
1565
[email protected]a34f61ee2014-03-18 20:59:491566TEST_P(HttpNetworkTransactionTest,
1567 PreconnectErrorNotConnectedOnWrite) {
1568 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101569 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491570}
1571
1572TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1573 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101574 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491575}
1576
1577TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1578 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101579 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1580}
1581
1582TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1583 MockRead read_failure(ASYNC, OK); // EOF
1584 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1585}
1586
[email protected]d58ceea82014-06-04 10:55:541587// Make sure that on a 408 response (Request Timeout), the request is retried,
1588// if the socket was a preconnected (UNUSED_IDLE) socket.
1589TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1590 MockRead read_failure(SYNCHRONOUS,
1591 "HTTP/1.1 408 Request Timeout\r\n"
1592 "Connection: Keep-Alive\r\n"
1593 "Content-Length: 6\r\n\r\n"
1594 "Pickle");
1595 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1596 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1597}
1598
[email protected]09356c652014-03-25 15:36:101599TEST_P(HttpNetworkTransactionTest,
1600 SpdyPreconnectErrorNotConnectedOnWrite) {
1601 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1602 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1603}
1604
1605TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1606 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1607 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1608}
1609
1610TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1611 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1612 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1613}
1614
1615TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1616 MockRead read_failure(ASYNC, OK); // EOF
1617 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491618}
1619
[email protected]23e482282013-06-14 16:08:021620TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421621 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251622 request.method = "GET";
bncce36dca22015-04-21 22:11:231623 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251624 request.load_flags = 0;
1625
mmenkee65e7af2015-10-13 17:16:421626 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271627 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411628 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271629
[email protected]3d2a59b2008-09-26 19:44:251630 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061631 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351632 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1633 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061634 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251635 };
[email protected]31a2bfe2010-02-09 08:03:391636 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071637 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251638
[email protected]49639fa2011-12-20 23:22:411639 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251640
[email protected]49639fa2011-12-20 23:22:411641 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421642 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251643
1644 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421645 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:591646
1647 IPEndPoint endpoint;
1648 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
1649 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251650}
1651
1652// What do various browsers do when the server closes a non-keepalive
1653// connection without sending any response header or body?
1654//
1655// IE7: error page
1656// Safari 3.1.2 (Windows): error page
1657// Firefox 3.0.1: blank page
1658// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421659// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1660// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021661TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251662 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061663 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351664 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1665 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061666 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251667 };
[email protected]31a2bfe2010-02-09 08:03:391668 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1669 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421670 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251671}
[email protected]038e9a32008-10-08 22:40:161672
[email protected]1826a402014-01-08 15:40:481673// Test that network access can be deferred and resumed.
1674TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1675 HttpRequestInfo request;
1676 request.method = "GET";
bncce36dca22015-04-21 22:11:231677 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481678 request.load_flags = 0;
1679
mmenkee65e7af2015-10-13 17:16:421680 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1826a402014-01-08 15:40:481681 scoped_ptr<HttpTransaction> trans(
1682 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1683
1684 // Defer on OnBeforeNetworkStart.
1685 BeforeNetworkStartHandler net_start_handler(true); // defer
1686 trans->SetBeforeNetworkStartCallback(
1687 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1688 base::Unretained(&net_start_handler)));
1689
1690 MockRead data_reads[] = {
1691 MockRead("HTTP/1.0 200 OK\r\n"),
1692 MockRead("Content-Length: 5\r\n\r\n"),
1693 MockRead("hello"),
1694 MockRead(SYNCHRONOUS, 0),
1695 };
1696 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1697 session_deps_.socket_factory->AddSocketDataProvider(&data);
1698
1699 TestCompletionCallback callback;
1700
1701 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1702 EXPECT_EQ(ERR_IO_PENDING, rv);
1703 base::MessageLoop::current()->RunUntilIdle();
1704
1705 // Should have deferred for network start.
1706 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1707 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481708
1709 trans->ResumeNetworkStart();
1710 rv = callback.WaitForResult();
1711 EXPECT_EQ(OK, rv);
1712 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1713
1714 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1715 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1716 if (rv == ERR_IO_PENDING)
1717 rv = callback.WaitForResult();
1718 EXPECT_EQ(5, rv);
1719 trans.reset();
1720}
1721
1722// Test that network use can be deferred and canceled.
1723TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1724 HttpRequestInfo request;
1725 request.method = "GET";
bncce36dca22015-04-21 22:11:231726 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481727 request.load_flags = 0;
1728
mmenkee65e7af2015-10-13 17:16:421729 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1826a402014-01-08 15:40:481730 scoped_ptr<HttpTransaction> trans(
1731 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1732
1733 // Defer on OnBeforeNetworkStart.
1734 BeforeNetworkStartHandler net_start_handler(true); // defer
1735 trans->SetBeforeNetworkStartCallback(
1736 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1737 base::Unretained(&net_start_handler)));
1738
1739 TestCompletionCallback callback;
1740
1741 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1742 EXPECT_EQ(ERR_IO_PENDING, rv);
1743 base::MessageLoop::current()->RunUntilIdle();
1744
1745 // Should have deferred for network start.
1746 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1747 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481748}
1749
[email protected]7a5378b2012-11-04 03:25:171750// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1751// tests. There was a bug causing HttpNetworkTransaction to hang in the
1752// destructor in such situations.
1753// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021754TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171755 HttpRequestInfo request;
1756 request.method = "GET";
bncce36dca22015-04-21 22:11:231757 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171758 request.load_flags = 0;
1759
mmenkee65e7af2015-10-13 17:16:421760 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361761 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501762 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171763
1764 MockRead data_reads[] = {
1765 MockRead("HTTP/1.0 200 OK\r\n"),
1766 MockRead("Connection: keep-alive\r\n"),
1767 MockRead("Content-Length: 100\r\n\r\n"),
1768 MockRead("hello"),
1769 MockRead(SYNCHRONOUS, 0),
1770 };
1771 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071772 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171773
1774 TestCompletionCallback callback;
1775
1776 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1777 EXPECT_EQ(ERR_IO_PENDING, rv);
1778
1779 rv = callback.WaitForResult();
1780 EXPECT_EQ(OK, rv);
1781
1782 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501783 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171784 if (rv == ERR_IO_PENDING)
1785 rv = callback.WaitForResult();
1786 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501787 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171788 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1789
1790 trans.reset();
[email protected]2da659e2013-05-23 20:51:341791 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171792 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1793}
1794
[email protected]23e482282013-06-14 16:08:021795TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171796 HttpRequestInfo request;
1797 request.method = "GET";
bncce36dca22015-04-21 22:11:231798 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171799 request.load_flags = 0;
1800
mmenkee65e7af2015-10-13 17:16:421801 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361802 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501803 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171804
1805 MockRead data_reads[] = {
1806 MockRead("HTTP/1.0 200 OK\r\n"),
1807 MockRead("Connection: keep-alive\r\n"),
1808 MockRead("Content-Length: 100\r\n\r\n"),
1809 MockRead(SYNCHRONOUS, 0),
1810 };
1811 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071812 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171813
1814 TestCompletionCallback callback;
1815
1816 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1817 EXPECT_EQ(ERR_IO_PENDING, rv);
1818
1819 rv = callback.WaitForResult();
1820 EXPECT_EQ(OK, rv);
1821
1822 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501823 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171824 if (rv == ERR_IO_PENDING)
1825 rv = callback.WaitForResult();
1826 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1827
1828 trans.reset();
[email protected]2da659e2013-05-23 20:51:341829 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171830 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1831}
1832
[email protected]0b0bf032010-09-21 18:08:501833// Test that we correctly reuse a keep-alive connection after not explicitly
1834// reading the body.
[email protected]23e482282013-06-14 16:08:021835TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131836 HttpRequestInfo request;
1837 request.method = "GET";
1838 request.url = GURL("http://www.foo.com/");
1839 request.load_flags = 0;
1840
vishal.b62985ca92015-04-17 08:45:511841 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071842 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:421843 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271844
[email protected]0b0bf032010-09-21 18:08:501845 // Note that because all these reads happen in the same
1846 // StaticSocketDataProvider, it shows that the same socket is being reused for
1847 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131848 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501849 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1850 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131851 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501852 MockRead("HTTP/1.1 302 Found\r\n"
1853 "Content-Length: 0\r\n\r\n"),
1854 MockRead("HTTP/1.1 302 Found\r\n"
1855 "Content-Length: 5\r\n\r\n"
1856 "hello"),
1857 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1858 "Content-Length: 0\r\n\r\n"),
1859 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1860 "Content-Length: 5\r\n\r\n"
1861 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131862 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1863 MockRead("hello"),
1864 };
1865 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071866 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131867
1868 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061869 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131870 };
1871 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071872 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131873
[email protected]0b0bf032010-09-21 18:08:501874 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1875 std::string response_lines[kNumUnreadBodies];
1876
[email protected]58e32bb2013-01-21 18:23:251877 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501878 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411879 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131880
[email protected]262eec82013-03-19 21:01:361881 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501882 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131883
[email protected]49639fa2011-12-20 23:22:411884 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131885 EXPECT_EQ(ERR_IO_PENDING, rv);
1886
1887 rv = callback.WaitForResult();
1888 EXPECT_EQ(OK, rv);
1889
[email protected]58e32bb2013-01-21 18:23:251890 LoadTimingInfo load_timing_info;
1891 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1892 if (i == 0) {
1893 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1894 first_socket_log_id = load_timing_info.socket_log_id;
1895 } else {
1896 TestLoadTimingReused(load_timing_info);
1897 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1898 }
1899
[email protected]fc31d6a42010-06-24 18:05:131900 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501901 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131902
[email protected]90499482013-06-01 00:39:501903 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501904 response_lines[i] = response->headers->GetStatusLine();
1905
1906 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131907 }
[email protected]0b0bf032010-09-21 18:08:501908
1909 const char* const kStatusLines[] = {
1910 "HTTP/1.1 204 No Content",
1911 "HTTP/1.1 205 Reset Content",
1912 "HTTP/1.1 304 Not Modified",
1913 "HTTP/1.1 302 Found",
1914 "HTTP/1.1 302 Found",
1915 "HTTP/1.1 301 Moved Permanently",
1916 "HTTP/1.1 301 Moved Permanently",
1917 };
1918
mostynb91e0da982015-01-20 19:17:271919 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1920 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501921
1922 for (int i = 0; i < kNumUnreadBodies; ++i)
1923 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1924
[email protected]49639fa2011-12-20 23:22:411925 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361926 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501927 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411928 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501929 EXPECT_EQ(ERR_IO_PENDING, rv);
1930 rv = callback.WaitForResult();
1931 EXPECT_EQ(OK, rv);
1932 const HttpResponseInfo* response = trans->GetResponseInfo();
1933 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501934 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501935 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1936 std::string response_data;
1937 rv = ReadTransaction(trans.get(), &response_data);
1938 EXPECT_EQ(OK, rv);
1939 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131940}
1941
[email protected]038e9a32008-10-08 22:40:161942// Test the request-challenge-retry sequence for basic auth.
1943// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021944TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421945 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161946 request.method = "GET";
bncce36dca22015-04-21 22:11:231947 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161948 request.load_flags = 0;
1949
vishal.b62985ca92015-04-17 08:45:511950 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071951 session_deps_.net_log = &log;
mmenkee65e7af2015-10-13 17:16:421952 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271953 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411954 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271955
[email protected]f9ee6b52008-11-08 06:46:231956 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231957 MockWrite(
1958 "GET / HTTP/1.1\r\n"
1959 "Host: www.example.org\r\n"
1960 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231961 };
1962
[email protected]038e9a32008-10-08 22:40:161963 MockRead data_reads1[] = {
1964 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1965 // Give a couple authenticate options (only the middle one is actually
1966 // supported).
[email protected]22927ad2009-09-21 19:56:191967 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161968 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1969 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1970 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1971 // Large content-length -- won't matter, as connection will be reset.
1972 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061973 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161974 };
1975
1976 // After calling trans->RestartWithAuth(), this is the request we should
1977 // be issuing -- the final header line contains the credentials.
1978 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:231979 MockWrite(
1980 "GET / HTTP/1.1\r\n"
1981 "Host: www.example.org\r\n"
1982 "Connection: keep-alive\r\n"
1983 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:161984 };
1985
1986 // Lastly, the server responds with the actual content.
1987 MockRead data_reads2[] = {
1988 MockRead("HTTP/1.0 200 OK\r\n"),
1989 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1990 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061991 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161992 };
1993
[email protected]31a2bfe2010-02-09 08:03:391994 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1995 data_writes1, arraysize(data_writes1));
1996 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1997 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071998 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1999 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162000
[email protected]49639fa2011-12-20 23:22:412001 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162002
[email protected]49639fa2011-12-20 23:22:412003 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422004 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162005
2006 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422007 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162008
[email protected]58e32bb2013-01-21 18:23:252009 LoadTimingInfo load_timing_info1;
2010 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2011 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2012
sclittlefb249892015-09-10 21:33:222013 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2014 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2015 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:192016 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2017
[email protected]1c773ea12009-04-28 19:58:422018 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502019 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042020 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162021
[email protected]49639fa2011-12-20 23:22:412022 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162023
[email protected]49639fa2011-12-20 23:22:412024 rv = trans->RestartWithAuth(
2025 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422026 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162027
2028 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422029 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162030
[email protected]58e32bb2013-01-21 18:23:252031 LoadTimingInfo load_timing_info2;
2032 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2033 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2034 // The load timing after restart should have a new socket ID, and times after
2035 // those of the first load timing.
2036 EXPECT_LE(load_timing_info1.receive_headers_end,
2037 load_timing_info2.connect_timing.connect_start);
2038 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2039
sclittlefb249892015-09-10 21:33:222040 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2041 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2042 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
[email protected]b8015c42013-12-24 15:18:192043 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2044
[email protected]038e9a32008-10-08 22:40:162045 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502046 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:162047 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2048 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162049}
2050
ttuttled9dbc652015-09-29 20:00:592051// Test the request-challenge-retry sequence for basic auth.
2052// (basic auth is the easiest to mock, because it has no randomness).
2053TEST_P(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
2054 HttpRequestInfo request;
2055 request.method = "GET";
2056 request.url = GURL("http://www.example.org/");
2057 request.load_flags = 0;
2058
2059 TestNetLog log;
2060 MockHostResolver* resolver = new MockHostResolver();
2061 session_deps_.net_log = &log;
2062 session_deps_.host_resolver.reset(resolver);
mmenkee65e7af2015-10-13 17:16:422063 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
ttuttled9dbc652015-09-29 20:00:592064 scoped_ptr<HttpTransaction> trans(
2065 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2066
2067 resolver->rules()->ClearRules();
2068 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2069
2070 MockWrite data_writes1[] = {
2071 MockWrite("GET / HTTP/1.1\r\n"
2072 "Host: www.example.org\r\n"
2073 "Connection: keep-alive\r\n\r\n"),
2074 };
2075
2076 MockRead data_reads1[] = {
2077 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2078 // Give a couple authenticate options (only the middle one is actually
2079 // supported).
2080 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2081 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2082 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2083 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2084 // Large content-length -- won't matter, as connection will be reset.
2085 MockRead("Content-Length: 10000\r\n\r\n"),
2086 MockRead(SYNCHRONOUS, ERR_FAILED),
2087 };
2088
2089 // After calling trans->RestartWithAuth(), this is the request we should
2090 // be issuing -- the final header line contains the credentials.
2091 MockWrite data_writes2[] = {
2092 MockWrite("GET / HTTP/1.1\r\n"
2093 "Host: www.example.org\r\n"
2094 "Connection: keep-alive\r\n"
2095 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2096 };
2097
2098 // Lastly, the server responds with the actual content.
2099 MockRead data_reads2[] = {
2100 MockRead("HTTP/1.0 200 OK\r\n"),
2101 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2102 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2103 };
2104
2105 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2106 data_writes1, arraysize(data_writes1));
2107 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2108 data_writes2, arraysize(data_writes2));
2109 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2110 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2111
2112 TestCompletionCallback callback1;
2113
2114 EXPECT_EQ(OK, callback1.GetResult(trans->Start(&request, callback1.callback(),
2115 BoundNetLog())));
2116
2117 LoadTimingInfo load_timing_info1;
2118 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2119 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2120
2121 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2122 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2123 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
2124 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2125
2126 const HttpResponseInfo* response = trans->GetResponseInfo();
2127 ASSERT_TRUE(response);
2128 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2129
2130 IPEndPoint endpoint;
2131 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2132 ASSERT_FALSE(endpoint.address().empty());
2133 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2134
2135 resolver->rules()->ClearRules();
2136 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2137
2138 TestCompletionCallback callback2;
2139
2140 EXPECT_EQ(OK, callback2.GetResult(trans->RestartWithAuth(
2141 AuthCredentials(kFoo, kBar), callback2.callback())));
2142
2143 LoadTimingInfo load_timing_info2;
2144 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2145 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2146 // The load timing after restart should have a new socket ID, and times after
2147 // those of the first load timing.
2148 EXPECT_LE(load_timing_info1.receive_headers_end,
2149 load_timing_info2.connect_timing.connect_start);
2150 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2151
2152 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2153 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2154 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
2155 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2156
2157 response = trans->GetResponseInfo();
2158 ASSERT_TRUE(response);
2159 EXPECT_FALSE(response->auth_challenge.get());
2160 EXPECT_EQ(100, response->headers->GetContentLength());
2161
2162 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2163 ASSERT_FALSE(endpoint.address().empty());
2164 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2165}
2166
[email protected]23e482282013-06-14 16:08:022167TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462168 HttpRequestInfo request;
2169 request.method = "GET";
bncce36dca22015-04-21 22:11:232170 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292171 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462172
mmenkee65e7af2015-10-13 17:16:422173 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272174 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412175 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272176
[email protected]861fcd52009-08-26 02:33:462177 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232178 MockWrite(
2179 "GET / HTTP/1.1\r\n"
2180 "Host: www.example.org\r\n"
2181 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462182 };
2183
2184 MockRead data_reads[] = {
2185 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2186 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2187 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2188 // Large content-length -- won't matter, as connection will be reset.
2189 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062190 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462191 };
2192
[email protected]31a2bfe2010-02-09 08:03:392193 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2194 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072195 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412196 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462197
[email protected]49639fa2011-12-20 23:22:412198 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462199 EXPECT_EQ(ERR_IO_PENDING, rv);
2200
2201 rv = callback.WaitForResult();
2202 EXPECT_EQ(0, rv);
2203
sclittlefb249892015-09-10 21:33:222204 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2205 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2206 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
[email protected]b8015c42013-12-24 15:18:192207 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2208
[email protected]861fcd52009-08-26 02:33:462209 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502210 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462211 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2212}
2213
[email protected]2d2697f92009-02-18 21:00:322214// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2215// connection.
[email protected]23e482282013-06-14 16:08:022216TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422217 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322218 request.method = "GET";
bncce36dca22015-04-21 22:11:232219 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322220 request.load_flags = 0;
2221
vishal.b62985ca92015-04-17 08:45:512222 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072223 session_deps_.net_log = &log;
mmenkee65e7af2015-10-13 17:16:422224 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272225
[email protected]2d2697f92009-02-18 21:00:322226 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232227 MockWrite(
2228 "GET / HTTP/1.1\r\n"
2229 "Host: www.example.org\r\n"
2230 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322231
bncce36dca22015-04-21 22:11:232232 // After calling trans->RestartWithAuth(), this is the request we should
2233 // be issuing -- the final header line contains the credentials.
2234 MockWrite(
2235 "GET / HTTP/1.1\r\n"
2236 "Host: www.example.org\r\n"
2237 "Connection: keep-alive\r\n"
2238 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322239 };
2240
2241 MockRead data_reads1[] = {
2242 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2243 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2244 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2245 MockRead("Content-Length: 14\r\n\r\n"),
2246 MockRead("Unauthorized\r\n"),
2247
2248 // Lastly, the server responds with the actual content.
2249 MockRead("HTTP/1.1 200 OK\r\n"),
2250 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502251 MockRead("Content-Length: 5\r\n\r\n"),
2252 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322253 };
2254
[email protected]2d0a4f92011-05-05 16:38:462255 // If there is a regression where we disconnect a Keep-Alive
2256 // connection during an auth roundtrip, we'll end up reading this.
2257 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062258 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462259 };
2260
[email protected]31a2bfe2010-02-09 08:03:392261 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2262 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462263 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2264 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072265 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2266 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322267
[email protected]49639fa2011-12-20 23:22:412268 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322269
[email protected]262eec82013-03-19 21:01:362270 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502271 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412272 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422273 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322274
2275 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422276 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322277
[email protected]58e32bb2013-01-21 18:23:252278 LoadTimingInfo load_timing_info1;
2279 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2280 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2281
[email protected]1c773ea12009-04-28 19:58:422282 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502283 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042284 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322285
[email protected]49639fa2011-12-20 23:22:412286 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322287
[email protected]49639fa2011-12-20 23:22:412288 rv = trans->RestartWithAuth(
2289 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422290 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322291
2292 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422293 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322294
[email protected]58e32bb2013-01-21 18:23:252295 LoadTimingInfo load_timing_info2;
2296 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2297 TestLoadTimingReused(load_timing_info2);
2298 // The load timing after restart should have the same socket ID, and times
2299 // those of the first load timing.
2300 EXPECT_LE(load_timing_info1.receive_headers_end,
2301 load_timing_info2.send_start);
2302 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2303
[email protected]2d2697f92009-02-18 21:00:322304 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502305 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322306 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502307 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192308
2309 std::string response_data;
2310 rv = ReadTransaction(trans.get(), &response_data);
2311 EXPECT_EQ(OK, rv);
sclittlefb249892015-09-10 21:33:222312
2313 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2314 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2315 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:192316 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322317}
2318
2319// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2320// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022321TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422322 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322323 request.method = "GET";
bncce36dca22015-04-21 22:11:232324 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322325 request.load_flags = 0;
2326
mmenkee65e7af2015-10-13 17:16:422327 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272328
[email protected]2d2697f92009-02-18 21:00:322329 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232330 MockWrite(
2331 "GET / HTTP/1.1\r\n"
2332 "Host: www.example.org\r\n"
2333 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322334
bncce36dca22015-04-21 22:11:232335 // After calling trans->RestartWithAuth(), this is the request we should
2336 // be issuing -- the final header line contains the credentials.
2337 MockWrite(
2338 "GET / HTTP/1.1\r\n"
2339 "Host: www.example.org\r\n"
2340 "Connection: keep-alive\r\n"
2341 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322342 };
2343
[email protected]2d2697f92009-02-18 21:00:322344 MockRead data_reads1[] = {
2345 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2346 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312347 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322348
2349 // Lastly, the server responds with the actual content.
2350 MockRead("HTTP/1.1 200 OK\r\n"),
2351 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502352 MockRead("Content-Length: 5\r\n\r\n"),
2353 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322354 };
2355
[email protected]2d0a4f92011-05-05 16:38:462356 // An incorrect reconnect would cause this to be read.
2357 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062358 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462359 };
2360
[email protected]31a2bfe2010-02-09 08:03:392361 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2362 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462363 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2364 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072365 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2366 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322367
[email protected]49639fa2011-12-20 23:22:412368 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322369
[email protected]262eec82013-03-19 21:01:362370 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502371 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412372 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422373 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322374
2375 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422376 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322377
[email protected]1c773ea12009-04-28 19:58:422378 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502379 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042380 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322381
[email protected]49639fa2011-12-20 23:22:412382 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322383
[email protected]49639fa2011-12-20 23:22:412384 rv = trans->RestartWithAuth(
2385 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422386 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322387
2388 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422389 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322390
2391 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502392 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322393 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502394 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322395}
2396
2397// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2398// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022399TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422400 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322401 request.method = "GET";
bncce36dca22015-04-21 22:11:232402 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322403 request.load_flags = 0;
2404
mmenkee65e7af2015-10-13 17:16:422405 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272406
[email protected]2d2697f92009-02-18 21:00:322407 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232408 MockWrite(
2409 "GET / HTTP/1.1\r\n"
2410 "Host: www.example.org\r\n"
2411 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322412
bncce36dca22015-04-21 22:11:232413 // After calling trans->RestartWithAuth(), this is the request we should
2414 // be issuing -- the final header line contains the credentials.
2415 MockWrite(
2416 "GET / HTTP/1.1\r\n"
2417 "Host: www.example.org\r\n"
2418 "Connection: keep-alive\r\n"
2419 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322420 };
2421
2422 // Respond with 5 kb of response body.
2423 std::string large_body_string("Unauthorized");
2424 large_body_string.append(5 * 1024, ' ');
2425 large_body_string.append("\r\n");
2426
2427 MockRead data_reads1[] = {
2428 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2429 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2430 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2431 // 5134 = 12 + 5 * 1024 + 2
2432 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062433 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322434
2435 // Lastly, the server responds with the actual content.
2436 MockRead("HTTP/1.1 200 OK\r\n"),
2437 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502438 MockRead("Content-Length: 5\r\n\r\n"),
2439 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322440 };
2441
[email protected]2d0a4f92011-05-05 16:38:462442 // An incorrect reconnect would cause this to be read.
2443 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062444 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462445 };
2446
[email protected]31a2bfe2010-02-09 08:03:392447 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2448 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462449 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2450 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072451 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2452 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322453
[email protected]49639fa2011-12-20 23:22:412454 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322455
[email protected]262eec82013-03-19 21:01:362456 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502457 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412458 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422459 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322460
2461 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422462 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322463
[email protected]1c773ea12009-04-28 19:58:422464 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502465 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042466 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322467
[email protected]49639fa2011-12-20 23:22:412468 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322469
[email protected]49639fa2011-12-20 23:22:412470 rv = trans->RestartWithAuth(
2471 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422472 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322473
2474 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422475 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322476
2477 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502478 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322479 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502480 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322481}
2482
2483// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312484// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022485TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312486 HttpRequestInfo request;
2487 request.method = "GET";
bncce36dca22015-04-21 22:11:232488 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312489 request.load_flags = 0;
2490
mmenkee65e7af2015-10-13 17:16:422491 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272492
[email protected]11203f012009-11-12 23:02:312493 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232494 MockWrite(
2495 "GET / HTTP/1.1\r\n"
2496 "Host: www.example.org\r\n"
2497 "Connection: keep-alive\r\n\r\n"),
2498 // This simulates the seemingly successful write to a closed connection
2499 // if the bug is not fixed.
2500 MockWrite(
2501 "GET / HTTP/1.1\r\n"
2502 "Host: www.example.org\r\n"
2503 "Connection: keep-alive\r\n"
2504 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312505 };
2506
2507 MockRead data_reads1[] = {
2508 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2509 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2510 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2511 MockRead("Content-Length: 14\r\n\r\n"),
2512 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062513 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312514 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062515 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312516 };
2517
2518 // After calling trans->RestartWithAuth(), this is the request we should
2519 // be issuing -- the final header line contains the credentials.
2520 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232521 MockWrite(
2522 "GET / HTTP/1.1\r\n"
2523 "Host: www.example.org\r\n"
2524 "Connection: keep-alive\r\n"
2525 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312526 };
2527
2528 // Lastly, the server responds with the actual content.
2529 MockRead data_reads2[] = {
2530 MockRead("HTTP/1.1 200 OK\r\n"),
2531 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502532 MockRead("Content-Length: 5\r\n\r\n"),
2533 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312534 };
2535
[email protected]31a2bfe2010-02-09 08:03:392536 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2537 data_writes1, arraysize(data_writes1));
2538 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2539 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072540 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2541 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312542
[email protected]49639fa2011-12-20 23:22:412543 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312544
[email protected]262eec82013-03-19 21:01:362545 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502546 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412547 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312548 EXPECT_EQ(ERR_IO_PENDING, rv);
2549
2550 rv = callback1.WaitForResult();
2551 EXPECT_EQ(OK, rv);
2552
2553 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502554 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042555 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312556
[email protected]49639fa2011-12-20 23:22:412557 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312558
[email protected]49639fa2011-12-20 23:22:412559 rv = trans->RestartWithAuth(
2560 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312561 EXPECT_EQ(ERR_IO_PENDING, rv);
2562
2563 rv = callback2.WaitForResult();
2564 EXPECT_EQ(OK, rv);
2565
2566 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502567 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312568 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502569 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312570}
2571
[email protected]394816e92010-08-03 07:38:592572// Test the request-challenge-retry sequence for basic auth, over a connection
2573// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012574TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2575 HttpRequestInfo request;
2576 request.method = "GET";
bncce36dca22015-04-21 22:11:232577 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012578 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292579 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012580
2581 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032582 session_deps_.proxy_service =
2583 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512584 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012585 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422586 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012587
2588 // Since we have proxy, should try to establish tunnel.
2589 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542590 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172591 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542592 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012593 };
2594
mmenkee71e15332015-10-07 16:39:542595 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012596 // connection.
2597 MockRead data_reads1[] = {
2598 // No credentials.
2599 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2600 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542601 };
ttuttle34f63b52015-03-05 04:33:012602
mmenkee71e15332015-10-07 16:39:542603 // Since the first connection couldn't be reused, need to establish another
2604 // once given credentials.
2605 MockWrite data_writes2[] = {
2606 // After calling trans->RestartWithAuth(), this is the request we should
2607 // be issuing -- the final header line contains the credentials.
2608 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172609 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542610 "Proxy-Connection: keep-alive\r\n"
2611 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2612
2613 MockWrite("GET / HTTP/1.1\r\n"
2614 "Host: www.example.org\r\n"
2615 "Connection: keep-alive\r\n\r\n"),
2616 };
2617
2618 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012619 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2620
2621 MockRead("HTTP/1.1 200 OK\r\n"),
2622 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2623 MockRead("Content-Length: 5\r\n\r\n"),
2624 MockRead(SYNCHRONOUS, "hello"),
2625 };
2626
2627 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2628 data_writes1, arraysize(data_writes1));
2629 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542630 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2631 data_writes2, arraysize(data_writes2));
2632 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012633 SSLSocketDataProvider ssl(ASYNC, OK);
2634 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2635
2636 TestCompletionCallback callback1;
2637
2638 scoped_ptr<HttpTransaction> trans(
2639 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2640
2641 int rv = trans->Start(&request, callback1.callback(), log.bound());
2642 EXPECT_EQ(ERR_IO_PENDING, rv);
2643
2644 rv = callback1.WaitForResult();
2645 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462646 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012647 log.GetEntries(&entries);
2648 size_t pos = ExpectLogContainsSomewhere(
2649 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2650 NetLog::PHASE_NONE);
2651 ExpectLogContainsSomewhere(
2652 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2653 NetLog::PHASE_NONE);
2654
2655 const HttpResponseInfo* response = trans->GetResponseInfo();
2656 ASSERT_TRUE(response != NULL);
2657 EXPECT_FALSE(response->headers->IsKeepAlive());
2658 ASSERT_FALSE(response->headers.get() == NULL);
2659 EXPECT_EQ(407, response->headers->response_code());
2660 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2661 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2662
2663 LoadTimingInfo load_timing_info;
2664 // CONNECT requests and responses are handled at the connect job level, so
2665 // the transaction does not yet have a connection.
2666 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2667
2668 TestCompletionCallback callback2;
2669
2670 rv =
2671 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2672 EXPECT_EQ(ERR_IO_PENDING, rv);
2673
2674 rv = callback2.WaitForResult();
2675 EXPECT_EQ(OK, rv);
2676
2677 response = trans->GetResponseInfo();
2678 ASSERT_TRUE(response != NULL);
2679
2680 EXPECT_TRUE(response->headers->IsKeepAlive());
2681 EXPECT_EQ(200, response->headers->response_code());
2682 EXPECT_EQ(5, response->headers->GetContentLength());
2683 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2684
2685 // The password prompt info should not be set.
2686 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2687
2688 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2689 TestLoadTimingNotReusedWithPac(load_timing_info,
2690 CONNECT_TIMING_HAS_SSL_TIMES);
2691
2692 trans.reset();
2693 session->CloseAllConnections();
2694}
2695
2696// Test the request-challenge-retry sequence for basic auth, over a connection
2697// that requires a restart when setting up an SSL tunnel.
2698TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592699 HttpRequestInfo request;
2700 request.method = "GET";
bncce36dca22015-04-21 22:11:232701 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592702 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292703 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592704
[email protected]cb9bf6ca2011-01-28 13:15:272705 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032706 session_deps_.proxy_service =
2707 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512708 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072709 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422710 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272711
[email protected]394816e92010-08-03 07:38:592712 // Since we have proxy, should try to establish tunnel.
2713 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542714 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172715 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542716 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:112717 };
2718
mmenkee71e15332015-10-07 16:39:542719 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:082720 // connection.
2721 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:542722 // No credentials.
2723 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2724 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2725 MockRead("Proxy-Connection: close\r\n\r\n"),
2726 };
mmenkee0b5c882015-08-26 20:29:112727
mmenkee71e15332015-10-07 16:39:542728 MockWrite data_writes2[] = {
2729 // After calling trans->RestartWithAuth(), this is the request we should
2730 // be issuing -- the final header line contains the credentials.
2731 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172732 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542733 "Proxy-Connection: keep-alive\r\n"
2734 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:082735
mmenkee71e15332015-10-07 16:39:542736 MockWrite("GET / HTTP/1.1\r\n"
2737 "Host: www.example.org\r\n"
2738 "Connection: keep-alive\r\n\r\n"),
2739 };
2740
2741 MockRead data_reads2[] = {
2742 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2743
2744 MockRead("HTTP/1.1 200 OK\r\n"),
2745 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2746 MockRead("Content-Length: 5\r\n\r\n"),
2747 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592748 };
2749
2750 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2751 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072752 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542753 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2754 data_writes2, arraysize(data_writes2));
2755 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:062756 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072757 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592758
[email protected]49639fa2011-12-20 23:22:412759 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592760
[email protected]262eec82013-03-19 21:01:362761 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502762 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502763
[email protected]49639fa2011-12-20 23:22:412764 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592765 EXPECT_EQ(ERR_IO_PENDING, rv);
2766
2767 rv = callback1.WaitForResult();
2768 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462769 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402770 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592771 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402772 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592773 NetLog::PHASE_NONE);
2774 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402775 entries, pos,
[email protected]394816e92010-08-03 07:38:592776 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2777 NetLog::PHASE_NONE);
2778
2779 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502780 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012781 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502782 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592783 EXPECT_EQ(407, response->headers->response_code());
2784 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042785 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592786
[email protected]029c83b62013-01-24 05:28:202787 LoadTimingInfo load_timing_info;
2788 // CONNECT requests and responses are handled at the connect job level, so
2789 // the transaction does not yet have a connection.
2790 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2791
[email protected]49639fa2011-12-20 23:22:412792 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592793
[email protected]49639fa2011-12-20 23:22:412794 rv = trans->RestartWithAuth(
2795 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592796 EXPECT_EQ(ERR_IO_PENDING, rv);
2797
2798 rv = callback2.WaitForResult();
2799 EXPECT_EQ(OK, rv);
2800
2801 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502802 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592803
2804 EXPECT_TRUE(response->headers->IsKeepAlive());
2805 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502806 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592807 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2808
2809 // The password prompt info should not be set.
2810 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502811
[email protected]029c83b62013-01-24 05:28:202812 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2813 TestLoadTimingNotReusedWithPac(load_timing_info,
2814 CONNECT_TIMING_HAS_SSL_TIMES);
2815
[email protected]0b0bf032010-09-21 18:08:502816 trans.reset();
[email protected]102e27c2011-02-23 01:01:312817 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592818}
2819
[email protected]11203f012009-11-12 23:02:312820// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012821// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2822TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2823 HttpRequestInfo request;
2824 request.method = "GET";
bncce36dca22015-04-21 22:11:232825 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012826 // Ensure that proxy authentication is attempted even
2827 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292828 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012829
2830 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032831 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:512832 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012833 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422834 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012835
2836 scoped_ptr<HttpTransaction> trans(
2837 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2838
2839 // Since we have proxy, should try to establish tunnel.
2840 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:172841 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2842 "Host: www.example.org:443\r\n"
2843 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012844
2845 // After calling trans->RestartWithAuth(), this is the request we should
2846 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:172847 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2848 "Host: www.example.org:443\r\n"
2849 "Proxy-Connection: keep-alive\r\n"
2850 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012851 };
2852
2853 // The proxy responds to the connect with a 407, using a persistent
2854 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2855 MockRead data_reads1[] = {
2856 // No credentials.
2857 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2858 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2859 MockRead("Proxy-Connection: keep-alive\r\n"),
2860 MockRead("Content-Length: 10\r\n\r\n"),
2861 MockRead("0123456789"),
2862
2863 // Wrong credentials (wrong password).
2864 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2865 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2866 MockRead("Proxy-Connection: keep-alive\r\n"),
2867 MockRead("Content-Length: 10\r\n\r\n"),
2868 // No response body because the test stops reading here.
2869 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2870 };
2871
2872 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2873 data_writes1, arraysize(data_writes1));
2874 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2875
2876 TestCompletionCallback callback1;
2877
2878 int rv = trans->Start(&request, callback1.callback(), log.bound());
2879 EXPECT_EQ(ERR_IO_PENDING, rv);
2880
2881 rv = callback1.WaitForResult();
2882 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462883 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012884 log.GetEntries(&entries);
2885 size_t pos = ExpectLogContainsSomewhere(
2886 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2887 NetLog::PHASE_NONE);
2888 ExpectLogContainsSomewhere(
2889 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2890 NetLog::PHASE_NONE);
2891
2892 const HttpResponseInfo* response = trans->GetResponseInfo();
2893 ASSERT_TRUE(response);
2894 ASSERT_TRUE(response->headers);
2895 EXPECT_TRUE(response->headers->IsKeepAlive());
2896 EXPECT_EQ(407, response->headers->response_code());
2897 EXPECT_EQ(10, response->headers->GetContentLength());
2898 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2899 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2900
2901 TestCompletionCallback callback2;
2902
2903 // Wrong password (should be "bar").
2904 rv =
2905 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2906 EXPECT_EQ(ERR_IO_PENDING, rv);
2907
2908 rv = callback2.WaitForResult();
2909 EXPECT_EQ(OK, rv);
2910
2911 response = trans->GetResponseInfo();
2912 ASSERT_TRUE(response);
2913 ASSERT_TRUE(response->headers);
2914 EXPECT_TRUE(response->headers->IsKeepAlive());
2915 EXPECT_EQ(407, response->headers->response_code());
2916 EXPECT_EQ(10, response->headers->GetContentLength());
2917 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2918 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2919
2920 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2921 // out of scope.
2922 session->CloseAllConnections();
2923}
2924
2925// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2926// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2927TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272928 HttpRequestInfo request;
2929 request.method = "GET";
bncce36dca22015-04-21 22:11:232930 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272931 // Ensure that proxy authentication is attempted even
2932 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292933 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:272934
[email protected]2d2697f92009-02-18 21:00:322935 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032936 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:512937 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072938 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422939 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322940
[email protected]262eec82013-03-19 21:01:362941 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502942 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322943
[email protected]2d2697f92009-02-18 21:00:322944 // Since we have proxy, should try to establish tunnel.
2945 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:172946 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2947 "Host: www.example.org:443\r\n"
2948 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322949
bncce36dca22015-04-21 22:11:232950 // After calling trans->RestartWithAuth(), this is the request we should
2951 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:172952 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2953 "Host: www.example.org:443\r\n"
2954 "Proxy-Connection: keep-alive\r\n"
2955 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322956 };
2957
2958 // The proxy responds to the connect with a 407, using a persistent
2959 // connection.
2960 MockRead data_reads1[] = {
2961 // No credentials.
2962 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2963 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2964 MockRead("Content-Length: 10\r\n\r\n"),
2965 MockRead("0123456789"),
2966
2967 // Wrong credentials (wrong password).
2968 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2969 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2970 MockRead("Content-Length: 10\r\n\r\n"),
2971 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062972 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322973 };
2974
[email protected]31a2bfe2010-02-09 08:03:392975 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2976 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072977 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322978
[email protected]49639fa2011-12-20 23:22:412979 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322980
[email protected]49639fa2011-12-20 23:22:412981 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422982 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322983
2984 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422985 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462986 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402987 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392988 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402989 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392990 NetLog::PHASE_NONE);
2991 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402992 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392993 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2994 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322995
[email protected]1c773ea12009-04-28 19:58:422996 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242997 ASSERT_TRUE(response);
2998 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322999 EXPECT_TRUE(response->headers->IsKeepAlive());
3000 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:013001 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423002 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043003 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323004
[email protected]49639fa2011-12-20 23:22:413005 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323006
3007 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:413008 rv = trans->RestartWithAuth(
3009 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:423010 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:323011
3012 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423013 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:323014
3015 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243016 ASSERT_TRUE(response);
3017 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323018 EXPECT_TRUE(response->headers->IsKeepAlive());
3019 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:013020 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423021 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043022 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:133023
[email protected]e60e47a2010-07-14 03:37:183024 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3025 // out of scope.
[email protected]102e27c2011-02-23 01:01:313026 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323027}
3028
mmenkee71e15332015-10-07 16:39:543029// Test the case a proxy closes a socket while the challenge body is being
3030// drained.
3031TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
3032 HttpRequestInfo request;
3033 request.method = "GET";
3034 request.url = GURL("https://www.example.org/");
3035 // Ensure that proxy authentication is attempted even
3036 // when the no authentication data flag is set.
3037 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3038
3039 // Configure against proxy server "myproxy:70".
3040 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:423041 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543042
3043 scoped_ptr<HttpTransaction> trans(
3044 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3045
3046 // Since we have proxy, should try to establish tunnel.
3047 MockWrite data_writes1[] = {
3048 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173049 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543050 "Proxy-Connection: keep-alive\r\n\r\n"),
3051 };
3052
3053 // The proxy responds to the connect with a 407, using a persistent
3054 // connection.
3055 MockRead data_reads1[] = {
3056 // No credentials.
3057 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3058 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3059 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3060 // Server hands up in the middle of the body.
3061 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3062 };
3063
3064 MockWrite data_writes2[] = {
3065 // After calling trans->RestartWithAuth(), this is the request we should
3066 // be issuing -- the final header line contains the credentials.
3067 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173068 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543069 "Proxy-Connection: keep-alive\r\n"
3070 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3071
3072 MockWrite("GET / HTTP/1.1\r\n"
3073 "Host: www.example.org\r\n"
3074 "Connection: keep-alive\r\n\r\n"),
3075 };
3076
3077 MockRead data_reads2[] = {
3078 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3079
3080 MockRead("HTTP/1.1 200 OK\r\n"),
3081 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3082 MockRead("Content-Length: 5\r\n\r\n"),
3083 MockRead(SYNCHRONOUS, "hello"),
3084 };
3085
3086 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3087 data_writes1, arraysize(data_writes1));
3088 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3089 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3090 data_writes2, arraysize(data_writes2));
3091 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3092 SSLSocketDataProvider ssl(ASYNC, OK);
3093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3094
3095 TestCompletionCallback callback;
3096
3097 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3098 EXPECT_EQ(OK, callback.GetResult(rv));
3099
3100 const HttpResponseInfo* response = trans->GetResponseInfo();
3101 ASSERT_TRUE(response);
3102 ASSERT_TRUE(response->headers);
3103 EXPECT_TRUE(response->headers->IsKeepAlive());
3104 EXPECT_EQ(407, response->headers->response_code());
3105 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3106
3107 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
3108 EXPECT_EQ(OK, callback.GetResult(rv));
3109
3110 response = trans->GetResponseInfo();
3111 ASSERT_TRUE(response);
3112 ASSERT_TRUE(response->headers);
3113 EXPECT_TRUE(response->headers->IsKeepAlive());
3114 EXPECT_EQ(200, response->headers->response_code());
3115 std::string body;
3116 EXPECT_EQ(OK, ReadTransaction(trans.get(), &body));
3117 EXPECT_EQ("hello", body);
3118}
3119
[email protected]a8e9b162009-03-12 00:06:443120// Test that we don't read the response body when we fail to establish a tunnel,
3121// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:023122TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273123 HttpRequestInfo request;
3124 request.method = "GET";
bncce36dca22015-04-21 22:11:233125 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273126 request.load_flags = 0;
3127
[email protected]a8e9b162009-03-12 00:06:443128 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033129 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443130
mmenkee65e7af2015-10-13 17:16:423131 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443132
[email protected]262eec82013-03-19 21:01:363133 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503134 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:443135
[email protected]a8e9b162009-03-12 00:06:443136 // Since we have proxy, should try to establish tunnel.
3137 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173138 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3139 "Host: www.example.org:443\r\n"
3140 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443141 };
3142
3143 // The proxy responds to the connect with a 407.
3144 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243145 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3146 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3147 MockRead("Content-Length: 10\r\n\r\n"),
3148 MockRead("0123456789"), // Should not be reached.
3149 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443150 };
3151
[email protected]31a2bfe2010-02-09 08:03:393152 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3153 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073154 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443155
[email protected]49639fa2011-12-20 23:22:413156 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443157
[email protected]49639fa2011-12-20 23:22:413158 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423159 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:443160
3161 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423162 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:443163
[email protected]1c773ea12009-04-28 19:58:423164 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243165 ASSERT_TRUE(response);
3166 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443167 EXPECT_TRUE(response->headers->IsKeepAlive());
3168 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423169 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443170
3171 std::string response_data;
3172 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423173 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:183174
3175 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313176 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443177}
3178
ttuttle7933c112015-01-06 00:55:243179// Test that we don't pass extraneous headers from the proxy's response to the
3180// caller when the proxy responds to CONNECT with 407.
3181TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
3182 HttpRequestInfo request;
3183 request.method = "GET";
bncce36dca22015-04-21 22:11:233184 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243185 request.load_flags = 0;
3186
3187 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033188 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243189
mmenkee65e7af2015-10-13 17:16:423190 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243191
3192 scoped_ptr<HttpTransaction> trans(
3193 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3194
3195 // Since we have proxy, should try to establish tunnel.
3196 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173197 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3198 "Host: www.example.org:443\r\n"
3199 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243200 };
3201
3202 // The proxy responds to the connect with a 407.
3203 MockRead data_reads[] = {
3204 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3205 MockRead("X-Foo: bar\r\n"),
3206 MockRead("Set-Cookie: foo=bar\r\n"),
3207 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3208 MockRead("Content-Length: 10\r\n\r\n"),
3209 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
3210 };
3211
3212 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3213 arraysize(data_writes));
3214 session_deps_.socket_factory->AddSocketDataProvider(&data);
3215
3216 TestCompletionCallback callback;
3217
3218 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3219 EXPECT_EQ(ERR_IO_PENDING, rv);
3220
3221 rv = callback.WaitForResult();
3222 EXPECT_EQ(OK, rv);
3223
3224 const HttpResponseInfo* response = trans->GetResponseInfo();
3225 ASSERT_TRUE(response);
3226 ASSERT_TRUE(response->headers);
3227 EXPECT_TRUE(response->headers->IsKeepAlive());
3228 EXPECT_EQ(407, response->headers->response_code());
3229 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3230 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3231 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3232
3233 std::string response_data;
3234 rv = ReadTransaction(trans.get(), &response_data);
3235 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3236
3237 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3238 session->CloseAllConnections();
3239}
3240
[email protected]8fdbcd22010-05-05 02:54:523241// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3242// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:023243TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523244 HttpRequestInfo request;
3245 request.method = "GET";
bncce36dca22015-04-21 22:11:233246 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523247 request.load_flags = 0;
3248
[email protected]cb9bf6ca2011-01-28 13:15:273249 // We are using a DIRECT connection (i.e. no proxy) for this session.
mmenkee65e7af2015-10-13 17:16:423250 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273251 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:413252 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:273253
[email protected]8fdbcd22010-05-05 02:54:523254 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233255 MockWrite(
3256 "GET / HTTP/1.1\r\n"
3257 "Host: www.example.org\r\n"
3258 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523259 };
3260
3261 MockRead data_reads1[] = {
3262 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3263 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3264 // Large content-length -- won't matter, as connection will be reset.
3265 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063266 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523267 };
3268
3269 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3270 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073271 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523272
[email protected]49639fa2011-12-20 23:22:413273 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523274
[email protected]49639fa2011-12-20 23:22:413275 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523276 EXPECT_EQ(ERR_IO_PENDING, rv);
3277
3278 rv = callback.WaitForResult();
3279 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3280}
3281
[email protected]7a67a8152010-11-05 18:31:103282// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3283// through a non-authenticating proxy. The request should fail with
3284// ERR_UNEXPECTED_PROXY_AUTH.
3285// Note that it is impossible to detect if an HTTP server returns a 407 through
3286// a non-authenticating proxy - there is nothing to indicate whether the
3287// response came from the proxy or the server, so it is treated as if the proxy
3288// issued the challenge.
[email protected]23e482282013-06-14 16:08:023289TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233290 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273291 HttpRequestInfo request;
3292 request.method = "GET";
bncce36dca22015-04-21 22:11:233293 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273294
rdsmith82957ad2015-09-16 19:42:033295 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513296 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073297 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423298 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103299
[email protected]7a67a8152010-11-05 18:31:103300 // Since we have proxy, should try to establish tunnel.
3301 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173302 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3303 "Host: www.example.org:443\r\n"
3304 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103305
rsleevidb16bb02015-11-12 23:47:173306 MockWrite("GET / HTTP/1.1\r\n"
3307 "Host: www.example.org\r\n"
3308 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103309 };
3310
3311 MockRead data_reads1[] = {
3312 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3313
3314 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3315 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3316 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063317 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103318 };
3319
3320 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3321 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073322 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063323 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103325
[email protected]49639fa2011-12-20 23:22:413326 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103327
[email protected]262eec82013-03-19 21:01:363328 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503329 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103330
[email protected]49639fa2011-12-20 23:22:413331 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103332 EXPECT_EQ(ERR_IO_PENDING, rv);
3333
3334 rv = callback1.WaitForResult();
3335 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463336 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403337 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103338 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403339 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103340 NetLog::PHASE_NONE);
3341 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403342 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103343 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3344 NetLog::PHASE_NONE);
3345}
[email protected]2df19bb2010-08-25 20:13:463346
mmenke2a1781d2015-10-07 19:25:333347// Test a proxy auth scheme that allows default credentials and a proxy server
3348// that uses non-persistent connections.
3349TEST_P(HttpNetworkTransactionTest,
3350 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3351 HttpRequestInfo request;
3352 request.method = "GET";
3353 request.url = GURL("https://www.example.org/");
3354
3355 // Configure against proxy server "myproxy:70".
3356 session_deps_.proxy_service =
3357 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3358
3359 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3360 new HttpAuthHandlerMock::Factory());
3361 auth_handler_factory->set_do_init_from_challenge(true);
3362 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3363 mock_handler->set_allows_default_credentials(true);
3364 auth_handler_factory->AddMockHandler(mock_handler.release(),
3365 HttpAuth::AUTH_PROXY);
3366 session_deps_.http_auth_handler_factory = auth_handler_factory.Pass();
3367
3368 // Add NetLog just so can verify load timing information gets a NetLog ID.
3369 NetLog net_log;
3370 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423371 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333372
3373 // Since we have proxy, should try to establish tunnel.
3374 MockWrite data_writes1[] = {
3375 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173376 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333377 "Proxy-Connection: keep-alive\r\n\r\n"),
3378 };
3379
3380 // The proxy responds to the connect with a 407, using a non-persistent
3381 // connection.
3382 MockRead data_reads1[] = {
3383 // No credentials.
3384 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3385 MockRead("Proxy-Authenticate: Mock\r\n"),
3386 MockRead("Proxy-Connection: close\r\n\r\n"),
3387 };
3388
3389 // Since the first connection couldn't be reused, need to establish another
3390 // once given credentials.
3391 MockWrite data_writes2[] = {
3392 // After calling trans->RestartWithAuth(), this is the request we should
3393 // be issuing -- the final header line contains the credentials.
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"
mmenke2a1781d2015-10-07 19:25:333396 "Proxy-Connection: keep-alive\r\n"
3397 "Proxy-Authorization: auth_token\r\n\r\n"),
3398
3399 MockWrite("GET / HTTP/1.1\r\n"
3400 "Host: www.example.org\r\n"
3401 "Connection: keep-alive\r\n\r\n"),
3402 };
3403
3404 MockRead data_reads2[] = {
3405 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3406
3407 MockRead("HTTP/1.1 200 OK\r\n"),
3408 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3409 MockRead("Content-Length: 5\r\n\r\n"),
3410 MockRead(SYNCHRONOUS, "hello"),
3411 };
3412
3413 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3414 data_writes1, arraysize(data_writes1));
3415 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3416 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3417 data_writes2, arraysize(data_writes2));
3418 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3419 SSLSocketDataProvider ssl(ASYNC, OK);
3420 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3421
3422 scoped_ptr<HttpTransaction> trans(
3423 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3424
3425 TestCompletionCallback callback;
3426 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3427 EXPECT_EQ(OK, callback.GetResult(rv));
3428
3429 const HttpResponseInfo* response = trans->GetResponseInfo();
3430 ASSERT_TRUE(response);
3431 ASSERT_TRUE(response->headers);
3432 EXPECT_FALSE(response->headers->IsKeepAlive());
3433 EXPECT_EQ(407, response->headers->response_code());
3434 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3435 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3436 EXPECT_FALSE(response->auth_challenge.get());
3437
3438 LoadTimingInfo load_timing_info;
3439 // CONNECT requests and responses are handled at the connect job level, so
3440 // the transaction does not yet have a connection.
3441 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3442
3443 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3444 EXPECT_EQ(OK, callback.GetResult(rv));
3445 response = trans->GetResponseInfo();
3446 ASSERT_TRUE(response);
3447 ASSERT_TRUE(response->headers);
3448 EXPECT_TRUE(response->headers->IsKeepAlive());
3449 EXPECT_EQ(200, response->headers->response_code());
3450 EXPECT_EQ(5, response->headers->GetContentLength());
3451 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3452
3453 // The password prompt info should not be set.
3454 EXPECT_FALSE(response->auth_challenge);
3455
3456 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3457 TestLoadTimingNotReusedWithPac(load_timing_info,
3458 CONNECT_TIMING_HAS_SSL_TIMES);
3459
3460 trans.reset();
3461 session->CloseAllConnections();
3462}
3463
3464// Test a proxy auth scheme that allows default credentials and a proxy server
3465// that hangs up when credentials are initially sent.
3466TEST_P(HttpNetworkTransactionTest,
3467 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3468 HttpRequestInfo request;
3469 request.method = "GET";
3470 request.url = GURL("https://www.example.org/");
3471
3472 // Configure against proxy server "myproxy:70".
3473 session_deps_.proxy_service =
3474 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3475
3476 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3477 new HttpAuthHandlerMock::Factory());
3478 auth_handler_factory->set_do_init_from_challenge(true);
3479 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3480 mock_handler->set_allows_default_credentials(true);
3481 auth_handler_factory->AddMockHandler(mock_handler.release(),
3482 HttpAuth::AUTH_PROXY);
3483 session_deps_.http_auth_handler_factory = auth_handler_factory.Pass();
3484
3485 // Add NetLog just so can verify load timing information gets a NetLog ID.
3486 NetLog net_log;
3487 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423488 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333489
3490 // Should try to establish tunnel.
3491 MockWrite data_writes1[] = {
3492 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173493 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333494 "Proxy-Connection: keep-alive\r\n\r\n"),
3495
3496 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173497 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333498 "Proxy-Connection: keep-alive\r\n"
3499 "Proxy-Authorization: auth_token\r\n\r\n"),
3500 };
3501
3502 // The proxy responds to the connect with a 407, using a non-persistent
3503 // connection.
3504 MockRead data_reads1[] = {
3505 // No credentials.
3506 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3507 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3508 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3509 };
3510
3511 // Since the first connection was closed, need to establish another once given
3512 // credentials.
3513 MockWrite data_writes2[] = {
3514 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173515 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333516 "Proxy-Connection: keep-alive\r\n"
3517 "Proxy-Authorization: auth_token\r\n\r\n"),
3518
3519 MockWrite("GET / HTTP/1.1\r\n"
3520 "Host: www.example.org\r\n"
3521 "Connection: keep-alive\r\n\r\n"),
3522 };
3523
3524 MockRead data_reads2[] = {
3525 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3526
3527 MockRead("HTTP/1.1 200 OK\r\n"),
3528 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3529 MockRead("Content-Length: 5\r\n\r\n"),
3530 MockRead(SYNCHRONOUS, "hello"),
3531 };
3532
3533 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3534 data_writes1, arraysize(data_writes1));
3535 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3536 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3537 data_writes2, arraysize(data_writes2));
3538 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3539 SSLSocketDataProvider ssl(ASYNC, OK);
3540 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3541
3542 scoped_ptr<HttpTransaction> trans(
3543 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3544
3545 TestCompletionCallback callback;
3546 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3547 EXPECT_EQ(OK, callback.GetResult(rv));
3548
3549 const HttpResponseInfo* response = trans->GetResponseInfo();
3550 ASSERT_TRUE(response);
3551 ASSERT_TRUE(response->headers);
3552 EXPECT_TRUE(response->headers->IsKeepAlive());
3553 EXPECT_EQ(407, response->headers->response_code());
3554 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3555 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3556 EXPECT_FALSE(response->auth_challenge);
3557
3558 LoadTimingInfo load_timing_info;
3559 // CONNECT requests and responses are handled at the connect job level, so
3560 // the transaction does not yet have a connection.
3561 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3562
3563 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3564 EXPECT_EQ(OK, callback.GetResult(rv));
3565
3566 response = trans->GetResponseInfo();
3567 ASSERT_TRUE(response);
3568 ASSERT_TRUE(response->headers);
3569 EXPECT_TRUE(response->headers->IsKeepAlive());
3570 EXPECT_EQ(200, response->headers->response_code());
3571 EXPECT_EQ(5, response->headers->GetContentLength());
3572 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3573
3574 // The password prompt info should not be set.
3575 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3576
3577 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3578 TestLoadTimingNotReusedWithPac(load_timing_info,
3579 CONNECT_TIMING_HAS_SSL_TIMES);
3580
3581 trans.reset();
3582 session->CloseAllConnections();
3583}
3584
3585// Test a proxy auth scheme that allows default credentials and a proxy server
3586// that hangs up when credentials are initially sent, and hangs up again when
3587// they are retried.
3588TEST_P(HttpNetworkTransactionTest,
3589 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
3590 HttpRequestInfo request;
3591 request.method = "GET";
3592 request.url = GURL("https://www.example.org/");
3593
3594 // Configure against proxy server "myproxy:70".
3595 session_deps_.proxy_service =
3596 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3597
3598 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3599 new HttpAuthHandlerMock::Factory());
3600 auth_handler_factory->set_do_init_from_challenge(true);
3601 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3602 mock_handler->set_allows_default_credentials(true);
3603 auth_handler_factory->AddMockHandler(mock_handler.release(),
3604 HttpAuth::AUTH_PROXY);
3605 session_deps_.http_auth_handler_factory = auth_handler_factory.Pass();
3606
3607 // Add NetLog just so can verify load timing information gets a NetLog ID.
3608 NetLog net_log;
3609 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423610 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333611
3612 // Should try to establish tunnel.
3613 MockWrite data_writes1[] = {
3614 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173615 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333616 "Proxy-Connection: keep-alive\r\n\r\n"),
3617
3618 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173619 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333620 "Proxy-Connection: keep-alive\r\n"
3621 "Proxy-Authorization: auth_token\r\n\r\n"),
3622 };
3623
3624 // The proxy responds to the connect with a 407, and then hangs up after the
3625 // second request is sent.
3626 MockRead data_reads1[] = {
3627 // No credentials.
3628 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3629 MockRead("Content-Length: 0\r\n"),
3630 MockRead("Proxy-Connection: keep-alive\r\n"),
3631 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3632 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3633 };
3634
3635 // HttpNetworkTransaction sees a reused connection that was closed with
3636 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
3637 // request.
3638 MockWrite data_writes2[] = {
3639 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173640 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333641 "Proxy-Connection: keep-alive\r\n\r\n"),
3642 };
3643
3644 // The proxy, having had more than enough of us, just hangs up.
3645 MockRead data_reads2[] = {
3646 // No credentials.
3647 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3648 };
3649
3650 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3651 data_writes1, arraysize(data_writes1));
3652 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3653 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3654 data_writes2, arraysize(data_writes2));
3655 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3656
3657 scoped_ptr<HttpTransaction> trans(
3658 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3659
3660 TestCompletionCallback callback;
3661 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3662 EXPECT_EQ(OK, callback.GetResult(rv));
3663
3664 const HttpResponseInfo* response = trans->GetResponseInfo();
3665 ASSERT_TRUE(response);
3666 ASSERT_TRUE(response->headers);
3667 EXPECT_TRUE(response->headers->IsKeepAlive());
3668 EXPECT_EQ(407, response->headers->response_code());
3669 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3670 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3671 EXPECT_FALSE(response->auth_challenge);
3672
3673 LoadTimingInfo load_timing_info;
3674 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3675
3676 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3677 EXPECT_EQ(ERR_EMPTY_RESPONSE, callback.GetResult(rv));
3678
3679 trans.reset();
3680 session->CloseAllConnections();
3681}
3682
3683// Test a proxy auth scheme that allows default credentials and a proxy server
3684// that hangs up when credentials are initially sent, and sends a challenge
3685// again they are retried.
3686TEST_P(HttpNetworkTransactionTest,
3687 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
3688 HttpRequestInfo request;
3689 request.method = "GET";
3690 request.url = GURL("https://www.example.org/");
3691
3692 // Configure against proxy server "myproxy:70".
3693 session_deps_.proxy_service =
3694 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3695
3696 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3697 new HttpAuthHandlerMock::Factory());
3698 auth_handler_factory->set_do_init_from_challenge(true);
3699 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3700 mock_handler->set_allows_default_credentials(true);
3701 auth_handler_factory->AddMockHandler(mock_handler.release(),
3702 HttpAuth::AUTH_PROXY);
3703 // Add another handler for the second challenge. It supports default
3704 // credentials, but they shouldn't be used, since they were already tried.
3705 mock_handler.reset(new HttpAuthHandlerMock());
3706 mock_handler->set_allows_default_credentials(true);
3707 auth_handler_factory->AddMockHandler(mock_handler.release(),
3708 HttpAuth::AUTH_PROXY);
3709 session_deps_.http_auth_handler_factory = auth_handler_factory.Pass();
3710
3711 // Add NetLog just so can verify load timing information gets a NetLog ID.
3712 NetLog net_log;
3713 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423714 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333715
3716 // Should try to establish tunnel.
3717 MockWrite data_writes1[] = {
3718 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173719 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333720 "Proxy-Connection: keep-alive\r\n\r\n"),
3721 };
3722
3723 // The proxy responds to the connect with a 407, using a non-persistent
3724 // connection.
3725 MockRead data_reads1[] = {
3726 // No credentials.
3727 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3728 MockRead("Proxy-Authenticate: Mock\r\n"),
3729 MockRead("Proxy-Connection: close\r\n\r\n"),
3730 };
3731
3732 // Since the first connection was closed, need to establish another once given
3733 // credentials.
3734 MockWrite data_writes2[] = {
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
3741 MockRead data_reads2[] = {
3742 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3743 MockRead("Proxy-Authenticate: Mock\r\n"),
3744 MockRead("Proxy-Connection: close\r\n\r\n"),
3745 };
3746
3747 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3748 data_writes1, arraysize(data_writes1));
3749 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3750 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3751 data_writes2, arraysize(data_writes2));
3752 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3753 SSLSocketDataProvider ssl(ASYNC, OK);
3754 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3755
3756 scoped_ptr<HttpTransaction> trans(
3757 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3758
3759 TestCompletionCallback callback;
3760 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3761 EXPECT_EQ(OK, callback.GetResult(rv));
3762
3763 const HttpResponseInfo* response = trans->GetResponseInfo();
3764 ASSERT_TRUE(response);
3765 ASSERT_TRUE(response->headers);
3766 EXPECT_EQ(407, response->headers->response_code());
3767 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3768 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3769 EXPECT_FALSE(response->auth_challenge);
3770
3771 LoadTimingInfo load_timing_info;
3772 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3773
3774 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3775 EXPECT_EQ(OK, callback.GetResult(rv));
3776 response = trans->GetResponseInfo();
3777 ASSERT_TRUE(response);
3778 ASSERT_TRUE(response->headers);
3779 EXPECT_EQ(407, response->headers->response_code());
3780 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3781 EXPECT_TRUE(response->auth_challenge);
3782
3783 trans.reset();
3784 session->CloseAllConnections();
3785}
3786
[email protected]029c83b62013-01-24 05:28:203787// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023788TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203789 HttpRequestInfo request1;
3790 request1.method = "GET";
bncce36dca22015-04-21 22:11:233791 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203792
3793 HttpRequestInfo request2;
3794 request2.method = "GET";
bncce36dca22015-04-21 22:11:233795 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203796
3797 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033798 session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513799 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073800 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423801 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203802
3803 // Since we have proxy, should try to establish tunnel.
3804 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173805 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3806 "Host: www.example.org:443\r\n"
3807 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203808
rsleevidb16bb02015-11-12 23:47:173809 MockWrite("GET /1 HTTP/1.1\r\n"
3810 "Host: www.example.org\r\n"
3811 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203812
rsleevidb16bb02015-11-12 23:47:173813 MockWrite("GET /2 HTTP/1.1\r\n"
3814 "Host: www.example.org\r\n"
3815 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203816 };
3817
3818 // The proxy responds to the connect with a 407, using a persistent
3819 // connection.
3820 MockRead data_reads1[] = {
3821 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3822
3823 MockRead("HTTP/1.1 200 OK\r\n"),
3824 MockRead("Content-Length: 1\r\n\r\n"),
3825 MockRead(SYNCHRONOUS, "1"),
3826
3827 MockRead("HTTP/1.1 200 OK\r\n"),
3828 MockRead("Content-Length: 2\r\n\r\n"),
3829 MockRead(SYNCHRONOUS, "22"),
3830 };
3831
3832 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3833 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073834 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203835 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073836 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203837
3838 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363839 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503840 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203841
3842 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3843 EXPECT_EQ(ERR_IO_PENDING, rv);
3844
3845 rv = callback1.WaitForResult();
3846 EXPECT_EQ(OK, rv);
3847
3848 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3849 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503850 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203851 EXPECT_EQ(1, response1->headers->GetContentLength());
3852
3853 LoadTimingInfo load_timing_info1;
3854 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3855 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3856
3857 trans1.reset();
3858
3859 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363860 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503861 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203862
3863 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3864 EXPECT_EQ(ERR_IO_PENDING, rv);
3865
3866 rv = callback2.WaitForResult();
3867 EXPECT_EQ(OK, rv);
3868
3869 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3870 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503871 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203872 EXPECT_EQ(2, response2->headers->GetContentLength());
3873
3874 LoadTimingInfo load_timing_info2;
3875 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3876 TestLoadTimingReused(load_timing_info2);
3877
3878 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3879
3880 trans2.reset();
3881 session->CloseAllConnections();
3882}
3883
3884// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023885TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203886 HttpRequestInfo request1;
3887 request1.method = "GET";
bncce36dca22015-04-21 22:11:233888 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203889
3890 HttpRequestInfo request2;
3891 request2.method = "GET";
bncce36dca22015-04-21 22:11:233892 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203893
3894 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033895 session_deps_.proxy_service =
3896 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513897 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073898 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423899 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203900
3901 // Since we have proxy, should try to establish tunnel.
3902 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173903 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3904 "Host: www.example.org:443\r\n"
3905 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203906
rsleevidb16bb02015-11-12 23:47:173907 MockWrite("GET /1 HTTP/1.1\r\n"
3908 "Host: www.example.org\r\n"
3909 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203910
rsleevidb16bb02015-11-12 23:47:173911 MockWrite("GET /2 HTTP/1.1\r\n"
3912 "Host: www.example.org\r\n"
3913 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203914 };
3915
3916 // The proxy responds to the connect with a 407, using a persistent
3917 // connection.
3918 MockRead data_reads1[] = {
3919 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3920
3921 MockRead("HTTP/1.1 200 OK\r\n"),
3922 MockRead("Content-Length: 1\r\n\r\n"),
3923 MockRead(SYNCHRONOUS, "1"),
3924
3925 MockRead("HTTP/1.1 200 OK\r\n"),
3926 MockRead("Content-Length: 2\r\n\r\n"),
3927 MockRead(SYNCHRONOUS, "22"),
3928 };
3929
3930 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3931 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073932 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203933 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073934 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203935
3936 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363937 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503938 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203939
3940 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3941 EXPECT_EQ(ERR_IO_PENDING, rv);
3942
3943 rv = callback1.WaitForResult();
3944 EXPECT_EQ(OK, rv);
3945
3946 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3947 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503948 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203949 EXPECT_EQ(1, response1->headers->GetContentLength());
3950
3951 LoadTimingInfo load_timing_info1;
3952 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3953 TestLoadTimingNotReusedWithPac(load_timing_info1,
3954 CONNECT_TIMING_HAS_SSL_TIMES);
3955
3956 trans1.reset();
3957
3958 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363959 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503960 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203961
3962 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3963 EXPECT_EQ(ERR_IO_PENDING, rv);
3964
3965 rv = callback2.WaitForResult();
3966 EXPECT_EQ(OK, rv);
3967
3968 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3969 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503970 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203971 EXPECT_EQ(2, response2->headers->GetContentLength());
3972
3973 LoadTimingInfo load_timing_info2;
3974 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3975 TestLoadTimingReusedWithPac(load_timing_info2);
3976
3977 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3978
3979 trans2.reset();
3980 session->CloseAllConnections();
3981}
3982
[email protected]2df19bb2010-08-25 20:13:463983// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023984TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273985 HttpRequestInfo request;
3986 request.method = "GET";
bncce36dca22015-04-21 22:11:233987 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273988
[email protected]2df19bb2010-08-25 20:13:463989 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:033990 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:513991 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073992 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423993 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463994
[email protected]2df19bb2010-08-25 20:13:463995 // Since we have proxy, should use full url
3996 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233997 MockWrite(
3998 "GET http://www.example.org/ HTTP/1.1\r\n"
3999 "Host: www.example.org\r\n"
4000 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464001 };
4002
4003 MockRead data_reads1[] = {
4004 MockRead("HTTP/1.1 200 OK\r\n"),
4005 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4006 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064007 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464008 };
4009
4010 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4011 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074012 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064013 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074014 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464015
[email protected]49639fa2011-12-20 23:22:414016 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464017
[email protected]262eec82013-03-19 21:01:364018 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504019 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504020
[email protected]49639fa2011-12-20 23:22:414021 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464022 EXPECT_EQ(ERR_IO_PENDING, rv);
4023
4024 rv = callback1.WaitForResult();
4025 EXPECT_EQ(OK, rv);
4026
[email protected]58e32bb2013-01-21 18:23:254027 LoadTimingInfo load_timing_info;
4028 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4029 TestLoadTimingNotReused(load_timing_info,
4030 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4031
[email protected]2df19bb2010-08-25 20:13:464032 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504033 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464034
4035 EXPECT_TRUE(response->headers->IsKeepAlive());
4036 EXPECT_EQ(200, response->headers->response_code());
4037 EXPECT_EQ(100, response->headers->GetContentLength());
4038 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4039
4040 // The password prompt info should not be set.
4041 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4042}
4043
[email protected]7642b5ae2010-09-01 20:55:174044// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024045TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274046 HttpRequestInfo request;
4047 request.method = "GET";
bncce36dca22015-04-21 22:11:234048 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274049 request.load_flags = 0;
4050
[email protected]7642b5ae2010-09-01 20:55:174051 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034052 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514053 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074054 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424055 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174056
bncce36dca22015-04-21 22:11:234057 // fetch http://www.example.org/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:464058 scoped_ptr<SpdyFrame> req(
4059 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134060 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174061
[email protected]23e482282013-06-14 16:08:024062 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4063 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174064 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134065 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174066 };
4067
rch8e6c6c42015-05-01 14:05:134068 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4069 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074070 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174071
[email protected]8ddf8322012-02-23 18:08:064072 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384073 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074074 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174075
[email protected]49639fa2011-12-20 23:22:414076 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174077
[email protected]262eec82013-03-19 21:01:364078 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504080
[email protected]49639fa2011-12-20 23:22:414081 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:174082 EXPECT_EQ(ERR_IO_PENDING, rv);
4083
4084 rv = callback1.WaitForResult();
4085 EXPECT_EQ(OK, rv);
4086
[email protected]58e32bb2013-01-21 18:23:254087 LoadTimingInfo load_timing_info;
4088 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4089 TestLoadTimingNotReused(load_timing_info,
4090 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4091
[email protected]7642b5ae2010-09-01 20:55:174092 const HttpResponseInfo* response = trans->GetResponseInfo();
4093 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504094 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:024095 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174096
4097 std::string response_data;
4098 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234099 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174100}
4101
[email protected]1c173852014-06-19 12:51:504102// Verifies that a session which races and wins against the owning transaction
4103// (completing prior to host resolution), doesn't fail the transaction.
4104// Regression test for crbug.com/334413.
4105TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
4106 HttpRequestInfo request;
4107 request.method = "GET";
bncce36dca22015-04-21 22:11:234108 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504109 request.load_flags = 0;
4110
4111 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034112 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514113 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504114 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424115 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504116
bncce36dca22015-04-21 22:11:234117 // Fetch http://www.example.org/ through the SPDY proxy.
[email protected]1c173852014-06-19 12:51:504118 scoped_ptr<SpdyFrame> req(
4119 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134120 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:504121
4122 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4123 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
4124 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134125 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504126 };
4127
rch8e6c6c42015-05-01 14:05:134128 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4129 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504130 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4131
4132 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384133 ssl.SetNextProto(GetProtocol());
[email protected]1c173852014-06-19 12:51:504134 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4135
4136 TestCompletionCallback callback1;
4137
4138 scoped_ptr<HttpTransaction> trans(
4139 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4140
4141 // Stall the hostname resolution begun by the transaction.
4142 session_deps_.host_resolver->set_synchronous_mode(false);
4143 session_deps_.host_resolver->set_ondemand_mode(true);
4144
4145 int rv = trans->Start(&request, callback1.callback(), log.bound());
4146 EXPECT_EQ(ERR_IO_PENDING, rv);
4147
4148 // Race a session to the proxy, which completes first.
4149 session_deps_.host_resolver->set_ondemand_mode(false);
4150 SpdySessionKey key(
4151 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4152 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424153 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504154
4155 // Unstall the resolution begun by the transaction.
4156 session_deps_.host_resolver->set_ondemand_mode(true);
4157 session_deps_.host_resolver->ResolveAllPending();
4158
4159 EXPECT_FALSE(callback1.have_result());
4160 rv = callback1.WaitForResult();
4161 EXPECT_EQ(OK, rv);
4162
4163 const HttpResponseInfo* response = trans->GetResponseInfo();
4164 ASSERT_TRUE(response != NULL);
4165 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:024166 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504167
4168 std::string response_data;
4169 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4170 EXPECT_EQ(kUploadData, response_data);
4171}
4172
[email protected]dc7bd1c52010-11-12 00:01:134173// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024174TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274175 HttpRequestInfo request;
4176 request.method = "GET";
bncce36dca22015-04-21 22:11:234177 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274178 request.load_flags = 0;
4179
[email protected]79cb5c12011-09-12 13:12:044180 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034181 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514182 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074183 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424184 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134185
[email protected]dc7bd1c52010-11-12 00:01:134186 // The first request will be a bare GET, the second request will be a
4187 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:194188 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:464189 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384190 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134191 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464192 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134193 };
[email protected]ff98d7f02012-03-22 21:44:194194 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:464195 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
4196 arraysize(kExtraAuthorizationHeaders) / 2,
4197 false,
4198 3,
4199 LOWEST,
4200 false));
[email protected]dc7bd1c52010-11-12 00:01:134201 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134202 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134203 };
4204
4205 // The first response is a 407 proxy authentication challenge, and the second
4206 // response will be a 200 response since the second request includes a valid
4207 // Authorization header.
4208 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464209 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134210 };
[email protected]ff98d7f02012-03-22 21:44:194211 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:024212 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:134213 "407 Proxy Authentication Required",
4214 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
4215 1));
[email protected]ff98d7f02012-03-22 21:44:194216 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:024217 spdy_util_.ConstructSpdyBodyFrame(1, true));
4218 scoped_ptr<SpdyFrame> resp_data(
4219 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4220 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134221 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134222 CreateMockRead(*resp_authentication, 1),
4223 CreateMockRead(*body_authentication, 2),
4224 CreateMockRead(*resp_data, 4),
4225 CreateMockRead(*body_data, 5),
4226 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134227 };
4228
rch8e6c6c42015-05-01 14:05:134229 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4230 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074231 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134232
[email protected]8ddf8322012-02-23 18:08:064233 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384234 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074235 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134236
[email protected]49639fa2011-12-20 23:22:414237 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134238
[email protected]262eec82013-03-19 21:01:364239 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504240 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:134241
[email protected]49639fa2011-12-20 23:22:414242 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:134243 EXPECT_EQ(ERR_IO_PENDING, rv);
4244
4245 rv = callback1.WaitForResult();
4246 EXPECT_EQ(OK, rv);
4247
4248 const HttpResponseInfo* const response = trans->GetResponseInfo();
4249
4250 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504251 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:134252 EXPECT_EQ(407, response->headers->response_code());
4253 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:044254 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134255
[email protected]49639fa2011-12-20 23:22:414256 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134257
[email protected]49639fa2011-12-20 23:22:414258 rv = trans->RestartWithAuth(
4259 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:134260 EXPECT_EQ(ERR_IO_PENDING, rv);
4261
4262 rv = callback2.WaitForResult();
4263 EXPECT_EQ(OK, rv);
4264
4265 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
4266
4267 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:504268 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:134269 EXPECT_EQ(200, response_restart->headers->response_code());
4270 // The password prompt info should not be set.
4271 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
4272}
4273
[email protected]d9da5fe2010-10-13 22:37:164274// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:024275TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274276 HttpRequestInfo request;
4277 request.method = "GET";
bncce36dca22015-04-21 22:11:234278 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274279 request.load_flags = 0;
4280
[email protected]d9da5fe2010-10-13 22:37:164281 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034282 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514283 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074284 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424285 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164286
[email protected]262eec82013-03-19 21:01:364287 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504288 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164289
bncce36dca22015-04-21 22:11:234290 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:344291 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234292 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4293 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164294
bncce36dca22015-04-21 22:11:234295 const char get[] =
4296 "GET / HTTP/1.1\r\n"
4297 "Host: www.example.org\r\n"
4298 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:194299 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:024300 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
4301 scoped_ptr<SpdyFrame> conn_resp(
4302 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164303 const char resp[] = "HTTP/1.1 200 OK\r\n"
4304 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:194305 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024306 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:194307 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:024308 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:194309 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204310 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:044311
4312 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134313 CreateMockWrite(*connect, 0),
4314 CreateMockWrite(*wrapped_get, 2),
4315 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044316 };
4317
[email protected]d9da5fe2010-10-13 22:37:164318 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134319 CreateMockRead(*conn_resp, 1, ASYNC),
4320 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
4321 CreateMockRead(*wrapped_body, 4, ASYNC),
4322 CreateMockRead(*wrapped_body, 5, ASYNC),
4323 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164324 };
4325
rch8e6c6c42015-05-01 14:05:134326 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4327 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074328 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164329
[email protected]8ddf8322012-02-23 18:08:064330 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384331 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074332 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064333 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074334 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164335
[email protected]49639fa2011-12-20 23:22:414336 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164337
[email protected]49639fa2011-12-20 23:22:414338 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164339 EXPECT_EQ(ERR_IO_PENDING, rv);
4340
4341 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:134342 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:164343
[email protected]58e32bb2013-01-21 18:23:254344 LoadTimingInfo load_timing_info;
4345 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4346 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4347
[email protected]d9da5fe2010-10-13 22:37:164348 const HttpResponseInfo* response = trans->GetResponseInfo();
4349 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504350 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:164351 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4352
4353 std::string response_data;
4354 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4355 EXPECT_EQ("1234567890", response_data);
4356}
4357
4358// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:024359TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
rdsmithebb50aa2015-11-12 03:44:384360 SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
4361
[email protected]cb9bf6ca2011-01-28 13:15:274362 HttpRequestInfo request;
4363 request.method = "GET";
bncce36dca22015-04-21 22:11:234364 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274365 request.load_flags = 0;
4366
[email protected]d9da5fe2010-10-13 22:37:164367 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034368 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514369 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074370 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424371 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164372
[email protected]262eec82013-03-19 21:01:364373 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504374 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164375
bncce36dca22015-04-21 22:11:234376 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:344377 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234378 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4379 // fetch https://www.example.org/ via SPDY
4380 const char kMyUrl[] = "https://www.example.org/";
[email protected]cdf8f7e72013-05-23 10:56:464381 scoped_ptr<SpdyFrame> get(
rdsmithebb50aa2015-11-12 03:44:384382 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:024383 scoped_ptr<SpdyFrame> wrapped_get(
4384 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
4385 scoped_ptr<SpdyFrame> conn_resp(
4386 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4387 scoped_ptr<SpdyFrame> get_resp(
rdsmithebb50aa2015-11-12 03:44:384388 spdy_util_wrapped.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:194389 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024390 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
rdsmithebb50aa2015-11-12 03:44:384391 scoped_ptr<SpdyFrame> body(spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
[email protected]23e482282013-06-14 16:08:024392 scoped_ptr<SpdyFrame> wrapped_body(
4393 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:194394 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:204395 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:194396 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:204397 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:044398
4399 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:094400 CreateMockWrite(*connect, 0),
4401 CreateMockWrite(*wrapped_get, 2),
4402 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:044403 CreateMockWrite(*window_update_body, 7),
4404 };
4405
[email protected]d9da5fe2010-10-13 22:37:164406 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:094407 CreateMockRead(*conn_resp, 1, ASYNC),
4408 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:134409 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:094410 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134411 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164412 };
4413
rch32320842015-05-16 15:57:094414 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4415 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074416 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164417
[email protected]8ddf8322012-02-23 18:08:064418 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384419 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074420 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064421 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384422 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074423 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164424
[email protected]49639fa2011-12-20 23:22:414425 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164426
[email protected]49639fa2011-12-20 23:22:414427 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164428 EXPECT_EQ(ERR_IO_PENDING, rv);
4429
rch32320842015-05-16 15:57:094430 // Allow the SpdyProxyClientSocket's write callback to complete.
4431 base::MessageLoop::current()->RunUntilIdle();
4432 // Now allow the read of the response to complete.
4433 spdy_data.CompleteRead();
[email protected]d9da5fe2010-10-13 22:37:164434 rv = callback1.WaitForResult();
4435 EXPECT_EQ(OK, rv);
4436
[email protected]58e32bb2013-01-21 18:23:254437 LoadTimingInfo load_timing_info;
4438 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4439 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4440
[email protected]d9da5fe2010-10-13 22:37:164441 const HttpResponseInfo* response = trans->GetResponseInfo();
4442 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504443 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:024444 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:164445
4446 std::string response_data;
4447 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234448 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:164449}
4450
4451// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024452TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:274453 HttpRequestInfo request;
4454 request.method = "GET";
bncce36dca22015-04-21 22:11:234455 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274456 request.load_flags = 0;
4457
[email protected]d9da5fe2010-10-13 22:37:164458 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034459 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514460 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074461 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424462 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164463
[email protected]262eec82013-03-19 21:01:364464 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504465 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164466
bncce36dca22015-04-21 22:11:234467 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:344468 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234469 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:204470 scoped_ptr<SpdyFrame> get(
4471 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:164472
4473 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134474 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:164475 };
4476
[email protected]23e482282013-06-14 16:08:024477 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
4478 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:164479 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134480 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:164481 };
4482
rch8e6c6c42015-05-01 14:05:134483 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4484 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074485 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164486
[email protected]8ddf8322012-02-23 18:08:064487 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384488 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074489 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064490 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384491 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074492 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164493
[email protected]49639fa2011-12-20 23:22:414494 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164495
[email protected]49639fa2011-12-20 23:22:414496 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164497 EXPECT_EQ(ERR_IO_PENDING, rv);
4498
4499 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:174500 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:164501
[email protected]4eddbc732012-08-09 05:40:174502 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:164503}
4504
[email protected]f6c63db52013-02-02 00:35:224505// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4506// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024507TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224508 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
4509 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034510 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514511 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074512 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424513 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504514 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224515
4516 HttpRequestInfo request1;
4517 request1.method = "GET";
bncce36dca22015-04-21 22:11:234518 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224519 request1.load_flags = 0;
4520
4521 HttpRequestInfo request2;
4522 request2.method = "GET";
bncce36dca22015-04-21 22:11:234523 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224524 request2.load_flags = 0;
4525
bncce36dca22015-04-21 22:11:234526 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:344527 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234528 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:024529 scoped_ptr<SpdyFrame> conn_resp1(
4530 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224531
bncce36dca22015-04-21 22:11:234532 // Fetch https://www.example.org/ via HTTP.
4533 const char get1[] =
4534 "GET / HTTP/1.1\r\n"
4535 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224536 "Connection: keep-alive\r\n\r\n";
4537 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024538 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224539 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4540 "Content-Length: 1\r\n\r\n";
4541 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024542 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
4543 scoped_ptr<SpdyFrame> wrapped_body1(
4544 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:224545 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204546 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224547
bncce36dca22015-04-21 22:11:234548 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:294549 SpdyHeaderBlock connect2_block;
bnc7ecc1122015-09-28 13:22:494550 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]745aa9c2014-06-27 02:21:294551 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
rdsmithebb50aa2015-11-12 03:44:384552 if (GetProtocol() == kProtoHTTP2) {
bnc6b996d532015-07-29 10:51:324553 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
4554 } else {
bnc6b996d532015-07-29 10:51:324555 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
bnc7ecc1122015-09-28 13:22:494556 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
bnc6b996d532015-07-29 10:51:324557 }
[email protected]f6c63db52013-02-02 00:35:224558 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:294559 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:394560
[email protected]23e482282013-06-14 16:08:024561 scoped_ptr<SpdyFrame> conn_resp2(
4562 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:224563
bncce36dca22015-04-21 22:11:234564 // Fetch https://mail.example.org/ via HTTP.
4565 const char get2[] =
4566 "GET / HTTP/1.1\r\n"
4567 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224568 "Connection: keep-alive\r\n\r\n";
4569 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024570 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224571 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4572 "Content-Length: 2\r\n\r\n";
4573 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024574 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224575 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024576 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224577
4578 MockWrite spdy_writes[] = {
4579 CreateMockWrite(*connect1, 0),
4580 CreateMockWrite(*wrapped_get1, 2),
4581 CreateMockWrite(*connect2, 5),
4582 CreateMockWrite(*wrapped_get2, 7),
4583 };
4584
4585 MockRead spdy_reads[] = {
4586 CreateMockRead(*conn_resp1, 1, ASYNC),
4587 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4588 CreateMockRead(*wrapped_body1, 4, ASYNC),
4589 CreateMockRead(*conn_resp2, 6, ASYNC),
4590 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
4591 CreateMockRead(*wrapped_body2, 9, ASYNC),
4592 MockRead(ASYNC, 0, 10),
4593 };
4594
mmenke11eb5152015-06-09 14:50:504595 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4596 arraysize(spdy_writes));
4597 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224598
4599 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384600 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:504601 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224602 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504603 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224604 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504605 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:224606
4607 TestCompletionCallback callback;
4608
[email protected]262eec82013-03-19 21:01:364609 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504610 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224611 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504612 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224613
4614 LoadTimingInfo load_timing_info;
4615 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4616 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4617
4618 const HttpResponseInfo* response = trans->GetResponseInfo();
4619 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504620 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224621 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4622
4623 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294624 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504625 rv = trans->Read(buf.get(), 256, callback.callback());
4626 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224627
[email protected]262eec82013-03-19 21:01:364628 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504629 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224630 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504631 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224632
4633 LoadTimingInfo load_timing_info2;
4634 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4635 // Even though the SPDY connection is reused, a new tunnelled connection has
4636 // to be created, so the socket's load timing looks like a fresh connection.
4637 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
4638
4639 // The requests should have different IDs, since they each are using their own
4640 // separate stream.
4641 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4642
mmenke11eb5152015-06-09 14:50:504643 rv = trans2->Read(buf.get(), 256, callback.callback());
4644 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224645}
4646
4647// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4648// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:024649TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224650 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
4651 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034652 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514653 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074654 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424655 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504656 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224657
4658 HttpRequestInfo request1;
4659 request1.method = "GET";
bncce36dca22015-04-21 22:11:234660 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224661 request1.load_flags = 0;
4662
4663 HttpRequestInfo request2;
4664 request2.method = "GET";
bncce36dca22015-04-21 22:11:234665 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:224666 request2.load_flags = 0;
4667
bncce36dca22015-04-21 22:11:234668 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:344669 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234670 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:024671 scoped_ptr<SpdyFrame> conn_resp1(
4672 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224673
bncce36dca22015-04-21 22:11:234674 // Fetch https://www.example.org/ via HTTP.
4675 const char get1[] =
4676 "GET / HTTP/1.1\r\n"
4677 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224678 "Connection: keep-alive\r\n\r\n";
4679 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024680 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224681 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4682 "Content-Length: 1\r\n\r\n";
4683 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024684 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
4685 scoped_ptr<SpdyFrame> wrapped_body1(
4686 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:224687 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204688 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224689
bncce36dca22015-04-21 22:11:234690 // Fetch https://www.example.org/2 via HTTP.
4691 const char get2[] =
4692 "GET /2 HTTP/1.1\r\n"
4693 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224694 "Connection: keep-alive\r\n\r\n";
4695 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024696 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224697 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4698 "Content-Length: 2\r\n\r\n";
4699 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024700 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224701 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024702 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224703
4704 MockWrite spdy_writes[] = {
4705 CreateMockWrite(*connect1, 0),
4706 CreateMockWrite(*wrapped_get1, 2),
4707 CreateMockWrite(*wrapped_get2, 5),
4708 };
4709
4710 MockRead spdy_reads[] = {
4711 CreateMockRead(*conn_resp1, 1, ASYNC),
4712 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4713 CreateMockRead(*wrapped_body1, 4, ASYNC),
4714 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4715 CreateMockRead(*wrapped_body2, 7, ASYNC),
4716 MockRead(ASYNC, 0, 8),
4717 };
4718
mmenke11eb5152015-06-09 14:50:504719 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4720 arraysize(spdy_writes));
4721 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224722
4723 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384724 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:504725 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224726 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504727 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224728
4729 TestCompletionCallback callback;
4730
[email protected]262eec82013-03-19 21:01:364731 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504732 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224733 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4734 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:224735
4736 rv = callback.WaitForResult();
4737 EXPECT_EQ(OK, rv);
4738
4739 LoadTimingInfo load_timing_info;
4740 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4741 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4742
4743 const HttpResponseInfo* response = trans->GetResponseInfo();
4744 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504745 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224746 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4747
4748 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294749 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504750 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224751 trans.reset();
4752
[email protected]262eec82013-03-19 21:01:364753 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504754 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224755 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4756 EXPECT_EQ(ERR_IO_PENDING, rv);
4757
[email protected]f6c63db52013-02-02 00:35:224758 rv = callback.WaitForResult();
4759 EXPECT_EQ(OK, rv);
4760
4761 LoadTimingInfo load_timing_info2;
4762 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4763 TestLoadTimingReused(load_timing_info2);
4764
4765 // The requests should have the same ID.
4766 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4767
[email protected]90499482013-06-01 00:39:504768 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224769}
4770
4771// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4772// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:504773TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:224774 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034775 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514776 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074777 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424778 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504779 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224780
4781 HttpRequestInfo request1;
4782 request1.method = "GET";
bncce36dca22015-04-21 22:11:234783 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224784 request1.load_flags = 0;
4785
4786 HttpRequestInfo request2;
4787 request2.method = "GET";
bncce36dca22015-04-21 22:11:234788 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224789 request2.load_flags = 0;
4790
bncce36dca22015-04-21 22:11:234791 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024792 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234793 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294794 scoped_ptr<SpdyFrame> get1(
4795 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024796 scoped_ptr<SpdyFrame> get_resp1(
4797 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4798 scoped_ptr<SpdyFrame> body1(
4799 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:384800 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:224801
bncce36dca22015-04-21 22:11:234802 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024803 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234804 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294805 scoped_ptr<SpdyFrame> get2(
4806 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024807 scoped_ptr<SpdyFrame> get_resp2(
4808 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4809 scoped_ptr<SpdyFrame> body2(
4810 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224811
4812 MockWrite spdy_writes[] = {
4813 CreateMockWrite(*get1, 0),
4814 CreateMockWrite(*get2, 3),
4815 };
4816
4817 MockRead spdy_reads[] = {
4818 CreateMockRead(*get_resp1, 1, ASYNC),
4819 CreateMockRead(*body1, 2, ASYNC),
4820 CreateMockRead(*get_resp2, 4, ASYNC),
4821 CreateMockRead(*body2, 5, ASYNC),
4822 MockRead(ASYNC, 0, 6),
4823 };
4824
mmenke11eb5152015-06-09 14:50:504825 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4826 arraysize(spdy_writes));
4827 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224828
4829 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384830 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:504831 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224832
4833 TestCompletionCallback callback;
4834
[email protected]262eec82013-03-19 21:01:364835 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504836 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224837 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504838 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224839
4840 LoadTimingInfo load_timing_info;
4841 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4842 TestLoadTimingNotReused(load_timing_info,
4843 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4844
4845 const HttpResponseInfo* response = trans->GetResponseInfo();
4846 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504847 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:024848 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:224849
4850 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294851 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504852 rv = trans->Read(buf.get(), 256, callback.callback());
4853 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224854 // Delete the first request, so the second one can reuse the socket.
4855 trans.reset();
4856
[email protected]262eec82013-03-19 21:01:364857 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504858 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224859 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504860 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224861
4862 LoadTimingInfo load_timing_info2;
4863 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4864 TestLoadTimingReused(load_timing_info2);
4865
4866 // The requests should have the same ID.
4867 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4868
mmenke11eb5152015-06-09 14:50:504869 rv = trans2->Read(buf.get(), 256, callback.callback());
4870 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224871}
4872
[email protected]2df19bb2010-08-25 20:13:464873// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024874TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464875 HttpRequestInfo request;
4876 request.method = "GET";
bncce36dca22015-04-21 22:11:234877 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464878 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294879 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464880
[email protected]79cb5c12011-09-12 13:12:044881 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034882 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514883 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074884 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424885 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274886
[email protected]2df19bb2010-08-25 20:13:464887 // Since we have proxy, should use full url
4888 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234889 MockWrite(
4890 "GET http://www.example.org/ HTTP/1.1\r\n"
4891 "Host: www.example.org\r\n"
4892 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464893
bncce36dca22015-04-21 22:11:234894 // After calling trans->RestartWithAuth(), this is the request we should
4895 // be issuing -- the final header line contains the credentials.
4896 MockWrite(
4897 "GET http://www.example.org/ HTTP/1.1\r\n"
4898 "Host: www.example.org\r\n"
4899 "Proxy-Connection: keep-alive\r\n"
4900 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464901 };
4902
4903 // The proxy responds to the GET with a 407, using a persistent
4904 // connection.
4905 MockRead data_reads1[] = {
4906 // No credentials.
4907 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4908 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4909 MockRead("Proxy-Connection: keep-alive\r\n"),
4910 MockRead("Content-Length: 0\r\n\r\n"),
4911
4912 MockRead("HTTP/1.1 200 OK\r\n"),
4913 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4914 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064915 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464916 };
4917
4918 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4919 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074920 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064921 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074922 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464923
[email protected]49639fa2011-12-20 23:22:414924 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464925
[email protected]262eec82013-03-19 21:01:364926 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504927 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504928
[email protected]49639fa2011-12-20 23:22:414929 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464930 EXPECT_EQ(ERR_IO_PENDING, rv);
4931
4932 rv = callback1.WaitForResult();
4933 EXPECT_EQ(OK, rv);
4934
[email protected]58e32bb2013-01-21 18:23:254935 LoadTimingInfo load_timing_info;
4936 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4937 TestLoadTimingNotReused(load_timing_info,
4938 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4939
[email protected]2df19bb2010-08-25 20:13:464940 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504941 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504942 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464943 EXPECT_EQ(407, response->headers->response_code());
4944 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044945 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464946
[email protected]49639fa2011-12-20 23:22:414947 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464948
[email protected]49639fa2011-12-20 23:22:414949 rv = trans->RestartWithAuth(
4950 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464951 EXPECT_EQ(ERR_IO_PENDING, rv);
4952
4953 rv = callback2.WaitForResult();
4954 EXPECT_EQ(OK, rv);
4955
[email protected]58e32bb2013-01-21 18:23:254956 load_timing_info = LoadTimingInfo();
4957 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4958 // Retrying with HTTP AUTH is considered to be reusing a socket.
4959 TestLoadTimingReused(load_timing_info);
4960
[email protected]2df19bb2010-08-25 20:13:464961 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504962 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464963
4964 EXPECT_TRUE(response->headers->IsKeepAlive());
4965 EXPECT_EQ(200, response->headers->response_code());
4966 EXPECT_EQ(100, response->headers->GetContentLength());
4967 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4968
4969 // The password prompt info should not be set.
4970 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4971}
4972
[email protected]23e482282013-06-14 16:08:024973void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084974 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424975 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084976 request.method = "GET";
bncce36dca22015-04-21 22:11:234977 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084978 request.load_flags = 0;
4979
[email protected]cb9bf6ca2011-01-28 13:15:274980 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034981 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:424982 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274983
[email protected]c744cf22009-02-27 07:28:084984 // Since we have proxy, should try to establish tunnel.
4985 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:174986 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4987 "Host: www.example.org:443\r\n"
4988 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084989 };
4990
4991 MockRead data_reads[] = {
4992 status,
4993 MockRead("Content-Length: 10\r\n\r\n"),
4994 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064995 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084996 };
4997
[email protected]31a2bfe2010-02-09 08:03:394998 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4999 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075000 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085001
[email protected]49639fa2011-12-20 23:22:415002 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085003
[email protected]262eec82013-03-19 21:01:365004 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505005 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505006
[email protected]49639fa2011-12-20 23:22:415007 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425008 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:085009
5010 rv = callback.WaitForResult();
5011 EXPECT_EQ(expected_status, rv);
5012}
5013
[email protected]23e482282013-06-14 16:08:025014void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235015 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085016 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425017 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085018}
5019
[email protected]23e482282013-06-14 16:08:025020TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085021 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5022}
5023
[email protected]23e482282013-06-14 16:08:025024TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085025 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5026}
5027
[email protected]23e482282013-06-14 16:08:025028TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085029 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5030}
5031
[email protected]23e482282013-06-14 16:08:025032TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085033 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5034}
5035
[email protected]23e482282013-06-14 16:08:025036TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085037 ConnectStatusHelper(
5038 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5039}
5040
[email protected]23e482282013-06-14 16:08:025041TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085042 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5043}
5044
[email protected]23e482282013-06-14 16:08:025045TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085046 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5047}
5048
[email protected]23e482282013-06-14 16:08:025049TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085050 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5051}
5052
[email protected]23e482282013-06-14 16:08:025053TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085054 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5055}
5056
[email protected]23e482282013-06-14 16:08:025057TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085058 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5059}
5060
[email protected]23e482282013-06-14 16:08:025061TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085062 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5063}
5064
[email protected]23e482282013-06-14 16:08:025065TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085066 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5067}
5068
[email protected]23e482282013-06-14 16:08:025069TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085070 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5071}
5072
[email protected]23e482282013-06-14 16:08:025073TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085074 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5075}
5076
[email protected]23e482282013-06-14 16:08:025077TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085078 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5079}
5080
[email protected]23e482282013-06-14 16:08:025081TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085082 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5083}
5084
[email protected]0a17aab32014-04-24 03:32:375085TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
5086 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5087}
5088
[email protected]23e482282013-06-14 16:08:025089TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085090 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5091}
5092
[email protected]23e482282013-06-14 16:08:025093TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085094 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5095}
5096
[email protected]23e482282013-06-14 16:08:025097TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085098 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5099}
5100
[email protected]23e482282013-06-14 16:08:025101TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085102 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5103}
5104
[email protected]23e482282013-06-14 16:08:025105TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085106 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5107}
5108
[email protected]23e482282013-06-14 16:08:025109TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085110 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5111}
5112
[email protected]23e482282013-06-14 16:08:025113TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085114 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5115}
5116
[email protected]23e482282013-06-14 16:08:025117TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085118 ConnectStatusHelperWithExpectedStatus(
5119 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545120 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085121}
5122
[email protected]23e482282013-06-14 16:08:025123TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085124 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5125}
5126
[email protected]23e482282013-06-14 16:08:025127TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085128 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5129}
5130
[email protected]23e482282013-06-14 16:08:025131TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085132 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5133}
5134
[email protected]23e482282013-06-14 16:08:025135TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085136 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5137}
5138
[email protected]23e482282013-06-14 16:08:025139TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085140 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5141}
5142
[email protected]23e482282013-06-14 16:08:025143TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085144 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5145}
5146
[email protected]23e482282013-06-14 16:08:025147TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085148 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5149}
5150
[email protected]23e482282013-06-14 16:08:025151TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085152 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5153}
5154
[email protected]23e482282013-06-14 16:08:025155TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085156 ConnectStatusHelper(
5157 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5158}
5159
[email protected]23e482282013-06-14 16:08:025160TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085161 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5162}
5163
[email protected]23e482282013-06-14 16:08:025164TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085165 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5166}
5167
[email protected]23e482282013-06-14 16:08:025168TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085169 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5170}
5171
[email protected]23e482282013-06-14 16:08:025172TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085173 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5174}
5175
[email protected]23e482282013-06-14 16:08:025176TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085177 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5178}
5179
[email protected]23e482282013-06-14 16:08:025180TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085181 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5182}
5183
[email protected]23e482282013-06-14 16:08:025184TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085185 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5186}
5187
[email protected]038e9a32008-10-08 22:40:165188// Test the flow when both the proxy server AND origin server require
5189// authentication. Again, this uses basic auth for both since that is
5190// the simplest to mock.
[email protected]23e482282013-06-14 16:08:025191TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275192 HttpRequestInfo request;
5193 request.method = "GET";
bncce36dca22015-04-21 22:11:235194 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275195 request.load_flags = 0;
5196
[email protected]038e9a32008-10-08 22:40:165197 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035198 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:425199 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075200
5201 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:165203
[email protected]f9ee6b52008-11-08 06:46:235204 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235205 MockWrite(
5206 "GET http://www.example.org/ HTTP/1.1\r\n"
5207 "Host: www.example.org\r\n"
5208 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235209 };
5210
[email protected]038e9a32008-10-08 22:40:165211 MockRead data_reads1[] = {
5212 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5213 // Give a couple authenticate options (only the middle one is actually
5214 // supported).
[email protected]22927ad2009-09-21 19:56:195215 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165216 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5217 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5218 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5219 // Large content-length -- won't matter, as connection will be reset.
5220 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065221 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165222 };
5223
5224 // After calling trans->RestartWithAuth() the first time, this is the
5225 // request we should be issuing -- the final header line contains the
5226 // proxy's credentials.
5227 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235228 MockWrite(
5229 "GET http://www.example.org/ HTTP/1.1\r\n"
5230 "Host: www.example.org\r\n"
5231 "Proxy-Connection: keep-alive\r\n"
5232 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165233 };
5234
5235 // Now the proxy server lets the request pass through to origin server.
5236 // The origin server responds with a 401.
5237 MockRead data_reads2[] = {
5238 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5239 // Note: We are using the same realm-name as the proxy server. This is
5240 // completely valid, as realms are unique across hosts.
5241 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5242 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5243 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065244 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165245 };
5246
5247 // After calling trans->RestartWithAuth() the second time, we should send
5248 // the credentials for both the proxy and origin server.
5249 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235250 MockWrite(
5251 "GET http://www.example.org/ HTTP/1.1\r\n"
5252 "Host: www.example.org\r\n"
5253 "Proxy-Connection: keep-alive\r\n"
5254 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5255 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165256 };
5257
5258 // Lastly we get the desired content.
5259 MockRead data_reads3[] = {
5260 MockRead("HTTP/1.0 200 OK\r\n"),
5261 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5262 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065263 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165264 };
5265
[email protected]31a2bfe2010-02-09 08:03:395266 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5267 data_writes1, arraysize(data_writes1));
5268 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5269 data_writes2, arraysize(data_writes2));
5270 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5271 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075272 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5273 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5274 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165275
[email protected]49639fa2011-12-20 23:22:415276 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165277
[email protected]49639fa2011-12-20 23:22:415278 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425279 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165280
5281 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425282 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165283
[email protected]1c773ea12009-04-28 19:58:425284 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505285 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045286 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165287
[email protected]49639fa2011-12-20 23:22:415288 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165289
[email protected]49639fa2011-12-20 23:22:415290 rv = trans->RestartWithAuth(
5291 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425292 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165293
5294 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425295 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165296
5297 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505298 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045299 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165300
[email protected]49639fa2011-12-20 23:22:415301 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165302
[email protected]49639fa2011-12-20 23:22:415303 rv = trans->RestartWithAuth(
5304 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425305 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165306
5307 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425308 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165309
5310 response = trans->GetResponseInfo();
5311 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5312 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165313}
[email protected]4ddaf2502008-10-23 18:26:195314
[email protected]ea9dc9a2009-09-05 00:43:325315// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5316// can't hook into its internals to cause it to generate predictable NTLM
5317// authorization headers.
5318#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295319// The NTLM authentication unit tests were generated by capturing the HTTP
5320// requests and responses using Fiddler 2 and inspecting the generated random
5321// bytes in the debugger.
5322
5323// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:025324TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425325 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245326 request.method = "GET";
5327 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545328
5329 // Ensure load is not disrupted by flags which suppress behaviour specific
5330 // to other auth schemes.
5331 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245332
[email protected]cb9bf6ca2011-01-28 13:15:275333 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5334 MockGetHostName);
mmenkee65e7af2015-10-13 17:16:425335 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275336
[email protected]3f918782009-02-28 01:29:245337 MockWrite data_writes1[] = {
5338 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5339 "Host: 172.22.68.17\r\n"
5340 "Connection: keep-alive\r\n\r\n"),
5341 };
5342
5343 MockRead data_reads1[] = {
5344 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045345 // Negotiate and NTLM are often requested together. However, we only want
5346 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5347 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245348 MockRead("WWW-Authenticate: NTLM\r\n"),
5349 MockRead("Connection: close\r\n"),
5350 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365351 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245352 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065353 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245354 };
5355
5356 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225357 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:245358 // request we should be issuing -- the final header line contains a Type
5359 // 1 message.
5360 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5361 "Host: 172.22.68.17\r\n"
5362 "Connection: keep-alive\r\n"
5363 "Authorization: NTLM "
5364 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5365
5366 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5367 // (the credentials for the origin server). The second request continues
5368 // on the same connection.
5369 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5370 "Host: 172.22.68.17\r\n"
5371 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:295372 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5373 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5374 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5375 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5376 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245377 };
5378
5379 MockRead data_reads2[] = {
5380 // The origin server responds with a Type 2 message.
5381 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5382 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295383 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245384 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5385 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5386 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5387 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5388 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5389 "BtAAAAAAA=\r\n"),
5390 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365391 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245392 MockRead("You are not authorized to view this page\r\n"),
5393
5394 // Lastly we get the desired content.
5395 MockRead("HTTP/1.1 200 OK\r\n"),
5396 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5397 MockRead("Content-Length: 13\r\n\r\n"),
5398 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065399 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245400 };
5401
[email protected]31a2bfe2010-02-09 08:03:395402 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5403 data_writes1, arraysize(data_writes1));
5404 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5405 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075406 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5407 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245408
[email protected]49639fa2011-12-20 23:22:415409 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245410
[email protected]262eec82013-03-19 21:01:365411 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505412 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505413
[email protected]49639fa2011-12-20 23:22:415414 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425415 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245416
5417 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425418 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245419
[email protected]0757e7702009-03-27 04:00:225420 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5421
[email protected]1c773ea12009-04-28 19:58:425422 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:045423 ASSERT_FALSE(response == NULL);
5424 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245425
[email protected]49639fa2011-12-20 23:22:415426 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255427
[email protected]f3cf9802011-10-28 18:44:585428 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415429 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:255430 EXPECT_EQ(ERR_IO_PENDING, rv);
5431
5432 rv = callback2.WaitForResult();
5433 EXPECT_EQ(OK, rv);
5434
5435 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5436
5437 response = trans->GetResponseInfo();
5438 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:255439 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5440
[email protected]49639fa2011-12-20 23:22:415441 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245442
[email protected]49639fa2011-12-20 23:22:415443 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425444 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245445
[email protected]0757e7702009-03-27 04:00:225446 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425447 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245448
5449 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505450 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:245451 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5452 EXPECT_EQ(13, response->headers->GetContentLength());
5453}
5454
[email protected]385a4672009-03-11 22:21:295455// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:025456TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425457 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295458 request.method = "GET";
5459 request.url = GURL("http://172.22.68.17/kids/login.aspx");
5460 request.load_flags = 0;
5461
[email protected]cb9bf6ca2011-01-28 13:15:275462 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5463 MockGetHostName);
mmenkee65e7af2015-10-13 17:16:425464 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275465
[email protected]385a4672009-03-11 22:21:295466 MockWrite data_writes1[] = {
5467 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5468 "Host: 172.22.68.17\r\n"
5469 "Connection: keep-alive\r\n\r\n"),
5470 };
5471
5472 MockRead data_reads1[] = {
5473 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045474 // Negotiate and NTLM are often requested together. However, we only want
5475 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5476 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:295477 MockRead("WWW-Authenticate: NTLM\r\n"),
5478 MockRead("Connection: close\r\n"),
5479 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365480 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295481 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065482 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295483 };
5484
5485 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225486 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295487 // request we should be issuing -- the final header line contains a Type
5488 // 1 message.
5489 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5490 "Host: 172.22.68.17\r\n"
5491 "Connection: keep-alive\r\n"
5492 "Authorization: NTLM "
5493 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5494
5495 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5496 // (the credentials for the origin server). The second request continues
5497 // on the same connection.
5498 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5499 "Host: 172.22.68.17\r\n"
5500 "Connection: keep-alive\r\n"
5501 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5502 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5503 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
5504 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
5505 "4Ww7b7E=\r\n\r\n"),
5506 };
5507
5508 MockRead data_reads2[] = {
5509 // The origin server responds with a Type 2 message.
5510 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5511 MockRead("WWW-Authenticate: NTLM "
5512 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
5513 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5514 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5515 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5516 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5517 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5518 "BtAAAAAAA=\r\n"),
5519 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365520 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295521 MockRead("You are not authorized to view this page\r\n"),
5522
5523 // Wrong password.
5524 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:295525 MockRead("WWW-Authenticate: NTLM\r\n"),
5526 MockRead("Connection: close\r\n"),
5527 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365528 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295529 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065530 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295531 };
5532
5533 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:225534 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295535 // request we should be issuing -- the final header line contains a Type
5536 // 1 message.
5537 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5538 "Host: 172.22.68.17\r\n"
5539 "Connection: keep-alive\r\n"
5540 "Authorization: NTLM "
5541 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5542
5543 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5544 // (the credentials for the origin server). The second request continues
5545 // on the same connection.
5546 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5547 "Host: 172.22.68.17\r\n"
5548 "Connection: keep-alive\r\n"
5549 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5550 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5551 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
5552 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
5553 "+4MUm7c=\r\n\r\n"),
5554 };
5555
5556 MockRead data_reads3[] = {
5557 // The origin server responds with a Type 2 message.
5558 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5559 MockRead("WWW-Authenticate: NTLM "
5560 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
5561 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5562 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5563 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5564 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5565 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5566 "BtAAAAAAA=\r\n"),
5567 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365568 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295569 MockRead("You are not authorized to view this page\r\n"),
5570
5571 // Lastly we get the desired content.
5572 MockRead("HTTP/1.1 200 OK\r\n"),
5573 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5574 MockRead("Content-Length: 13\r\n\r\n"),
5575 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065576 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:295577 };
5578
[email protected]31a2bfe2010-02-09 08:03:395579 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5580 data_writes1, arraysize(data_writes1));
5581 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5582 data_writes2, arraysize(data_writes2));
5583 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5584 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075585 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5586 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5587 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:295588
[email protected]49639fa2011-12-20 23:22:415589 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:295590
[email protected]262eec82013-03-19 21:01:365591 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505592 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505593
[email protected]49639fa2011-12-20 23:22:415594 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425595 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295596
5597 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425598 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295599
[email protected]0757e7702009-03-27 04:00:225600 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:295601
[email protected]1c773ea12009-04-28 19:58:425602 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505603 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045604 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:295605
[email protected]49639fa2011-12-20 23:22:415606 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:295607
[email protected]0757e7702009-03-27 04:00:225608 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:585609 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:415610 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425611 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295612
[email protected]10af5fe72011-01-31 16:17:255613 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425614 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295615
[email protected]0757e7702009-03-27 04:00:225616 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415617 TestCompletionCallback callback3;
5618 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425619 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:255620 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425621 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225622 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5623
5624 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:045625 ASSERT_FALSE(response == NULL);
5626 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:225627
[email protected]49639fa2011-12-20 23:22:415628 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:225629
5630 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:585631 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415632 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:255633 EXPECT_EQ(ERR_IO_PENDING, rv);
5634
5635 rv = callback4.WaitForResult();
5636 EXPECT_EQ(OK, rv);
5637
5638 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5639
[email protected]49639fa2011-12-20 23:22:415640 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:255641
5642 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:415643 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:425644 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225645
5646 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425647 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225648
[email protected]385a4672009-03-11 22:21:295649 response = trans->GetResponseInfo();
5650 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5651 EXPECT_EQ(13, response->headers->GetContentLength());
5652}
[email protected]ea9dc9a2009-09-05 00:43:325653#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:295654
[email protected]4ddaf2502008-10-23 18:26:195655// Test reading a server response which has only headers, and no body.
5656// After some maximum number of bytes is consumed, the transaction should
5657// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:025658TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:425659 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:195660 request.method = "GET";
bncce36dca22015-04-21 22:11:235661 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:195662 request.load_flags = 0;
5663
mmenkee65e7af2015-10-13 17:16:425664 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275665 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415666 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275667
[email protected]b75b7b2f2009-10-06 00:54:535668 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:435669 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:535670 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:195671
5672 MockRead data_reads[] = {
5673 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065674 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:195675 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:065676 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:195677 };
[email protected]31a2bfe2010-02-09 08:03:395678 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075679 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:195680
[email protected]49639fa2011-12-20 23:22:415681 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:195682
[email protected]49639fa2011-12-20 23:22:415683 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425684 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:195685
5686 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425687 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:195688}
[email protected]f4e426b2008-11-05 00:24:495689
5690// Make sure that we don't try to reuse a TCPClientSocket when failing to
5691// establish tunnel.
5692// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:025693TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:235694 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275695 HttpRequestInfo request;
5696 request.method = "GET";
bncce36dca22015-04-21 22:11:235697 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275698 request.load_flags = 0;
5699
[email protected]f4e426b2008-11-05 00:24:495700 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035701 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:015702
mmenkee65e7af2015-10-13 17:16:425703 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495704
[email protected]262eec82013-03-19 21:01:365705 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505706 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495707
[email protected]f4e426b2008-11-05 00:24:495708 // Since we have proxy, should try to establish tunnel.
5709 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175710 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5711 "Host: www.example.org:443\r\n"
5712 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495713 };
5714
[email protected]77848d12008-11-14 00:00:225715 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495716 // connection. Usually a proxy would return 501 (not implemented),
5717 // or 200 (tunnel established).
5718 MockRead data_reads1[] = {
5719 MockRead("HTTP/1.1 404 Not Found\r\n"),
5720 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065721 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495722 };
5723
[email protected]31a2bfe2010-02-09 08:03:395724 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5725 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075726 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495727
[email protected]49639fa2011-12-20 23:22:415728 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495729
[email protected]49639fa2011-12-20 23:22:415730 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425731 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495732
5733 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425734 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495735
[email protected]b4404c02009-04-10 16:38:525736 // Empty the current queue. This is necessary because idle sockets are
5737 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345738 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525739
[email protected]f4e426b2008-11-05 00:24:495740 // We now check to make sure the TCPClientSocket was not added back to
5741 // the pool.
[email protected]90499482013-06-01 00:39:505742 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495743 trans.reset();
[email protected]2da659e2013-05-23 20:51:345744 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495745 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505746 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495747}
[email protected]372d34a2008-11-05 21:30:515748
[email protected]1b157c02009-04-21 01:55:405749// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025750TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425751 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405752 request.method = "GET";
bncce36dca22015-04-21 22:11:235753 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405754 request.load_flags = 0;
5755
mmenkee65e7af2015-10-13 17:16:425756 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275757
[email protected]262eec82013-03-19 21:01:365758 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505759 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275760
[email protected]1b157c02009-04-21 01:55:405761 MockRead data_reads[] = {
5762 // A part of the response body is received with the response headers.
5763 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5764 // The rest of the response body is received in two parts.
5765 MockRead("lo"),
5766 MockRead(" world"),
5767 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065768 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405769 };
5770
[email protected]31a2bfe2010-02-09 08:03:395771 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075772 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405773
[email protected]49639fa2011-12-20 23:22:415774 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405775
[email protected]49639fa2011-12-20 23:22:415776 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425777 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405778
5779 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425780 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405781
[email protected]1c773ea12009-04-28 19:58:425782 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505783 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405784
[email protected]90499482013-06-01 00:39:505785 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405786 std::string status_line = response->headers->GetStatusLine();
5787 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5788
[email protected]90499482013-06-01 00:39:505789 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405790
5791 std::string response_data;
5792 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425793 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405794 EXPECT_EQ("hello world", response_data);
5795
5796 // Empty the current queue. This is necessary because idle sockets are
5797 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345798 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405799
5800 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505801 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405802}
5803
[email protected]76a505b2010-08-25 06:23:005804// Make sure that we recycle a SSL socket after reading all of the response
5805// body.
[email protected]23e482282013-06-14 16:08:025806TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005807 HttpRequestInfo request;
5808 request.method = "GET";
bncce36dca22015-04-21 22:11:235809 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005810 request.load_flags = 0;
5811
5812 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235813 MockWrite(
5814 "GET / HTTP/1.1\r\n"
5815 "Host: www.example.org\r\n"
5816 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005817 };
5818
5819 MockRead data_reads[] = {
5820 MockRead("HTTP/1.1 200 OK\r\n"),
5821 MockRead("Content-Length: 11\r\n\r\n"),
5822 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065823 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005824 };
5825
[email protected]8ddf8322012-02-23 18:08:065826 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075827 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005828
5829 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5830 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075831 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005832
[email protected]49639fa2011-12-20 23:22:415833 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005834
mmenkee65e7af2015-10-13 17:16:425835 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365836 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505837 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005838
[email protected]49639fa2011-12-20 23:22:415839 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005840
5841 EXPECT_EQ(ERR_IO_PENDING, rv);
5842 EXPECT_EQ(OK, callback.WaitForResult());
5843
5844 const HttpResponseInfo* response = trans->GetResponseInfo();
5845 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505846 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005847 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5848
[email protected]90499482013-06-01 00:39:505849 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005850
5851 std::string response_data;
5852 rv = ReadTransaction(trans.get(), &response_data);
5853 EXPECT_EQ(OK, rv);
5854 EXPECT_EQ("hello world", response_data);
5855
5856 // Empty the current queue. This is necessary because idle sockets are
5857 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345858 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005859
5860 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505861 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005862}
5863
5864// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5865// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025866TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005867 HttpRequestInfo request;
5868 request.method = "GET";
bncce36dca22015-04-21 22:11:235869 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005870 request.load_flags = 0;
5871
5872 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235873 MockWrite(
5874 "GET / HTTP/1.1\r\n"
5875 "Host: www.example.org\r\n"
5876 "Connection: keep-alive\r\n\r\n"),
5877 MockWrite(
5878 "GET / HTTP/1.1\r\n"
5879 "Host: www.example.org\r\n"
5880 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005881 };
5882
5883 MockRead data_reads[] = {
5884 MockRead("HTTP/1.1 200 OK\r\n"),
5885 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065886 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005887 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065888 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005889 };
5890
[email protected]8ddf8322012-02-23 18:08:065891 SSLSocketDataProvider ssl(ASYNC, OK);
5892 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075893 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5894 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005895
5896 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5897 data_writes, arraysize(data_writes));
5898 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5899 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075900 session_deps_.socket_factory->AddSocketDataProvider(&data);
5901 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005902
[email protected]49639fa2011-12-20 23:22:415903 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005904
mmenkee65e7af2015-10-13 17:16:425905 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365906 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505907 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005908
[email protected]49639fa2011-12-20 23:22:415909 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005910
5911 EXPECT_EQ(ERR_IO_PENDING, rv);
5912 EXPECT_EQ(OK, callback.WaitForResult());
5913
5914 const HttpResponseInfo* response = trans->GetResponseInfo();
5915 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505916 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005917 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5918
[email protected]90499482013-06-01 00:39:505919 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005920
5921 std::string response_data;
5922 rv = ReadTransaction(trans.get(), &response_data);
5923 EXPECT_EQ(OK, rv);
5924 EXPECT_EQ("hello world", response_data);
5925
5926 // Empty the current queue. This is necessary because idle sockets are
5927 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345928 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005929
5930 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505931 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005932
5933 // Now start the second transaction, which should reuse the previous socket.
5934
[email protected]90499482013-06-01 00:39:505935 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005936
[email protected]49639fa2011-12-20 23:22:415937 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005938
5939 EXPECT_EQ(ERR_IO_PENDING, rv);
5940 EXPECT_EQ(OK, callback.WaitForResult());
5941
5942 response = trans->GetResponseInfo();
5943 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505944 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005945 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5946
[email protected]90499482013-06-01 00:39:505947 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005948
5949 rv = ReadTransaction(trans.get(), &response_data);
5950 EXPECT_EQ(OK, rv);
5951 EXPECT_EQ("hello world", response_data);
5952
5953 // Empty the current queue. This is necessary because idle sockets are
5954 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345955 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005956
5957 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505958 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005959}
5960
[email protected]b4404c02009-04-10 16:38:525961// Make sure that we recycle a socket after a zero-length response.
5962// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025963TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425964 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525965 request.method = "GET";
bncce36dca22015-04-21 22:11:235966 request.url = GURL(
5967 "http://www.example.org/csi?v=3&s=web&action=&"
5968 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5969 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5970 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525971 request.load_flags = 0;
5972
mmenkee65e7af2015-10-13 17:16:425973 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275974
[email protected]262eec82013-03-19 21:01:365975 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505976 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275977
[email protected]b4404c02009-04-10 16:38:525978 MockRead data_reads[] = {
5979 MockRead("HTTP/1.1 204 No Content\r\n"
5980 "Content-Length: 0\r\n"
5981 "Content-Type: text/html\r\n\r\n"),
5982 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065983 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525984 };
5985
[email protected]31a2bfe2010-02-09 08:03:395986 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075987 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525988
[email protected]49639fa2011-12-20 23:22:415989 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525990
[email protected]49639fa2011-12-20 23:22:415991 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425992 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525993
5994 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425995 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525996
[email protected]1c773ea12009-04-28 19:58:425997 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505998 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525999
[email protected]90499482013-06-01 00:39:506000 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:526001 std::string status_line = response->headers->GetStatusLine();
6002 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6003
[email protected]90499482013-06-01 00:39:506004 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526005
6006 std::string response_data;
6007 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426008 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:526009 EXPECT_EQ("", response_data);
6010
6011 // Empty the current queue. This is necessary because idle sockets are
6012 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:346013 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526014
6015 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506016 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526017}
6018
[email protected]23e482282013-06-14 16:08:026019TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
olli.raula6df48b2a2015-11-26 07:40:226020 std::vector<scoped_ptr<UploadElementReader>> element_readers;
6021 element_readers.push_back(
6022 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
6023 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276024
[email protected]1c773ea12009-04-28 19:58:426025 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516026 // Transaction 1: a GET request that succeeds. The socket is recycled
6027 // after use.
6028 request[0].method = "GET";
6029 request[0].url = GURL("http://www.google.com/");
6030 request[0].load_flags = 0;
6031 // Transaction 2: a POST request. Reuses the socket kept alive from
6032 // transaction 1. The first attempts fails when writing the POST data.
6033 // This causes the transaction to retry with a new socket. The second
6034 // attempt succeeds.
6035 request[1].method = "POST";
6036 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276037 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516038 request[1].load_flags = 0;
6039
mmenkee65e7af2015-10-13 17:16:426040 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516041
6042 // The first socket is used for transaction 1 and the first attempt of
6043 // transaction 2.
6044
6045 // The response of transaction 1.
6046 MockRead data_reads1[] = {
6047 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6048 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066049 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516050 };
6051 // The mock write results of transaction 1 and the first attempt of
6052 // transaction 2.
6053 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066054 MockWrite(SYNCHRONOUS, 64), // GET
6055 MockWrite(SYNCHRONOUS, 93), // POST
6056 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516057 };
[email protected]31a2bfe2010-02-09 08:03:396058 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6059 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516060
6061 // The second socket is used for the second attempt of transaction 2.
6062
6063 // The response of transaction 2.
6064 MockRead data_reads2[] = {
6065 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6066 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066067 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516068 };
6069 // The mock write results of the second attempt of transaction 2.
6070 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066071 MockWrite(SYNCHRONOUS, 93), // POST
6072 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516073 };
[email protected]31a2bfe2010-02-09 08:03:396074 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6075 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516076
[email protected]bb88e1d32013-05-03 23:11:076077 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6078 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516079
thestig9d3bb0c2015-01-24 00:49:516080 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516081 "hello world", "welcome"
6082 };
6083
6084 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:426085 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506086 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:516087
[email protected]49639fa2011-12-20 23:22:416088 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516089
[email protected]49639fa2011-12-20 23:22:416090 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426091 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:516092
6093 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426094 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516095
[email protected]1c773ea12009-04-28 19:58:426096 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506097 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:516098
[email protected]90499482013-06-01 00:39:506099 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:516100 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6101
6102 std::string response_data;
6103 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426104 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516105 EXPECT_EQ(kExpectedResponseData[i], response_data);
6106 }
6107}
[email protected]f9ee6b52008-11-08 06:46:236108
6109// Test the request-challenge-retry sequence for basic auth when there is
6110// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166111// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:026112TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426113 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236114 request.method = "GET";
bncce36dca22015-04-21 22:11:236115 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416116 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296117
mmenkee65e7af2015-10-13 17:16:426118 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276119 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416120 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276121
[email protected]a97cca42009-08-14 01:00:296122 // The password contains an escaped character -- for this test to pass it
6123 // will need to be unescaped by HttpNetworkTransaction.
6124 EXPECT_EQ("b%40r", request.url.password());
6125
[email protected]f9ee6b52008-11-08 06:46:236126 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236127 MockWrite(
6128 "GET / HTTP/1.1\r\n"
6129 "Host: www.example.org\r\n"
6130 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236131 };
6132
6133 MockRead data_reads1[] = {
6134 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6135 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6136 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066137 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236138 };
6139
[email protected]2262e3a2012-05-22 16:08:166140 // After the challenge above, the transaction will be restarted using the
6141 // identity from the url (foo, b@r) to answer the challenge.
6142 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236143 MockWrite(
6144 "GET / HTTP/1.1\r\n"
6145 "Host: www.example.org\r\n"
6146 "Connection: keep-alive\r\n"
6147 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166148 };
6149
6150 MockRead data_reads2[] = {
6151 MockRead("HTTP/1.0 200 OK\r\n"),
6152 MockRead("Content-Length: 100\r\n\r\n"),
6153 MockRead(SYNCHRONOUS, OK),
6154 };
6155
[email protected]31a2bfe2010-02-09 08:03:396156 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6157 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166158 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6159 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076160 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6161 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236162
[email protected]49639fa2011-12-20 23:22:416163 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:416164 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426165 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236166 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426167 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:166168 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6169
6170 TestCompletionCallback callback2;
6171 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6172 EXPECT_EQ(ERR_IO_PENDING, rv);
6173 rv = callback2.WaitForResult();
6174 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226175 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6176
[email protected]2262e3a2012-05-22 16:08:166177 const HttpResponseInfo* response = trans->GetResponseInfo();
6178 ASSERT_TRUE(response != NULL);
6179
6180 // There is no challenge info, since the identity in URL worked.
6181 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6182
6183 EXPECT_EQ(100, response->headers->GetContentLength());
6184
6185 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:346186 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166187}
6188
6189// Test the request-challenge-retry sequence for basic auth when there is an
6190// incorrect identity in the URL. The identity from the URL should be used only
6191// once.
[email protected]23e482282013-06-14 16:08:026192TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166193 HttpRequestInfo request;
6194 request.method = "GET";
6195 // Note: the URL has a username:password in it. The password "baz" is
6196 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236197 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166198
6199 request.load_flags = LOAD_NORMAL;
6200
mmenkee65e7af2015-10-13 17:16:426201 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:166202 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416203 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:166204
6205 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236206 MockWrite(
6207 "GET / HTTP/1.1\r\n"
6208 "Host: www.example.org\r\n"
6209 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166210 };
6211
6212 MockRead data_reads1[] = {
6213 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6214 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6215 MockRead("Content-Length: 10\r\n\r\n"),
6216 MockRead(SYNCHRONOUS, ERR_FAILED),
6217 };
6218
6219 // After the challenge above, the transaction will be restarted using the
6220 // identity from the url (foo, baz) to answer the challenge.
6221 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236222 MockWrite(
6223 "GET / HTTP/1.1\r\n"
6224 "Host: www.example.org\r\n"
6225 "Connection: keep-alive\r\n"
6226 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166227 };
6228
6229 MockRead data_reads2[] = {
6230 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6231 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6232 MockRead("Content-Length: 10\r\n\r\n"),
6233 MockRead(SYNCHRONOUS, ERR_FAILED),
6234 };
6235
6236 // After the challenge above, the transaction will be restarted using the
6237 // identity supplied by the user (foo, bar) to answer the challenge.
6238 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236239 MockWrite(
6240 "GET / HTTP/1.1\r\n"
6241 "Host: www.example.org\r\n"
6242 "Connection: keep-alive\r\n"
6243 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166244 };
6245
6246 MockRead data_reads3[] = {
6247 MockRead("HTTP/1.0 200 OK\r\n"),
6248 MockRead("Content-Length: 100\r\n\r\n"),
6249 MockRead(SYNCHRONOUS, OK),
6250 };
6251
6252 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6253 data_writes1, arraysize(data_writes1));
6254 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6255 data_writes2, arraysize(data_writes2));
6256 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6257 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076258 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6259 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6260 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166261
6262 TestCompletionCallback callback1;
6263
6264 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6265 EXPECT_EQ(ERR_IO_PENDING, rv);
6266
6267 rv = callback1.WaitForResult();
6268 EXPECT_EQ(OK, rv);
6269
6270 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6271 TestCompletionCallback callback2;
6272 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6273 EXPECT_EQ(ERR_IO_PENDING, rv);
6274 rv = callback2.WaitForResult();
6275 EXPECT_EQ(OK, rv);
6276 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6277
6278 const HttpResponseInfo* response = trans->GetResponseInfo();
6279 ASSERT_TRUE(response != NULL);
6280 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6281
6282 TestCompletionCallback callback3;
6283 rv = trans->RestartWithAuth(
6284 AuthCredentials(kFoo, kBar), callback3.callback());
6285 EXPECT_EQ(ERR_IO_PENDING, rv);
6286 rv = callback3.WaitForResult();
6287 EXPECT_EQ(OK, rv);
6288 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6289
6290 response = trans->GetResponseInfo();
6291 ASSERT_TRUE(response != NULL);
6292
6293 // There is no challenge info, since the identity worked.
6294 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6295
6296 EXPECT_EQ(100, response->headers->GetContentLength());
6297
[email protected]ea9dc9a2009-09-05 00:43:326298 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:346299 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326300}
6301
[email protected]2217aa22013-10-11 03:03:546302
6303// Test the request-challenge-retry sequence for basic auth when there is a
6304// correct identity in the URL, but its use is being suppressed. The identity
6305// from the URL should never be used.
6306TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
6307 HttpRequestInfo request;
6308 request.method = "GET";
bncce36dca22015-04-21 22:11:236309 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546310 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6311
mmenkee65e7af2015-10-13 17:16:426312 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:546313 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416314 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:546315
6316 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236317 MockWrite(
6318 "GET / HTTP/1.1\r\n"
6319 "Host: www.example.org\r\n"
6320 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546321 };
6322
6323 MockRead data_reads1[] = {
6324 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6325 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6326 MockRead("Content-Length: 10\r\n\r\n"),
6327 MockRead(SYNCHRONOUS, ERR_FAILED),
6328 };
6329
6330 // After the challenge above, the transaction will be restarted using the
6331 // identity supplied by the user, not the one in the URL, to answer the
6332 // challenge.
6333 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236334 MockWrite(
6335 "GET / HTTP/1.1\r\n"
6336 "Host: www.example.org\r\n"
6337 "Connection: keep-alive\r\n"
6338 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546339 };
6340
6341 MockRead data_reads3[] = {
6342 MockRead("HTTP/1.0 200 OK\r\n"),
6343 MockRead("Content-Length: 100\r\n\r\n"),
6344 MockRead(SYNCHRONOUS, OK),
6345 };
6346
6347 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6348 data_writes1, arraysize(data_writes1));
6349 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6350 data_writes3, arraysize(data_writes3));
6351 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6352 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6353
6354 TestCompletionCallback callback1;
6355 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6356 EXPECT_EQ(ERR_IO_PENDING, rv);
6357 rv = callback1.WaitForResult();
6358 EXPECT_EQ(OK, rv);
6359 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6360
6361 const HttpResponseInfo* response = trans->GetResponseInfo();
6362 ASSERT_TRUE(response != NULL);
6363 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6364
6365 TestCompletionCallback callback3;
6366 rv = trans->RestartWithAuth(
6367 AuthCredentials(kFoo, kBar), callback3.callback());
6368 EXPECT_EQ(ERR_IO_PENDING, rv);
6369 rv = callback3.WaitForResult();
6370 EXPECT_EQ(OK, rv);
6371 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6372
6373 response = trans->GetResponseInfo();
6374 ASSERT_TRUE(response != NULL);
6375
6376 // There is no challenge info, since the identity worked.
6377 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6378 EXPECT_EQ(100, response->headers->GetContentLength());
6379
6380 // Empty the current queue.
6381 base::MessageLoop::current()->RunUntilIdle();
6382}
6383
[email protected]f9ee6b52008-11-08 06:46:236384// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:026385TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
mmenkee65e7af2015-10-13 17:16:426386 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:236387
6388 // Transaction 1: authenticate (foo, bar) on MyRealm1
6389 {
[email protected]1c773ea12009-04-28 19:58:426390 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236391 request.method = "GET";
bncce36dca22015-04-21 22:11:236392 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:236393 request.load_flags = 0;
6394
[email protected]262eec82013-03-19 21:01:366395 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506396 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276397
[email protected]f9ee6b52008-11-08 06:46:236398 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236399 MockWrite(
6400 "GET /x/y/z HTTP/1.1\r\n"
6401 "Host: www.example.org\r\n"
6402 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236403 };
6404
6405 MockRead data_reads1[] = {
6406 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6407 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6408 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066409 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236410 };
6411
6412 // Resend with authorization (username=foo, password=bar)
6413 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236414 MockWrite(
6415 "GET /x/y/z HTTP/1.1\r\n"
6416 "Host: www.example.org\r\n"
6417 "Connection: keep-alive\r\n"
6418 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236419 };
6420
6421 // Sever accepts the authorization.
6422 MockRead data_reads2[] = {
6423 MockRead("HTTP/1.0 200 OK\r\n"),
6424 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066425 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236426 };
6427
[email protected]31a2bfe2010-02-09 08:03:396428 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6429 data_writes1, arraysize(data_writes1));
6430 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6431 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076432 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6433 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236434
[email protected]49639fa2011-12-20 23:22:416435 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236436
[email protected]49639fa2011-12-20 23:22:416437 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426438 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236439
6440 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426441 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236442
[email protected]1c773ea12009-04-28 19:58:426443 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506444 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046445 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236446
[email protected]49639fa2011-12-20 23:22:416447 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236448
[email protected]49639fa2011-12-20 23:22:416449 rv = trans->RestartWithAuth(
6450 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426451 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236452
6453 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426454 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236455
6456 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506457 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236458 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6459 EXPECT_EQ(100, response->headers->GetContentLength());
6460 }
6461
6462 // ------------------------------------------------------------------------
6463
6464 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
6465 {
[email protected]1c773ea12009-04-28 19:58:426466 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236467 request.method = "GET";
6468 // Note that Transaction 1 was at /x/y/z, so this is in the same
6469 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:236470 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:236471 request.load_flags = 0;
6472
[email protected]262eec82013-03-19 21:01:366473 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506474 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276475
[email protected]f9ee6b52008-11-08 06:46:236476 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236477 MockWrite(
6478 "GET /x/y/a/b HTTP/1.1\r\n"
6479 "Host: www.example.org\r\n"
6480 "Connection: keep-alive\r\n"
6481 // Send preemptive authorization for MyRealm1
6482 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236483 };
6484
6485 // The server didn't like the preemptive authorization, and
6486 // challenges us for a different realm (MyRealm2).
6487 MockRead data_reads1[] = {
6488 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6489 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
6490 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066491 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236492 };
6493
6494 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
6495 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236496 MockWrite(
6497 "GET /x/y/a/b HTTP/1.1\r\n"
6498 "Host: www.example.org\r\n"
6499 "Connection: keep-alive\r\n"
6500 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236501 };
6502
6503 // Sever accepts the authorization.
6504 MockRead data_reads2[] = {
6505 MockRead("HTTP/1.0 200 OK\r\n"),
6506 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066507 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236508 };
6509
[email protected]31a2bfe2010-02-09 08:03:396510 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6511 data_writes1, arraysize(data_writes1));
6512 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6513 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076514 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6515 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236516
[email protected]49639fa2011-12-20 23:22:416517 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236518
[email protected]49639fa2011-12-20 23:22:416519 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426520 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236521
6522 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426523 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236524
[email protected]1c773ea12009-04-28 19:58:426525 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506526 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046527 ASSERT_TRUE(response->auth_challenge.get());
6528 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:236529 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:046530 response->auth_challenge->challenger.ToString());
6531 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
6532 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:236533
[email protected]49639fa2011-12-20 23:22:416534 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236535
[email protected]49639fa2011-12-20 23:22:416536 rv = trans->RestartWithAuth(
6537 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426538 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236539
6540 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426541 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236542
6543 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506544 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236545 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6546 EXPECT_EQ(100, response->headers->GetContentLength());
6547 }
6548
6549 // ------------------------------------------------------------------------
6550
6551 // Transaction 3: Resend a request in MyRealm's protection space --
6552 // succeed with preemptive authorization.
6553 {
[email protected]1c773ea12009-04-28 19:58:426554 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236555 request.method = "GET";
bncce36dca22015-04-21 22:11:236556 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:236557 request.load_flags = 0;
6558
[email protected]262eec82013-03-19 21:01:366559 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506560 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276561
[email protected]f9ee6b52008-11-08 06:46:236562 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236563 MockWrite(
6564 "GET /x/y/z2 HTTP/1.1\r\n"
6565 "Host: www.example.org\r\n"
6566 "Connection: keep-alive\r\n"
6567 // The authorization for MyRealm1 gets sent preemptively
6568 // (since the url is in the same protection space)
6569 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236570 };
6571
6572 // Sever accepts the preemptive authorization
6573 MockRead data_reads1[] = {
6574 MockRead("HTTP/1.0 200 OK\r\n"),
6575 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066576 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236577 };
6578
[email protected]31a2bfe2010-02-09 08:03:396579 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6580 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076581 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:236582
[email protected]49639fa2011-12-20 23:22:416583 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236584
[email protected]49639fa2011-12-20 23:22:416585 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426586 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236587
6588 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426589 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236590
[email protected]1c773ea12009-04-28 19:58:426591 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506592 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236593
6594 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6595 EXPECT_EQ(100, response->headers->GetContentLength());
6596 }
6597
6598 // ------------------------------------------------------------------------
6599
6600 // Transaction 4: request another URL in MyRealm (however the
6601 // url is not known to belong to the protection space, so no pre-auth).
6602 {
[email protected]1c773ea12009-04-28 19:58:426603 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236604 request.method = "GET";
bncce36dca22015-04-21 22:11:236605 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:236606 request.load_flags = 0;
6607
[email protected]262eec82013-03-19 21:01:366608 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506609 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276610
[email protected]f9ee6b52008-11-08 06:46:236611 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236612 MockWrite(
6613 "GET /x/1 HTTP/1.1\r\n"
6614 "Host: www.example.org\r\n"
6615 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236616 };
6617
6618 MockRead data_reads1[] = {
6619 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6620 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6621 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066622 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236623 };
6624
6625 // Resend with authorization from MyRealm's cache.
6626 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236627 MockWrite(
6628 "GET /x/1 HTTP/1.1\r\n"
6629 "Host: www.example.org\r\n"
6630 "Connection: keep-alive\r\n"
6631 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236632 };
6633
6634 // Sever accepts the authorization.
6635 MockRead data_reads2[] = {
6636 MockRead("HTTP/1.0 200 OK\r\n"),
6637 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066638 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236639 };
6640
[email protected]31a2bfe2010-02-09 08:03:396641 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6642 data_writes1, arraysize(data_writes1));
6643 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6644 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076645 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6646 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236647
[email protected]49639fa2011-12-20 23:22:416648 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236649
[email protected]49639fa2011-12-20 23:22:416650 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426651 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236652
6653 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426654 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236655
[email protected]0757e7702009-03-27 04:00:226656 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416657 TestCompletionCallback callback2;
6658 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426659 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226660 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426661 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226662 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6663
[email protected]1c773ea12009-04-28 19:58:426664 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506665 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236666 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6667 EXPECT_EQ(100, response->headers->GetContentLength());
6668 }
6669
6670 // ------------------------------------------------------------------------
6671
6672 // Transaction 5: request a URL in MyRealm, but the server rejects the
6673 // cached identity. Should invalidate and re-prompt.
6674 {
[email protected]1c773ea12009-04-28 19:58:426675 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236676 request.method = "GET";
bncce36dca22015-04-21 22:11:236677 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:236678 request.load_flags = 0;
6679
[email protected]262eec82013-03-19 21:01:366680 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506681 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276682
[email protected]f9ee6b52008-11-08 06:46:236683 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236684 MockWrite(
6685 "GET /p/q/t HTTP/1.1\r\n"
6686 "Host: www.example.org\r\n"
6687 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236688 };
6689
6690 MockRead data_reads1[] = {
6691 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6692 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6693 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066694 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236695 };
6696
6697 // Resend with authorization from cache for MyRealm.
6698 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236699 MockWrite(
6700 "GET /p/q/t HTTP/1.1\r\n"
6701 "Host: www.example.org\r\n"
6702 "Connection: keep-alive\r\n"
6703 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236704 };
6705
6706 // Sever rejects the authorization.
6707 MockRead data_reads2[] = {
6708 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6709 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6710 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066711 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236712 };
6713
6714 // At this point we should prompt for new credentials for MyRealm.
6715 // Restart with username=foo3, password=foo4.
6716 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236717 MockWrite(
6718 "GET /p/q/t HTTP/1.1\r\n"
6719 "Host: www.example.org\r\n"
6720 "Connection: keep-alive\r\n"
6721 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236722 };
6723
6724 // Sever accepts the authorization.
6725 MockRead data_reads3[] = {
6726 MockRead("HTTP/1.0 200 OK\r\n"),
6727 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066728 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236729 };
6730
[email protected]31a2bfe2010-02-09 08:03:396731 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6732 data_writes1, arraysize(data_writes1));
6733 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6734 data_writes2, arraysize(data_writes2));
6735 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6736 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076737 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6738 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6739 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236740
[email protected]49639fa2011-12-20 23:22:416741 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236742
[email protected]49639fa2011-12-20 23:22:416743 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426744 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236745
6746 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426747 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236748
[email protected]0757e7702009-03-27 04:00:226749 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416750 TestCompletionCallback callback2;
6751 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426752 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226753 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426754 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226755 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6756
[email protected]1c773ea12009-04-28 19:58:426757 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506758 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046759 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236760
[email protected]49639fa2011-12-20 23:22:416761 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236762
[email protected]49639fa2011-12-20 23:22:416763 rv = trans->RestartWithAuth(
6764 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426765 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236766
[email protected]0757e7702009-03-27 04:00:226767 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426768 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236769
6770 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506771 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236772 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6773 EXPECT_EQ(100, response->headers->GetContentLength());
6774 }
6775}
[email protected]89ceba9a2009-03-21 03:46:066776
[email protected]3c32c5f2010-05-18 15:18:126777// Tests that nonce count increments when multiple auth attempts
6778// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026779TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446780 HttpAuthHandlerDigest::Factory* digest_factory =
6781 new HttpAuthHandlerDigest::Factory();
6782 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6783 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6784 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076785 session_deps_.http_auth_handler_factory.reset(digest_factory);
mmenkee65e7af2015-10-13 17:16:426786 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126787
6788 // Transaction 1: authenticate (foo, bar) on MyRealm1
6789 {
[email protected]3c32c5f2010-05-18 15:18:126790 HttpRequestInfo request;
6791 request.method = "GET";
bncce36dca22015-04-21 22:11:236792 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126793 request.load_flags = 0;
6794
[email protected]262eec82013-03-19 21:01:366795 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506796 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276797
[email protected]3c32c5f2010-05-18 15:18:126798 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236799 MockWrite(
6800 "GET /x/y/z HTTP/1.1\r\n"
6801 "Host: www.example.org\r\n"
6802 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126803 };
6804
6805 MockRead data_reads1[] = {
6806 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6807 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6808 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066809 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126810 };
6811
6812 // Resend with authorization (username=foo, password=bar)
6813 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236814 MockWrite(
6815 "GET /x/y/z HTTP/1.1\r\n"
6816 "Host: www.example.org\r\n"
6817 "Connection: keep-alive\r\n"
6818 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6819 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6820 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6821 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126822 };
6823
6824 // Sever accepts the authorization.
6825 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:086826 MockRead("HTTP/1.0 200 OK\r\n"),
6827 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126828 };
6829
6830 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6831 data_writes1, arraysize(data_writes1));
6832 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6833 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076834 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6835 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126836
[email protected]49639fa2011-12-20 23:22:416837 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126838
[email protected]49639fa2011-12-20 23:22:416839 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126840 EXPECT_EQ(ERR_IO_PENDING, rv);
6841
6842 rv = callback1.WaitForResult();
6843 EXPECT_EQ(OK, rv);
6844
6845 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506846 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046847 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126848
[email protected]49639fa2011-12-20 23:22:416849 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126850
[email protected]49639fa2011-12-20 23:22:416851 rv = trans->RestartWithAuth(
6852 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126853 EXPECT_EQ(ERR_IO_PENDING, rv);
6854
6855 rv = callback2.WaitForResult();
6856 EXPECT_EQ(OK, rv);
6857
6858 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506859 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126860 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6861 }
6862
6863 // ------------------------------------------------------------------------
6864
6865 // Transaction 2: Request another resource in digestive's protection space.
6866 // This will preemptively add an Authorization header which should have an
6867 // "nc" value of 2 (as compared to 1 in the first use.
6868 {
[email protected]3c32c5f2010-05-18 15:18:126869 HttpRequestInfo request;
6870 request.method = "GET";
6871 // Note that Transaction 1 was at /x/y/z, so this is in the same
6872 // protection space as digest.
bncce36dca22015-04-21 22:11:236873 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126874 request.load_flags = 0;
6875
[email protected]262eec82013-03-19 21:01:366876 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506877 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276878
[email protected]3c32c5f2010-05-18 15:18:126879 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236880 MockWrite(
6881 "GET /x/y/a/b HTTP/1.1\r\n"
6882 "Host: www.example.org\r\n"
6883 "Connection: keep-alive\r\n"
6884 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6885 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6886 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6887 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126888 };
6889
6890 // Sever accepts the authorization.
6891 MockRead data_reads1[] = {
6892 MockRead("HTTP/1.0 200 OK\r\n"),
6893 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066894 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126895 };
6896
6897 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6898 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076899 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126900
[email protected]49639fa2011-12-20 23:22:416901 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126902
[email protected]49639fa2011-12-20 23:22:416903 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126904 EXPECT_EQ(ERR_IO_PENDING, rv);
6905
6906 rv = callback1.WaitForResult();
6907 EXPECT_EQ(OK, rv);
6908
6909 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506910 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126911 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6912 }
6913}
6914
[email protected]89ceba9a2009-03-21 03:46:066915// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026916TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066917 // Create a transaction (the dependencies aren't important).
mmenkee65e7af2015-10-13 17:16:426918 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406919 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416920 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066921
6922 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066923 trans->read_buf_ = new IOBuffer(15);
6924 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206925 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066926
6927 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146928 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576929 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086930 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576931 response->response_time = base::Time::Now();
6932 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066933
6934 { // Setup state for response_.vary_data
6935 HttpRequestInfo request;
6936 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6937 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276938 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436939 request.extra_headers.SetHeader("Foo", "1");
6940 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506941 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066942 }
6943
6944 // Cause the above state to be reset.
6945 trans->ResetStateForRestart();
6946
6947 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076948 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066949 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206950 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576951 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6952 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046953 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086954 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576955 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066956}
6957
[email protected]bacff652009-03-31 17:50:336958// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026959TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336960 HttpRequestInfo request;
6961 request.method = "GET";
bncce36dca22015-04-21 22:11:236962 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336963 request.load_flags = 0;
6964
mmenkee65e7af2015-10-13 17:16:426965 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276966 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416967 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276968
[email protected]bacff652009-03-31 17:50:336969 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236970 MockWrite(
6971 "GET / HTTP/1.1\r\n"
6972 "Host: www.example.org\r\n"
6973 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336974 };
6975
6976 MockRead data_reads[] = {
6977 MockRead("HTTP/1.0 200 OK\r\n"),
6978 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6979 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066980 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336981 };
6982
[email protected]5ecc992a42009-11-11 01:41:596983 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396984 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6985 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066986 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6987 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336988
[email protected]bb88e1d32013-05-03 23:11:076989 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6990 session_deps_.socket_factory->AddSocketDataProvider(&data);
6991 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6992 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336993
[email protected]49639fa2011-12-20 23:22:416994 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336995
[email protected]49639fa2011-12-20 23:22:416996 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336997 EXPECT_EQ(ERR_IO_PENDING, rv);
6998
6999 rv = callback.WaitForResult();
7000 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7001
[email protected]49639fa2011-12-20 23:22:417002 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337003 EXPECT_EQ(ERR_IO_PENDING, rv);
7004
7005 rv = callback.WaitForResult();
7006 EXPECT_EQ(OK, rv);
7007
7008 const HttpResponseInfo* response = trans->GetResponseInfo();
7009
[email protected]fe2255a2011-09-20 19:37:507010 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:337011 EXPECT_EQ(100, response->headers->GetContentLength());
7012}
7013
7014// Test HTTPS connections to a site with a bad certificate, going through a
7015// proxy
[email protected]23e482282013-06-14 16:08:027016TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037017 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337018
7019 HttpRequestInfo request;
7020 request.method = "GET";
bncce36dca22015-04-21 22:11:237021 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337022 request.load_flags = 0;
7023
7024 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177025 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7026 "Host: www.example.org:443\r\n"
7027 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337028 };
7029
7030 MockRead proxy_reads[] = {
7031 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067032 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337033 };
7034
7035 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177036 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7037 "Host: www.example.org:443\r\n"
7038 "Proxy-Connection: keep-alive\r\n\r\n"),
7039 MockWrite("GET / HTTP/1.1\r\n"
7040 "Host: www.example.org\r\n"
7041 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337042 };
7043
7044 MockRead data_reads[] = {
7045 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7046 MockRead("HTTP/1.0 200 OK\r\n"),
7047 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7048 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067049 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337050 };
7051
[email protected]31a2bfe2010-02-09 08:03:397052 StaticSocketDataProvider ssl_bad_certificate(
7053 proxy_reads, arraysize(proxy_reads),
7054 proxy_writes, arraysize(proxy_writes));
7055 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7056 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067057 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7058 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337059
[email protected]bb88e1d32013-05-03 23:11:077060 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7061 session_deps_.socket_factory->AddSocketDataProvider(&data);
7062 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7063 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337064
[email protected]49639fa2011-12-20 23:22:417065 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337066
7067 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077068 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337069
mmenkee65e7af2015-10-13 17:16:427070 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:407071 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417072 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:337073
[email protected]49639fa2011-12-20 23:22:417074 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:337075 EXPECT_EQ(ERR_IO_PENDING, rv);
7076
7077 rv = callback.WaitForResult();
7078 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7079
[email protected]49639fa2011-12-20 23:22:417080 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337081 EXPECT_EQ(ERR_IO_PENDING, rv);
7082
7083 rv = callback.WaitForResult();
7084 EXPECT_EQ(OK, rv);
7085
7086 const HttpResponseInfo* response = trans->GetResponseInfo();
7087
[email protected]fe2255a2011-09-20 19:37:507088 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:337089 EXPECT_EQ(100, response->headers->GetContentLength());
7090 }
7091}
7092
[email protected]2df19bb2010-08-25 20:13:467093
7094// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:027095TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037096 session_deps_.proxy_service =
7097 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517098 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077099 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467100
7101 HttpRequestInfo request;
7102 request.method = "GET";
bncce36dca22015-04-21 22:11:237103 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467104 request.load_flags = 0;
7105
7106 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177107 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7108 "Host: www.example.org:443\r\n"
7109 "Proxy-Connection: keep-alive\r\n\r\n"),
7110 MockWrite("GET / HTTP/1.1\r\n"
7111 "Host: www.example.org\r\n"
7112 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467113 };
7114
7115 MockRead data_reads[] = {
7116 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7117 MockRead("HTTP/1.1 200 OK\r\n"),
7118 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7119 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067120 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467121 };
7122
7123 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7124 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067125 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7126 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467127
[email protected]bb88e1d32013-05-03 23:11:077128 session_deps_.socket_factory->AddSocketDataProvider(&data);
7129 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7130 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467131
[email protected]49639fa2011-12-20 23:22:417132 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467133
mmenkee65e7af2015-10-13 17:16:427134 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467135 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417136 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467137
[email protected]49639fa2011-12-20 23:22:417138 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467139 EXPECT_EQ(ERR_IO_PENDING, rv);
7140
7141 rv = callback.WaitForResult();
7142 EXPECT_EQ(OK, rv);
7143 const HttpResponseInfo* response = trans->GetResponseInfo();
7144
[email protected]fe2255a2011-09-20 19:37:507145 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467146
7147 EXPECT_TRUE(response->headers->IsKeepAlive());
7148 EXPECT_EQ(200, response->headers->response_code());
7149 EXPECT_EQ(100, response->headers->GetContentLength());
7150 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207151
7152 LoadTimingInfo load_timing_info;
7153 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7154 TestLoadTimingNotReusedWithPac(load_timing_info,
7155 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467156}
7157
[email protected]511f6f52010-12-17 03:58:297158// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027159TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037160 session_deps_.proxy_service =
7161 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517162 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077163 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297164
7165 HttpRequestInfo request;
7166 request.method = "GET";
bncce36dca22015-04-21 22:11:237167 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297168 request.load_flags = 0;
7169
7170 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177171 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7172 "Host: www.example.org:443\r\n"
7173 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297174 };
7175
7176 MockRead data_reads[] = {
7177 MockRead("HTTP/1.1 302 Redirect\r\n"),
7178 MockRead("Location: http://login.example.com/\r\n"),
7179 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067180 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297181 };
7182
7183 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7184 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067185 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297186
[email protected]bb88e1d32013-05-03 23:11:077187 session_deps_.socket_factory->AddSocketDataProvider(&data);
7188 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297189
[email protected]49639fa2011-12-20 23:22:417190 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297191
mmenkee65e7af2015-10-13 17:16:427192 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297193 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417194 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297195
[email protected]49639fa2011-12-20 23:22:417196 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297197 EXPECT_EQ(ERR_IO_PENDING, rv);
7198
7199 rv = callback.WaitForResult();
7200 EXPECT_EQ(OK, rv);
7201 const HttpResponseInfo* response = trans->GetResponseInfo();
7202
[email protected]fe2255a2011-09-20 19:37:507203 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:297204
7205 EXPECT_EQ(302, response->headers->response_code());
7206 std::string url;
7207 EXPECT_TRUE(response->headers->IsRedirect(&url));
7208 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207209
7210 // In the case of redirects from proxies, HttpNetworkTransaction returns
7211 // timing for the proxy connection instead of the connection to the host,
7212 // and no send / receive times.
7213 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7214 LoadTimingInfo load_timing_info;
7215 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7216
7217 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:297218 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207219
7220 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7221 EXPECT_LE(load_timing_info.proxy_resolve_start,
7222 load_timing_info.proxy_resolve_end);
7223 EXPECT_LE(load_timing_info.proxy_resolve_end,
7224 load_timing_info.connect_timing.connect_start);
7225 ExpectConnectTimingHasTimes(
7226 load_timing_info.connect_timing,
7227 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7228
7229 EXPECT_TRUE(load_timing_info.send_start.is_null());
7230 EXPECT_TRUE(load_timing_info.send_end.is_null());
7231 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297232}
7233
7234// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027235TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037236 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297237
7238 HttpRequestInfo request;
7239 request.method = "GET";
bncce36dca22015-04-21 22:11:237240 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297241 request.load_flags = 0;
7242
lgarrona91df87f2014-12-05 00:51:347243 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237244 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:207245 scoped_ptr<SpdyFrame> goaway(
7246 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297247 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137248 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
7249 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297250 };
7251
7252 static const char* const kExtraHeaders[] = {
7253 "location",
7254 "http://login.example.com/",
7255 };
[email protected]ff98d7f02012-03-22 21:44:197256 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:027257 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:297258 arraysize(kExtraHeaders)/2, 1));
7259 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137260 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297261 };
7262
rch8e6c6c42015-05-01 14:05:137263 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7264 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067265 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
rdsmithebb50aa2015-11-12 03:44:387266 proxy_ssl.SetNextProto(GetProtocol());
[email protected]511f6f52010-12-17 03:58:297267
[email protected]bb88e1d32013-05-03 23:11:077268 session_deps_.socket_factory->AddSocketDataProvider(&data);
7269 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297270
[email protected]49639fa2011-12-20 23:22:417271 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297272
mmenkee65e7af2015-10-13 17:16:427273 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297274 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417275 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297276
[email protected]49639fa2011-12-20 23:22:417277 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297278 EXPECT_EQ(ERR_IO_PENDING, rv);
7279
7280 rv = callback.WaitForResult();
7281 EXPECT_EQ(OK, rv);
7282 const HttpResponseInfo* response = trans->GetResponseInfo();
7283
[email protected]fe2255a2011-09-20 19:37:507284 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:297285
7286 EXPECT_EQ(302, response->headers->response_code());
7287 std::string url;
7288 EXPECT_TRUE(response->headers->IsRedirect(&url));
7289 EXPECT_EQ("http://login.example.com/", url);
7290}
7291
[email protected]4eddbc732012-08-09 05:40:177292// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027293TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177294 ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037295 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297296
7297 HttpRequestInfo request;
7298 request.method = "GET";
bncce36dca22015-04-21 22:11:237299 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297300 request.load_flags = 0;
7301
7302 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177303 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7304 "Host: www.example.org:443\r\n"
7305 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297306 };
7307
7308 MockRead data_reads[] = {
7309 MockRead("HTTP/1.1 404 Not Found\r\n"),
7310 MockRead("Content-Length: 23\r\n\r\n"),
7311 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067312 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297313 };
7314
7315 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7316 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067317 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297318
[email protected]bb88e1d32013-05-03 23:11:077319 session_deps_.socket_factory->AddSocketDataProvider(&data);
7320 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297321
[email protected]49639fa2011-12-20 23:22:417322 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297323
mmenkee65e7af2015-10-13 17:16:427324 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297325 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417326 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297327
[email protected]49639fa2011-12-20 23:22:417328 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297329 EXPECT_EQ(ERR_IO_PENDING, rv);
7330
7331 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177332 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297333
[email protected]4eddbc732012-08-09 05:40:177334 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297335}
7336
[email protected]4eddbc732012-08-09 05:40:177337// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027338TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177339 ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037340 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297341
7342 HttpRequestInfo request;
7343 request.method = "GET";
bncce36dca22015-04-21 22:11:237344 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297345 request.load_flags = 0;
7346
lgarrona91df87f2014-12-05 00:51:347347 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237348 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:207349 scoped_ptr<SpdyFrame> rst(
7350 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297351 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137352 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:297353 };
7354
7355 static const char* const kExtraHeaders[] = {
7356 "location",
7357 "http://login.example.com/",
7358 };
[email protected]ff98d7f02012-03-22 21:44:197359 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:027360 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:297361 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:197362 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:027363 spdy_util_.ConstructSpdyBodyFrame(
7364 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297365 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137366 CreateMockRead(*resp.get(), 1),
7367 CreateMockRead(*body.get(), 2),
7368 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297369 };
7370
rch8e6c6c42015-05-01 14:05:137371 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7372 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067373 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
rdsmithebb50aa2015-11-12 03:44:387374 proxy_ssl.SetNextProto(GetProtocol());
[email protected]511f6f52010-12-17 03:58:297375
[email protected]bb88e1d32013-05-03 23:11:077376 session_deps_.socket_factory->AddSocketDataProvider(&data);
7377 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297378
[email protected]49639fa2011-12-20 23:22:417379 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297380
mmenkee65e7af2015-10-13 17:16:427381 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297382 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417383 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297384
[email protected]49639fa2011-12-20 23:22:417385 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297386 EXPECT_EQ(ERR_IO_PENDING, rv);
7387
7388 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177389 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297390
[email protected]4eddbc732012-08-09 05:40:177391 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297392}
7393
[email protected]0c5fb722012-02-28 11:50:357394// Test the request-challenge-retry sequence for basic auth, through
7395// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:027396TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:357397 HttpRequestInfo request;
7398 request.method = "GET";
bncce36dca22015-04-21 22:11:237399 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:357400 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:297401 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:357402
7403 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037404 session_deps_.proxy_service =
7405 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:517406 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077407 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:427408 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:357409
7410 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:347411 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237412 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:207413 scoped_ptr<SpdyFrame> rst(
7414 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
rdsmithebb50aa2015-11-12 03:44:387415 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:357416
7417 // After calling trans->RestartWithAuth(), this is the request we should
7418 // be issuing -- the final header line contains the credentials.
7419 const char* const kAuthCredentials[] = {
7420 "proxy-authorization", "Basic Zm9vOmJhcg==",
7421 };
[email protected]fba2dbde2013-05-24 16:09:017422 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:347423 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:237424 HostPortPair("www.example.org", 443)));
7425 // fetch https://www.example.org/ via HTTP
7426 const char get[] =
7427 "GET / HTTP/1.1\r\n"
7428 "Host: www.example.org\r\n"
7429 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:197430 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:027431 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:357432
7433 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137434 CreateMockWrite(*req, 0, ASYNC),
7435 CreateMockWrite(*rst, 2, ASYNC),
7436 CreateMockWrite(*connect2, 3),
7437 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:357438 };
7439
7440 // The proxy responds to the connect with a 407, using a persistent
7441 // connection.
thestig9d3bb0c2015-01-24 00:49:517442 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:357443 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:357444 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
7445 };
[email protected]745aa9c2014-06-27 02:21:297446 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
7447 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:357448
[email protected]23e482282013-06-14 16:08:027449 scoped_ptr<SpdyFrame> conn_resp(
7450 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:357451 const char resp[] = "HTTP/1.1 200 OK\r\n"
7452 "Content-Length: 5\r\n\r\n";
7453
[email protected]ff98d7f02012-03-22 21:44:197454 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:027455 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:197456 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:027457 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:357458 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137459 CreateMockRead(*conn_auth_resp, 1, ASYNC),
7460 CreateMockRead(*conn_resp, 4, ASYNC),
7461 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
7462 CreateMockRead(*wrapped_body, 7, ASYNC),
7463 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:357464 };
7465
rch8e6c6c42015-05-01 14:05:137466 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7467 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077468 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:357469 // Negotiate SPDY to the proxy
7470 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:387471 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:077472 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:357473 // Vanilla SSL to the server
7474 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077475 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:357476
7477 TestCompletionCallback callback1;
7478
[email protected]262eec82013-03-19 21:01:367479 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507480 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:357481
7482 int rv = trans->Start(&request, callback1.callback(), log.bound());
7483 EXPECT_EQ(ERR_IO_PENDING, rv);
7484
7485 rv = callback1.WaitForResult();
7486 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:467487 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:357488 log.GetEntries(&entries);
7489 size_t pos = ExpectLogContainsSomewhere(
7490 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
7491 NetLog::PHASE_NONE);
7492 ExpectLogContainsSomewhere(
7493 entries, pos,
7494 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
7495 NetLog::PHASE_NONE);
7496
7497 const HttpResponseInfo* response = trans->GetResponseInfo();
7498 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507499 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:357500 EXPECT_EQ(407, response->headers->response_code());
7501 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7502 EXPECT_TRUE(response->auth_challenge.get() != NULL);
7503 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
7504
7505 TestCompletionCallback callback2;
7506
7507 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
7508 callback2.callback());
7509 EXPECT_EQ(ERR_IO_PENDING, rv);
7510
7511 rv = callback2.WaitForResult();
7512 EXPECT_EQ(OK, rv);
7513
7514 response = trans->GetResponseInfo();
7515 ASSERT_TRUE(response != NULL);
7516
7517 EXPECT_TRUE(response->headers->IsKeepAlive());
7518 EXPECT_EQ(200, response->headers->response_code());
7519 EXPECT_EQ(5, response->headers->GetContentLength());
7520 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7521
7522 // The password prompt info should not be set.
7523 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7524
[email protected]029c83b62013-01-24 05:28:207525 LoadTimingInfo load_timing_info;
7526 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7527 TestLoadTimingNotReusedWithPac(load_timing_info,
7528 CONNECT_TIMING_HAS_SSL_TIMES);
7529
[email protected]0c5fb722012-02-28 11:50:357530 trans.reset();
7531 session->CloseAllConnections();
7532}
7533
[email protected]7c6f7ba2012-04-03 04:09:297534// Test that an explicitly trusted SPDY proxy can push a resource from an
7535// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:027536TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:297537 HttpRequestInfo request;
7538 HttpRequestInfo push_request;
7539
[email protected]7c6f7ba2012-04-03 04:09:297540 request.method = "GET";
bncce36dca22015-04-21 22:11:237541 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:297542 push_request.method = "GET";
7543 push_request.url = GURL("http://www.another-origin.com/foo.dat");
7544
[email protected]7c6f7ba2012-04-03 04:09:297545 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037546 session_deps_.proxy_service =
7547 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:517548 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077549 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507550
7551 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:077552 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:507553
mmenkee65e7af2015-10-13 17:16:427554 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:297555
[email protected]cdf8f7e72013-05-23 10:56:467556 scoped_ptr<SpdyFrame> stream1_syn(
7557 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:297558
7559 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137560 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:297561 };
7562
7563 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027564 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:297565
7566 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027567 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:297568
7569 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027570 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:297571 0,
7572 2,
7573 1,
7574 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:437575 const char kPushedData[] = "pushed";
7576 scoped_ptr<SpdyFrame> stream2_body(
7577 spdy_util_.ConstructSpdyBodyFrame(
7578 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:297579
7580 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137581 CreateMockRead(*stream1_reply, 1, ASYNC),
7582 CreateMockRead(*stream2_syn, 2, ASYNC),
7583 CreateMockRead(*stream1_body, 3, ASYNC),
7584 CreateMockRead(*stream2_body, 4, ASYNC),
7585 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:297586 };
7587
rch8e6c6c42015-05-01 14:05:137588 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7589 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077590 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:297591 // Negotiate SPDY to the proxy
7592 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:387593 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:077594 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:297595
[email protected]262eec82013-03-19 21:01:367596 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507597 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:297598 TestCompletionCallback callback;
7599 int rv = trans->Start(&request, callback.callback(), log.bound());
7600 EXPECT_EQ(ERR_IO_PENDING, rv);
7601
7602 rv = callback.WaitForResult();
7603 EXPECT_EQ(OK, rv);
7604 const HttpResponseInfo* response = trans->GetResponseInfo();
7605
[email protected]262eec82013-03-19 21:01:367606 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:507607 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7608 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:297609 EXPECT_EQ(ERR_IO_PENDING, rv);
7610
7611 rv = callback.WaitForResult();
7612 EXPECT_EQ(OK, rv);
7613 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
7614
7615 ASSERT_TRUE(response != NULL);
7616 EXPECT_TRUE(response->headers->IsKeepAlive());
7617
7618 EXPECT_EQ(200, response->headers->response_code());
7619 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7620
7621 std::string response_data;
7622 rv = ReadTransaction(trans.get(), &response_data);
7623 EXPECT_EQ(OK, rv);
7624 EXPECT_EQ("hello!", response_data);
7625
[email protected]029c83b62013-01-24 05:28:207626 LoadTimingInfo load_timing_info;
7627 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7628 TestLoadTimingNotReusedWithPac(load_timing_info,
7629 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7630
[email protected]7c6f7ba2012-04-03 04:09:297631 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:507632 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:297633 EXPECT_EQ(200, push_response->headers->response_code());
7634
7635 rv = ReadTransaction(push_trans.get(), &response_data);
7636 EXPECT_EQ(OK, rv);
7637 EXPECT_EQ("pushed", response_data);
7638
[email protected]029c83b62013-01-24 05:28:207639 LoadTimingInfo push_load_timing_info;
7640 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
7641 TestLoadTimingReusedWithPac(push_load_timing_info);
7642 // The transactions should share a socket ID, despite being for different
7643 // origins.
7644 EXPECT_EQ(load_timing_info.socket_log_id,
7645 push_load_timing_info.socket_log_id);
7646
[email protected]7c6f7ba2012-04-03 04:09:297647 trans.reset();
7648 push_trans.reset();
7649 session->CloseAllConnections();
7650}
7651
[email protected]8c843192012-04-05 07:15:007652// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:027653TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:007654 HttpRequestInfo request;
7655
7656 request.method = "GET";
bncce36dca22015-04-21 22:11:237657 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:007658
[email protected]8c843192012-04-05 07:15:007659 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037660 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:517661 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077662 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507663
7664 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:077665 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:507666
mmenkee65e7af2015-10-13 17:16:427667 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:007668
[email protected]cdf8f7e72013-05-23 10:56:467669 scoped_ptr<SpdyFrame> stream1_syn(
7670 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:007671
7672 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:207673 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:007674
7675 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137676 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:007677 };
7678
7679 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027680 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:007681
7682 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027683 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:007684
7685 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027686 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:007687 0,
7688 2,
7689 1,
7690 "https://www.another-origin.com/foo.dat"));
7691
7692 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137693 CreateMockRead(*stream1_reply, 1, ASYNC),
7694 CreateMockRead(*stream2_syn, 2, ASYNC),
7695 CreateMockRead(*stream1_body, 4, ASYNC),
7696 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:007697 };
7698
rch8e6c6c42015-05-01 14:05:137699 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7700 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077701 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007702 // Negotiate SPDY to the proxy
7703 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:387704 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:077705 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007706
[email protected]262eec82013-03-19 21:01:367707 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507708 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007709 TestCompletionCallback callback;
7710 int rv = trans->Start(&request, callback.callback(), log.bound());
7711 EXPECT_EQ(ERR_IO_PENDING, rv);
7712
7713 rv = callback.WaitForResult();
7714 EXPECT_EQ(OK, rv);
7715 const HttpResponseInfo* response = trans->GetResponseInfo();
7716
7717 ASSERT_TRUE(response != NULL);
7718 EXPECT_TRUE(response->headers->IsKeepAlive());
7719
7720 EXPECT_EQ(200, response->headers->response_code());
7721 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7722
7723 std::string response_data;
7724 rv = ReadTransaction(trans.get(), &response_data);
7725 EXPECT_EQ(OK, rv);
7726 EXPECT_EQ("hello!", response_data);
7727
7728 trans.reset();
7729 session->CloseAllConnections();
7730}
7731
[email protected]2df19bb2010-08-25 20:13:467732// Test HTTPS connections to a site with a bad certificate, going through an
7733// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027734TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037735 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:467736
7737 HttpRequestInfo request;
7738 request.method = "GET";
bncce36dca22015-04-21 22:11:237739 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467740 request.load_flags = 0;
7741
7742 // Attempt to fetch the URL from a server with a bad cert
7743 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:177744 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7745 "Host: www.example.org:443\r\n"
7746 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467747 };
7748
7749 MockRead bad_cert_reads[] = {
7750 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067751 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467752 };
7753
7754 // Attempt to fetch the URL with a good cert
7755 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177756 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7757 "Host: www.example.org:443\r\n"
7758 "Proxy-Connection: keep-alive\r\n\r\n"),
7759 MockWrite("GET / HTTP/1.1\r\n"
7760 "Host: www.example.org\r\n"
7761 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467762 };
7763
7764 MockRead good_cert_reads[] = {
7765 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7766 MockRead("HTTP/1.0 200 OK\r\n"),
7767 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7768 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067769 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467770 };
7771
7772 StaticSocketDataProvider ssl_bad_certificate(
7773 bad_cert_reads, arraysize(bad_cert_reads),
7774 bad_cert_writes, arraysize(bad_cert_writes));
7775 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7776 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067777 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7778 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467779
7780 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077781 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7782 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7783 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467784
7785 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077786 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7787 session_deps_.socket_factory->AddSocketDataProvider(&data);
7788 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467789
[email protected]49639fa2011-12-20 23:22:417790 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467791
mmenkee65e7af2015-10-13 17:16:427792 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467793 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417794 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467795
[email protected]49639fa2011-12-20 23:22:417796 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467797 EXPECT_EQ(ERR_IO_PENDING, rv);
7798
7799 rv = callback.WaitForResult();
7800 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7801
[email protected]49639fa2011-12-20 23:22:417802 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467803 EXPECT_EQ(ERR_IO_PENDING, rv);
7804
7805 rv = callback.WaitForResult();
7806 EXPECT_EQ(OK, rv);
7807
7808 const HttpResponseInfo* response = trans->GetResponseInfo();
7809
[email protected]fe2255a2011-09-20 19:37:507810 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467811 EXPECT_EQ(100, response->headers->GetContentLength());
7812}
7813
[email protected]23e482282013-06-14 16:08:027814TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427815 HttpRequestInfo request;
7816 request.method = "GET";
bncce36dca22015-04-21 22:11:237817 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437818 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7819 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427820
mmenkee65e7af2015-10-13 17:16:427821 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277822 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417823 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277824
[email protected]1c773ea12009-04-28 19:58:427825 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237826 MockWrite(
7827 "GET / HTTP/1.1\r\n"
7828 "Host: www.example.org\r\n"
7829 "Connection: keep-alive\r\n"
7830 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427831 };
7832
7833 // Lastly, the server responds with the actual content.
7834 MockRead data_reads[] = {
7835 MockRead("HTTP/1.0 200 OK\r\n"),
7836 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7837 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067838 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427839 };
7840
[email protected]31a2bfe2010-02-09 08:03:397841 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7842 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077843 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427844
[email protected]49639fa2011-12-20 23:22:417845 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427846
[email protected]49639fa2011-12-20 23:22:417847 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427848 EXPECT_EQ(ERR_IO_PENDING, rv);
7849
7850 rv = callback.WaitForResult();
7851 EXPECT_EQ(OK, rv);
7852}
7853
[email protected]23e482282013-06-14 16:08:027854TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297855 HttpRequestInfo request;
7856 request.method = "GET";
bncce36dca22015-04-21 22:11:237857 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297858 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7859 "Chromium Ultra Awesome X Edition");
7860
rdsmith82957ad2015-09-16 19:42:037861 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:427862 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277863 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417864 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277865
[email protected]da81f132010-08-18 23:39:297866 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177867 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7868 "Host: www.example.org:443\r\n"
7869 "Proxy-Connection: keep-alive\r\n"
7870 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297871 };
7872 MockRead data_reads[] = {
7873 // Return an error, so the transaction stops here (this test isn't
7874 // interested in the rest).
7875 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7876 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7877 MockRead("Proxy-Connection: close\r\n\r\n"),
7878 };
7879
7880 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7881 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077882 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297883
[email protected]49639fa2011-12-20 23:22:417884 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297885
[email protected]49639fa2011-12-20 23:22:417886 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297887 EXPECT_EQ(ERR_IO_PENDING, rv);
7888
7889 rv = callback.WaitForResult();
7890 EXPECT_EQ(OK, rv);
7891}
7892
[email protected]23e482282013-06-14 16:08:027893TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427894 HttpRequestInfo request;
7895 request.method = "GET";
bncce36dca22015-04-21 22:11:237896 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427897 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167898 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7899 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427900
mmenkee65e7af2015-10-13 17:16:427901 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277902 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417903 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277904
[email protected]1c773ea12009-04-28 19:58:427905 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237906 MockWrite(
7907 "GET / HTTP/1.1\r\n"
7908 "Host: www.example.org\r\n"
7909 "Connection: keep-alive\r\n"
7910 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427911 };
7912
7913 // Lastly, the server responds with the actual content.
7914 MockRead data_reads[] = {
7915 MockRead("HTTP/1.0 200 OK\r\n"),
7916 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7917 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067918 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427919 };
7920
[email protected]31a2bfe2010-02-09 08:03:397921 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7922 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077923 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427924
[email protected]49639fa2011-12-20 23:22:417925 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427926
[email protected]49639fa2011-12-20 23:22:417927 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427928 EXPECT_EQ(ERR_IO_PENDING, rv);
7929
7930 rv = callback.WaitForResult();
7931 EXPECT_EQ(OK, rv);
7932}
7933
[email protected]23e482282013-06-14 16:08:027934TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427935 HttpRequestInfo request;
7936 request.method = "POST";
bncce36dca22015-04-21 22:11:237937 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427938
mmenkee65e7af2015-10-13 17:16:427939 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277940 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417941 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277942
[email protected]1c773ea12009-04-28 19:58:427943 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237944 MockWrite(
7945 "POST / HTTP/1.1\r\n"
7946 "Host: www.example.org\r\n"
7947 "Connection: keep-alive\r\n"
7948 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427949 };
7950
7951 // Lastly, the server responds with the actual content.
7952 MockRead data_reads[] = {
7953 MockRead("HTTP/1.0 200 OK\r\n"),
7954 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7955 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067956 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427957 };
7958
[email protected]31a2bfe2010-02-09 08:03:397959 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7960 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077961 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427962
[email protected]49639fa2011-12-20 23:22:417963 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427964
[email protected]49639fa2011-12-20 23:22:417965 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427966 EXPECT_EQ(ERR_IO_PENDING, rv);
7967
7968 rv = callback.WaitForResult();
7969 EXPECT_EQ(OK, rv);
7970}
7971
[email protected]23e482282013-06-14 16:08:027972TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427973 HttpRequestInfo request;
7974 request.method = "PUT";
bncce36dca22015-04-21 22:11:237975 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427976
mmenkee65e7af2015-10-13 17:16:427977 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277978 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417979 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277980
[email protected]1c773ea12009-04-28 19:58:427981 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237982 MockWrite(
7983 "PUT / HTTP/1.1\r\n"
7984 "Host: www.example.org\r\n"
7985 "Connection: keep-alive\r\n"
7986 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427987 };
7988
7989 // Lastly, the server responds with the actual content.
7990 MockRead data_reads[] = {
7991 MockRead("HTTP/1.0 200 OK\r\n"),
7992 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7993 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067994 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427995 };
7996
[email protected]31a2bfe2010-02-09 08:03:397997 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7998 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077999 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428000
[email protected]49639fa2011-12-20 23:22:418001 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428002
[email protected]49639fa2011-12-20 23:22:418003 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428004 EXPECT_EQ(ERR_IO_PENDING, rv);
8005
8006 rv = callback.WaitForResult();
8007 EXPECT_EQ(OK, rv);
8008}
8009
[email protected]23e482282013-06-14 16:08:028010TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428011 HttpRequestInfo request;
8012 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238013 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428014
mmenkee65e7af2015-10-13 17:16:428015 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278016 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418017 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278018
[email protected]1c773ea12009-04-28 19:58:428019 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138020 MockWrite("HEAD / HTTP/1.1\r\n"
8021 "Host: www.example.org\r\n"
8022 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428023 };
8024
8025 // Lastly, the server responds with the actual content.
8026 MockRead data_reads[] = {
8027 MockRead("HTTP/1.0 200 OK\r\n"),
8028 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8029 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068030 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428031 };
8032
[email protected]31a2bfe2010-02-09 08:03:398033 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8034 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078035 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428036
[email protected]49639fa2011-12-20 23:22:418037 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428038
[email protected]49639fa2011-12-20 23:22:418039 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428040 EXPECT_EQ(ERR_IO_PENDING, rv);
8041
8042 rv = callback.WaitForResult();
8043 EXPECT_EQ(OK, rv);
8044}
8045
[email protected]23e482282013-06-14 16:08:028046TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428047 HttpRequestInfo request;
8048 request.method = "GET";
bncce36dca22015-04-21 22:11:238049 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428050 request.load_flags = LOAD_BYPASS_CACHE;
8051
mmenkee65e7af2015-10-13 17:16:428052 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278053 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418054 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278055
[email protected]1c773ea12009-04-28 19:58:428056 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238057 MockWrite(
8058 "GET / HTTP/1.1\r\n"
8059 "Host: www.example.org\r\n"
8060 "Connection: keep-alive\r\n"
8061 "Pragma: no-cache\r\n"
8062 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428063 };
8064
8065 // Lastly, the server responds with the actual content.
8066 MockRead data_reads[] = {
8067 MockRead("HTTP/1.0 200 OK\r\n"),
8068 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8069 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068070 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428071 };
8072
[email protected]31a2bfe2010-02-09 08:03:398073 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8074 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078075 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428076
[email protected]49639fa2011-12-20 23:22:418077 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428078
[email protected]49639fa2011-12-20 23:22:418079 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428080 EXPECT_EQ(ERR_IO_PENDING, rv);
8081
8082 rv = callback.WaitForResult();
8083 EXPECT_EQ(OK, rv);
8084}
8085
[email protected]23e482282013-06-14 16:08:028086TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:428087 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428088 HttpRequestInfo request;
8089 request.method = "GET";
bncce36dca22015-04-21 22:11:238090 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428091 request.load_flags = LOAD_VALIDATE_CACHE;
8092
mmenkee65e7af2015-10-13 17:16:428093 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278094 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418095 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278096
[email protected]1c773ea12009-04-28 19:58:428097 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238098 MockWrite(
8099 "GET / HTTP/1.1\r\n"
8100 "Host: www.example.org\r\n"
8101 "Connection: keep-alive\r\n"
8102 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428103 };
8104
8105 // Lastly, the server responds with the actual content.
8106 MockRead data_reads[] = {
8107 MockRead("HTTP/1.0 200 OK\r\n"),
8108 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8109 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068110 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428111 };
8112
[email protected]31a2bfe2010-02-09 08:03:398113 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8114 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078115 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428116
[email protected]49639fa2011-12-20 23:22:418117 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428118
[email protected]49639fa2011-12-20 23:22:418119 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428120 EXPECT_EQ(ERR_IO_PENDING, rv);
8121
8122 rv = callback.WaitForResult();
8123 EXPECT_EQ(OK, rv);
8124}
8125
[email protected]23e482282013-06-14 16:08:028126TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428127 HttpRequestInfo request;
8128 request.method = "GET";
bncce36dca22015-04-21 22:11:238129 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438130 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428131
mmenkee65e7af2015-10-13 17:16:428132 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278133 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418134 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278135
[email protected]1c773ea12009-04-28 19:58:428136 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238137 MockWrite(
8138 "GET / HTTP/1.1\r\n"
8139 "Host: www.example.org\r\n"
8140 "Connection: keep-alive\r\n"
8141 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428142 };
8143
8144 // Lastly, the server responds with the actual content.
8145 MockRead data_reads[] = {
8146 MockRead("HTTP/1.0 200 OK\r\n"),
8147 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8148 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068149 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428150 };
8151
[email protected]31a2bfe2010-02-09 08:03:398152 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8153 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078154 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428155
[email protected]49639fa2011-12-20 23:22:418156 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428157
[email protected]49639fa2011-12-20 23:22:418158 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428159 EXPECT_EQ(ERR_IO_PENDING, rv);
8160
8161 rv = callback.WaitForResult();
8162 EXPECT_EQ(OK, rv);
8163}
8164
[email protected]23e482282013-06-14 16:08:028165TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478166 HttpRequestInfo request;
8167 request.method = "GET";
bncce36dca22015-04-21 22:11:238168 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438169 request.extra_headers.SetHeader("referer", "www.foo.com");
8170 request.extra_headers.SetHeader("hEllo", "Kitty");
8171 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478172
mmenkee65e7af2015-10-13 17:16:428173 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278174 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418175 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278176
[email protected]270c6412010-03-29 22:02:478177 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238178 MockWrite(
8179 "GET / HTTP/1.1\r\n"
8180 "Host: www.example.org\r\n"
8181 "Connection: keep-alive\r\n"
8182 "referer: www.foo.com\r\n"
8183 "hEllo: Kitty\r\n"
8184 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478185 };
8186
8187 // Lastly, the server responds with the actual content.
8188 MockRead data_reads[] = {
8189 MockRead("HTTP/1.0 200 OK\r\n"),
8190 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8191 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068192 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478193 };
8194
8195 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8196 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078197 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478198
[email protected]49639fa2011-12-20 23:22:418199 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478200
[email protected]49639fa2011-12-20 23:22:418201 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:478202 EXPECT_EQ(ERR_IO_PENDING, rv);
8203
8204 rv = callback.WaitForResult();
8205 EXPECT_EQ(OK, rv);
8206}
8207
[email protected]23e482282013-06-14 16:08:028208TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278209 HttpRequestInfo request;
8210 request.method = "GET";
bncce36dca22015-04-21 22:11:238211 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278212 request.load_flags = 0;
8213
rdsmith82957ad2015-09-16 19:42:038214 session_deps_.proxy_service =
8215 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518216 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078217 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028218
mmenkee65e7af2015-10-13 17:16:428219 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:028220 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418221 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028222
[email protected]3cd17242009-06-23 02:59:028223 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8224 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8225
8226 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238227 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8228 MockWrite(
8229 "GET / HTTP/1.1\r\n"
8230 "Host: www.example.org\r\n"
8231 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028232
8233 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068234 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028235 MockRead("HTTP/1.0 200 OK\r\n"),
8236 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8237 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068238 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028239 };
8240
[email protected]31a2bfe2010-02-09 08:03:398241 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8242 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078243 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028244
[email protected]49639fa2011-12-20 23:22:418245 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028246
[email protected]49639fa2011-12-20 23:22:418247 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028248 EXPECT_EQ(ERR_IO_PENDING, rv);
8249
8250 rv = callback.WaitForResult();
8251 EXPECT_EQ(OK, rv);
8252
8253 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508254 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:028255
[email protected]029c83b62013-01-24 05:28:208256 LoadTimingInfo load_timing_info;
8257 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8258 TestLoadTimingNotReusedWithPac(load_timing_info,
8259 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8260
[email protected]3cd17242009-06-23 02:59:028261 std::string response_text;
8262 rv = ReadTransaction(trans.get(), &response_text);
8263 EXPECT_EQ(OK, rv);
8264 EXPECT_EQ("Payload", response_text);
8265}
8266
[email protected]23e482282013-06-14 16:08:028267TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278268 HttpRequestInfo request;
8269 request.method = "GET";
bncce36dca22015-04-21 22:11:238270 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278271 request.load_flags = 0;
8272
rdsmith82957ad2015-09-16 19:42:038273 session_deps_.proxy_service =
8274 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518275 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078276 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028277
mmenkee65e7af2015-10-13 17:16:428278 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:028279 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418280 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028281
[email protected]3cd17242009-06-23 02:59:028282 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8283 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8284
8285 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238286 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8287 arraysize(write_buffer)),
8288 MockWrite(
8289 "GET / HTTP/1.1\r\n"
8290 "Host: www.example.org\r\n"
8291 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028292
8293 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018294 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8295 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358296 MockRead("HTTP/1.0 200 OK\r\n"),
8297 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8298 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068299 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358300 };
8301
[email protected]31a2bfe2010-02-09 08:03:398302 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8303 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078304 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358305
[email protected]8ddf8322012-02-23 18:08:068306 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078307 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358308
[email protected]49639fa2011-12-20 23:22:418309 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358310
[email protected]49639fa2011-12-20 23:22:418311 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358312 EXPECT_EQ(ERR_IO_PENDING, rv);
8313
8314 rv = callback.WaitForResult();
8315 EXPECT_EQ(OK, rv);
8316
[email protected]029c83b62013-01-24 05:28:208317 LoadTimingInfo load_timing_info;
8318 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8319 TestLoadTimingNotReusedWithPac(load_timing_info,
8320 CONNECT_TIMING_HAS_SSL_TIMES);
8321
[email protected]e0c27be2009-07-15 13:09:358322 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508323 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:358324
8325 std::string response_text;
8326 rv = ReadTransaction(trans.get(), &response_text);
8327 EXPECT_EQ(OK, rv);
8328 EXPECT_EQ("Payload", response_text);
8329}
8330
[email protected]23e482282013-06-14 16:08:028331TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:208332 HttpRequestInfo request;
8333 request.method = "GET";
bncce36dca22015-04-21 22:11:238334 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:208335 request.load_flags = 0;
8336
rdsmith82957ad2015-09-16 19:42:038337 session_deps_.proxy_service =
8338 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518339 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078340 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:208341
mmenkee65e7af2015-10-13 17:16:428342 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:208343 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418344 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:208345
8346 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8347 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8348
8349 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238350 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8351 MockWrite(
8352 "GET / HTTP/1.1\r\n"
8353 "Host: www.example.org\r\n"
8354 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:208355
8356 MockRead data_reads[] = {
8357 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
8358 MockRead("HTTP/1.0 200 OK\r\n"),
8359 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8360 MockRead("Payload"),
8361 MockRead(SYNCHRONOUS, OK)
8362 };
8363
8364 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8365 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078366 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:208367
8368 TestCompletionCallback callback;
8369
8370 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8371 EXPECT_EQ(ERR_IO_PENDING, rv);
8372
8373 rv = callback.WaitForResult();
8374 EXPECT_EQ(OK, rv);
8375
8376 const HttpResponseInfo* response = trans->GetResponseInfo();
8377 ASSERT_TRUE(response != NULL);
8378
8379 LoadTimingInfo load_timing_info;
8380 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8381 TestLoadTimingNotReused(load_timing_info,
8382 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8383
8384 std::string response_text;
8385 rv = ReadTransaction(trans.get(), &response_text);
8386 EXPECT_EQ(OK, rv);
8387 EXPECT_EQ("Payload", response_text);
8388}
8389
[email protected]23e482282013-06-14 16:08:028390TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278391 HttpRequestInfo request;
8392 request.method = "GET";
bncce36dca22015-04-21 22:11:238393 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278394 request.load_flags = 0;
8395
rdsmith82957ad2015-09-16 19:42:038396 session_deps_.proxy_service =
8397 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518398 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078399 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358400
mmenkee65e7af2015-10-13 17:16:428401 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:358402 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418403 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358404
[email protected]e0c27be2009-07-15 13:09:358405 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8406 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378407 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238408 0x05, // Version
8409 0x01, // Command (CONNECT)
8410 0x00, // Reserved.
8411 0x03, // Address type (DOMAINNAME).
8412 0x0F, // Length of domain (15)
8413 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8414 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:378415 };
[email protected]e0c27be2009-07-15 13:09:358416 const char kSOCKS5OkResponse[] =
8417 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
8418
8419 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238420 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8421 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
8422 MockWrite(
8423 "GET / HTTP/1.1\r\n"
8424 "Host: www.example.org\r\n"
8425 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358426
8427 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018428 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8429 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:358430 MockRead("HTTP/1.0 200 OK\r\n"),
8431 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8432 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068433 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358434 };
8435
[email protected]31a2bfe2010-02-09 08:03:398436 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8437 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078438 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358439
[email protected]49639fa2011-12-20 23:22:418440 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358441
[email protected]49639fa2011-12-20 23:22:418442 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358443 EXPECT_EQ(ERR_IO_PENDING, rv);
8444
8445 rv = callback.WaitForResult();
8446 EXPECT_EQ(OK, rv);
8447
8448 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508449 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:358450
[email protected]029c83b62013-01-24 05:28:208451 LoadTimingInfo load_timing_info;
8452 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8453 TestLoadTimingNotReusedWithPac(load_timing_info,
8454 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8455
[email protected]e0c27be2009-07-15 13:09:358456 std::string response_text;
8457 rv = ReadTransaction(trans.get(), &response_text);
8458 EXPECT_EQ(OK, rv);
8459 EXPECT_EQ("Payload", response_text);
8460}
8461
[email protected]23e482282013-06-14 16:08:028462TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278463 HttpRequestInfo request;
8464 request.method = "GET";
bncce36dca22015-04-21 22:11:238465 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278466 request.load_flags = 0;
8467
rdsmith82957ad2015-09-16 19:42:038468 session_deps_.proxy_service =
8469 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518470 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078471 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358472
mmenkee65e7af2015-10-13 17:16:428473 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:358474 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418475 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358476
[email protected]e0c27be2009-07-15 13:09:358477 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8478 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378479 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238480 0x05, // Version
8481 0x01, // Command (CONNECT)
8482 0x00, // Reserved.
8483 0x03, // Address type (DOMAINNAME).
8484 0x0F, // Length of domain (15)
8485 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8486 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:378487 };
8488
[email protected]e0c27be2009-07-15 13:09:358489 const char kSOCKS5OkResponse[] =
8490 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
8491
8492 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238493 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8494 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
8495 arraysize(kSOCKS5OkRequest)),
8496 MockWrite(
8497 "GET / HTTP/1.1\r\n"
8498 "Host: www.example.org\r\n"
8499 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358500
8501 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018502 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8503 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:028504 MockRead("HTTP/1.0 200 OK\r\n"),
8505 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8506 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068507 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028508 };
8509
[email protected]31a2bfe2010-02-09 08:03:398510 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8511 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078512 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028513
[email protected]8ddf8322012-02-23 18:08:068514 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078515 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:028516
[email protected]49639fa2011-12-20 23:22:418517 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028518
[email protected]49639fa2011-12-20 23:22:418519 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028520 EXPECT_EQ(ERR_IO_PENDING, rv);
8521
8522 rv = callback.WaitForResult();
8523 EXPECT_EQ(OK, rv);
8524
8525 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508526 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:028527
[email protected]029c83b62013-01-24 05:28:208528 LoadTimingInfo load_timing_info;
8529 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8530 TestLoadTimingNotReusedWithPac(load_timing_info,
8531 CONNECT_TIMING_HAS_SSL_TIMES);
8532
[email protected]3cd17242009-06-23 02:59:028533 std::string response_text;
8534 rv = ReadTransaction(trans.get(), &response_text);
8535 EXPECT_EQ(OK, rv);
8536 EXPECT_EQ("Payload", response_text);
8537}
8538
[email protected]448d4ca52012-03-04 04:12:238539namespace {
8540
[email protected]04e5be32009-06-26 20:00:318541// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:068542
8543struct GroupNameTest {
8544 std::string proxy_server;
8545 std::string url;
8546 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:188547 bool ssl;
[email protected]2d731a32010-04-29 01:04:068548};
8549
mmenkee65e7af2015-10-13 17:16:428550scoped_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:438551 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:078552 SpdySessionDependencies* session_deps_) {
mmenkee65e7af2015-10-13 17:16:428553 scoped_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:068554
[email protected]30d4c022013-07-18 22:58:168555 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538556 session->http_server_properties();
bnccacc0992015-03-20 20:22:228557 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:258558 AlternateProtocolFromNextProto(next_proto), "", 443);
bnc7dc7e1b42015-07-28 14:43:128559 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:228560 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:128561 HostPortPair("host.with.alternate", 80), alternative_service, 1.0,
8562 expiration);
[email protected]2d731a32010-04-29 01:04:068563
8564 return session;
8565}
8566
mmenkee65e7af2015-10-13 17:16:428567int GroupNameTransactionHelper(const std::string& url,
8568 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:068569 HttpRequestInfo request;
8570 request.method = "GET";
8571 request.url = GURL(url);
8572 request.load_flags = 0;
8573
[email protected]262eec82013-03-19 21:01:368574 scoped_ptr<HttpTransaction> trans(
mmenkee65e7af2015-10-13 17:16:428575 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:278576
[email protected]49639fa2011-12-20 23:22:418577 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:068578
8579 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:418580 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:068581}
8582
[email protected]448d4ca52012-03-04 04:12:238583} // namespace
8584
[email protected]23e482282013-06-14 16:08:028585TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:068586 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238587 {
8588 "", // unused
8589 "http://www.example.org/direct",
8590 "www.example.org:80",
8591 false,
8592 },
8593 {
8594 "", // unused
8595 "http://[2001:1418:13:1::25]/direct",
8596 "[2001:1418:13:1::25]:80",
8597 false,
8598 },
[email protected]04e5be32009-06-26 20:00:318599
bncce36dca22015-04-21 22:11:238600 // SSL Tests
8601 {
8602 "", // unused
8603 "https://www.example.org/direct_ssl",
8604 "ssl/www.example.org:443",
8605 true,
8606 },
8607 {
8608 "", // unused
8609 "https://[2001:1418:13:1::25]/direct",
8610 "ssl/[2001:1418:13:1::25]:443",
8611 true,
8612 },
8613 {
8614 "", // unused
8615 "http://host.with.alternate/direct",
8616 "ssl/host.with.alternate:443",
8617 true,
8618 },
[email protected]2d731a32010-04-29 01:04:068619 };
[email protected]2ff8b312010-04-26 22:20:548620
bnc55ff9da2015-08-19 18:42:358621 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068622
viettrungluue4a8b882014-10-16 06:17:388623 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038624 session_deps_.proxy_service =
8625 ProxyService::CreateFixed(tests[i].proxy_server);
mmenkee65e7af2015-10-13 17:16:428626 scoped_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:388627 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068628
mmenkee65e7af2015-10-13 17:16:428629 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:288630 CaptureGroupNameTransportSocketPool* transport_conn_pool =
8631 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138632 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348633 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:448634 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8635 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028636 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
8637 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518638 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068639
8640 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:428641 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:188642 if (tests[i].ssl)
8643 EXPECT_EQ(tests[i].expected_group_name,
8644 ssl_conn_pool->last_group_name_received());
8645 else
8646 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:288647 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068648 }
[email protected]2d731a32010-04-29 01:04:068649}
8650
[email protected]23e482282013-06-14 16:08:028651TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:068652 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238653 {
8654 "http_proxy",
8655 "http://www.example.org/http_proxy_normal",
8656 "www.example.org:80",
8657 false,
8658 },
[email protected]2d731a32010-04-29 01:04:068659
bncce36dca22015-04-21 22:11:238660 // SSL Tests
8661 {
8662 "http_proxy",
8663 "https://www.example.org/http_connect_ssl",
8664 "ssl/www.example.org:443",
8665 true,
8666 },
[email protected]af3490e2010-10-16 21:02:298667
bncce36dca22015-04-21 22:11:238668 {
8669 "http_proxy",
8670 "http://host.with.alternate/direct",
8671 "ssl/host.with.alternate:443",
8672 true,
8673 },
[email protected]45499252013-01-23 17:12:568674
bncce36dca22015-04-21 22:11:238675 {
8676 "http_proxy",
8677 "ftp://ftp.google.com/http_proxy_normal",
8678 "ftp/ftp.google.com:21",
8679 false,
8680 },
[email protected]2d731a32010-04-29 01:04:068681 };
8682
bnc55ff9da2015-08-19 18:42:358683 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068684
viettrungluue4a8b882014-10-16 06:17:388685 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038686 session_deps_.proxy_service =
8687 ProxyService::CreateFixed(tests[i].proxy_server);
mmenkee65e7af2015-10-13 17:16:428688 scoped_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:388689 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068690
mmenkee65e7af2015-10-13 17:16:428691 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:068692
[email protected]e60e47a2010-07-14 03:37:188693 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138694 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348695 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138696 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348697 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028698
[email protected]831e4a32013-11-14 02:14:448699 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8700 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028701 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8702 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518703 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068704
8705 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:428706 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:188707 if (tests[i].ssl)
8708 EXPECT_EQ(tests[i].expected_group_name,
8709 ssl_conn_pool->last_group_name_received());
8710 else
8711 EXPECT_EQ(tests[i].expected_group_name,
8712 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068713 }
[email protected]2d731a32010-04-29 01:04:068714}
8715
[email protected]23e482282013-06-14 16:08:028716TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068717 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238718 {
8719 "socks4://socks_proxy:1080",
8720 "http://www.example.org/socks4_direct",
8721 "socks4/www.example.org:80",
8722 false,
8723 },
8724 {
8725 "socks5://socks_proxy:1080",
8726 "http://www.example.org/socks5_direct",
8727 "socks5/www.example.org:80",
8728 false,
8729 },
[email protected]2d731a32010-04-29 01:04:068730
bncce36dca22015-04-21 22:11:238731 // SSL Tests
8732 {
8733 "socks4://socks_proxy:1080",
8734 "https://www.example.org/socks4_ssl",
8735 "socks4/ssl/www.example.org:443",
8736 true,
8737 },
8738 {
8739 "socks5://socks_proxy:1080",
8740 "https://www.example.org/socks5_ssl",
8741 "socks5/ssl/www.example.org:443",
8742 true,
8743 },
[email protected]af3490e2010-10-16 21:02:298744
bncce36dca22015-04-21 22:11:238745 {
8746 "socks4://socks_proxy:1080",
8747 "http://host.with.alternate/direct",
8748 "socks4/ssl/host.with.alternate:443",
8749 true,
8750 },
[email protected]04e5be32009-06-26 20:00:318751 };
8752
bnc55ff9da2015-08-19 18:42:358753 session_deps_.use_alternative_services = true;
[email protected]2ff8b312010-04-26 22:20:548754
viettrungluue4a8b882014-10-16 06:17:388755 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038756 session_deps_.proxy_service =
8757 ProxyService::CreateFixed(tests[i].proxy_server);
mmenkee65e7af2015-10-13 17:16:428758 scoped_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:388759 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028760
mmenkee65e7af2015-10-13 17:16:428761 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:318762
[email protected]e60e47a2010-07-14 03:37:188763 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138764 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348765 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138766 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348767 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028768
[email protected]831e4a32013-11-14 02:14:448769 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8770 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028771 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8772 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518773 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318774
[email protected]262eec82013-03-19 21:01:368775 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508776 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318777
[email protected]2d731a32010-04-29 01:04:068778 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:428779 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:188780 if (tests[i].ssl)
8781 EXPECT_EQ(tests[i].expected_group_name,
8782 ssl_conn_pool->last_group_name_received());
8783 else
8784 EXPECT_EQ(tests[i].expected_group_name,
8785 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318786 }
8787}
8788
[email protected]23e482282013-06-14 16:08:028789TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278790 HttpRequestInfo request;
8791 request.method = "GET";
bncce36dca22015-04-21 22:11:238792 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278793
rdsmith82957ad2015-09-16 19:42:038794 session_deps_.proxy_service =
8795 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:328796
[email protected]69719062010-01-05 20:09:218797 // This simulates failure resolving all hostnames; that means we will fail
8798 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078799 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328800
mmenkee65e7af2015-10-13 17:16:428801 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258802 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418803 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258804
[email protected]49639fa2011-12-20 23:22:418805 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258806
[email protected]49639fa2011-12-20 23:22:418807 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258808 EXPECT_EQ(ERR_IO_PENDING, rv);
8809
[email protected]9172a982009-06-06 00:30:258810 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018811 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258812}
8813
[email protected]685af592010-05-11 19:31:248814// Base test to make sure that when the load flags for a request specify to
8815// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028816void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078817 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278818 // Issue a request, asking to bypass the cache(s).
8819 HttpRequestInfo request;
8820 request.method = "GET";
8821 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238822 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278823
[email protected]a2c2fb92009-07-18 07:31:048824 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078825 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328826
mmenkee65e7af2015-10-13 17:16:428827 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:078828 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418829 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288830
bncce36dca22015-04-21 22:11:238831 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288832 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298833 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078834 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238835 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8836 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478837 EXPECT_EQ(ERR_IO_PENDING, rv);
8838 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288839 EXPECT_EQ(OK, rv);
8840
8841 // Verify that it was added to host cache, by doing a subsequent async lookup
8842 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078843 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238844 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8845 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328846 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288847
bncce36dca22015-04-21 22:11:238848 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288849 // we can tell if the next lookup hit the cache, or the "network".
8850 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238851 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288852
8853 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8854 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068855 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398856 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078857 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288858
[email protected]3b9cca42009-06-16 01:08:288859 // Run the request.
[email protected]49639fa2011-12-20 23:22:418860 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288861 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418862 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288863
8864 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238865 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288866 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8867}
8868
[email protected]685af592010-05-11 19:31:248869// There are multiple load flags that should trigger the host cache bypass.
8870// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028871TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248872 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8873}
8874
[email protected]23e482282013-06-14 16:08:028875TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248876 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8877}
8878
[email protected]23e482282013-06-14 16:08:028879TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248880 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8881}
8882
[email protected]0877e3d2009-10-17 22:29:578883// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028884TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578885 HttpRequestInfo request;
8886 request.method = "GET";
8887 request.url = GURL("http://www.foo.com/");
8888 request.load_flags = 0;
8889
8890 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068891 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578892 };
[email protected]31a2bfe2010-02-09 08:03:398893 StaticSocketDataProvider data(NULL, 0,
8894 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078895 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenkee65e7af2015-10-13 17:16:428896 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578897
[email protected]49639fa2011-12-20 23:22:418898 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578899
8900 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418901 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578902
[email protected]49639fa2011-12-20 23:22:418903 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578904 EXPECT_EQ(ERR_IO_PENDING, rv);
8905
8906 rv = callback.WaitForResult();
8907 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:598908
8909 IPEndPoint endpoint;
8910 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
8911 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:578912}
8913
zmo9528c9f42015-08-04 22:12:088914// Check that a connection closed after the start of the headers finishes ok.
8915TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578916 HttpRequestInfo request;
8917 request.method = "GET";
8918 request.url = GURL("http://www.foo.com/");
8919 request.load_flags = 0;
8920
8921 MockRead data_reads[] = {
8922 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068923 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578924 };
8925
[email protected]31a2bfe2010-02-09 08:03:398926 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078927 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenkee65e7af2015-10-13 17:16:428928 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578929
[email protected]49639fa2011-12-20 23:22:418930 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578931
8932 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418933 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578934
[email protected]49639fa2011-12-20 23:22:418935 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578936 EXPECT_EQ(ERR_IO_PENDING, rv);
8937
8938 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:088939 EXPECT_EQ(OK, rv);
8940
8941 const HttpResponseInfo* response = trans->GetResponseInfo();
8942 ASSERT_TRUE(response != NULL);
8943
8944 EXPECT_TRUE(response->headers.get() != NULL);
8945 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8946
8947 std::string response_data;
8948 rv = ReadTransaction(trans.get(), &response_data);
8949 EXPECT_EQ(OK, rv);
8950 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:598951
8952 IPEndPoint endpoint;
8953 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
8954 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:578955}
8956
8957// Make sure that a dropped connection while draining the body for auth
8958// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028959TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578960 HttpRequestInfo request;
8961 request.method = "GET";
bncce36dca22015-04-21 22:11:238962 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578963 request.load_flags = 0;
8964
8965 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238966 MockWrite(
8967 "GET / HTTP/1.1\r\n"
8968 "Host: www.example.org\r\n"
8969 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578970 };
8971
8972 MockRead data_reads1[] = {
8973 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8974 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8975 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8976 MockRead("Content-Length: 14\r\n\r\n"),
8977 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068978 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578979 };
8980
[email protected]31a2bfe2010-02-09 08:03:398981 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8982 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078983 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578984
8985 // After calling trans->RestartWithAuth(), this is the request we should
8986 // be issuing -- the final header line contains the credentials.
8987 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238988 MockWrite(
8989 "GET / HTTP/1.1\r\n"
8990 "Host: www.example.org\r\n"
8991 "Connection: keep-alive\r\n"
8992 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578993 };
8994
8995 // Lastly, the server responds with the actual content.
8996 MockRead data_reads2[] = {
8997 MockRead("HTTP/1.1 200 OK\r\n"),
8998 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8999 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069000 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579001 };
9002
[email protected]31a2bfe2010-02-09 08:03:399003 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9004 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079005 session_deps_.socket_factory->AddSocketDataProvider(&data2);
mmenkee65e7af2015-10-13 17:16:429006 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579007
[email protected]49639fa2011-12-20 23:22:419008 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579009
[email protected]262eec82013-03-19 21:01:369010 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509011 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509012
[email protected]49639fa2011-12-20 23:22:419013 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579014 EXPECT_EQ(ERR_IO_PENDING, rv);
9015
9016 rv = callback1.WaitForResult();
9017 EXPECT_EQ(OK, rv);
9018
9019 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509020 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049021 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579022
[email protected]49639fa2011-12-20 23:22:419023 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579024
[email protected]49639fa2011-12-20 23:22:419025 rv = trans->RestartWithAuth(
9026 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:579027 EXPECT_EQ(ERR_IO_PENDING, rv);
9028
9029 rv = callback2.WaitForResult();
9030 EXPECT_EQ(OK, rv);
9031
9032 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509033 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:579034 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9035 EXPECT_EQ(100, response->headers->GetContentLength());
9036}
9037
9038// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:029039TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039040 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579041
9042 HttpRequestInfo request;
9043 request.method = "GET";
bncce36dca22015-04-21 22:11:239044 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579045 request.load_flags = 0;
9046
9047 MockRead proxy_reads[] = {
9048 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069049 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579050 };
9051
[email protected]31a2bfe2010-02-09 08:03:399052 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069053 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579054
[email protected]bb88e1d32013-05-03 23:11:079055 session_deps_.socket_factory->AddSocketDataProvider(&data);
9056 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579057
[email protected]49639fa2011-12-20 23:22:419058 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579059
[email protected]bb88e1d32013-05-03 23:11:079060 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579061
mmenkee65e7af2015-10-13 17:16:429062 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579063 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419064 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579065
[email protected]49639fa2011-12-20 23:22:419066 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579067 EXPECT_EQ(ERR_IO_PENDING, rv);
9068
9069 rv = callback.WaitForResult();
9070 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
9071}
9072
[email protected]23e482282013-06-14 16:08:029073TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469074 HttpRequestInfo request;
9075 request.method = "GET";
bncce36dca22015-04-21 22:11:239076 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469077 request.load_flags = 0;
9078
mmenkee65e7af2015-10-13 17:16:429079 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:279080 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419081 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:279082
[email protected]e22e1362009-11-23 21:31:129083 MockRead data_reads[] = {
9084 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069085 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129086 };
[email protected]9492e4a2010-02-24 00:58:469087
9088 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079089 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469090
[email protected]49639fa2011-12-20 23:22:419091 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469092
[email protected]49639fa2011-12-20 23:22:419093 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:469094 EXPECT_EQ(ERR_IO_PENDING, rv);
9095
9096 EXPECT_EQ(OK, callback.WaitForResult());
9097
9098 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509099 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:469100
[email protected]90499482013-06-01 00:39:509101 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:469102 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9103
9104 std::string response_data;
9105 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:239106 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:129107}
9108
[email protected]23e482282013-06-14 16:08:029109TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159110 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529111 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:339112 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219113 UploadFileElementReader::ScopedOverridingContentLengthForTests
9114 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339115
olli.raula6df48b2a2015-11-26 07:40:229116 std::vector<scoped_ptr<UploadElementReader>> element_readers;
9117 element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
9118 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0, kuint64max,
9119 base::Time())));
9120 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279121
9122 HttpRequestInfo request;
9123 request.method = "POST";
bncce36dca22015-04-21 22:11:239124 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279125 request.upload_data_stream = &upload_data_stream;
9126 request.load_flags = 0;
9127
mmenkee65e7af2015-10-13 17:16:429128 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:279129 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419130 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:339131
9132 MockRead data_reads[] = {
9133 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9134 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069135 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339136 };
[email protected]31a2bfe2010-02-09 08:03:399137 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079138 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339139
[email protected]49639fa2011-12-20 23:22:419140 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339141
[email protected]49639fa2011-12-20 23:22:419142 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:339143 EXPECT_EQ(ERR_IO_PENDING, rv);
9144
9145 rv = callback.WaitForResult();
9146 EXPECT_EQ(OK, rv);
9147
9148 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509149 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:339150
[email protected]90499482013-06-01 00:39:509151 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:339152 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9153
9154 std::string response_data;
9155 rv = ReadTransaction(trans.get(), &response_data);
9156 EXPECT_EQ(OK, rv);
9157 EXPECT_EQ("hello world", response_data);
9158
[email protected]dd3aa792013-07-16 19:10:239159 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339160}
9161
[email protected]23e482282013-06-14 16:08:029162TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159163 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529164 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369165 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:309166 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:369167 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119168 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369169
olli.raula6df48b2a2015-11-26 07:40:229170 std::vector<scoped_ptr<UploadElementReader>> element_readers;
9171 element_readers.push_back(make_scoped_ptr(
skyostil4891b25b2015-06-11 11:43:459172 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
olli.raula6df48b2a2015-11-26 07:40:229173 temp_file, 0, kuint64max, base::Time())));
9174 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279175
9176 HttpRequestInfo request;
9177 request.method = "POST";
bncce36dca22015-04-21 22:11:239178 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279179 request.upload_data_stream = &upload_data_stream;
9180 request.load_flags = 0;
9181
[email protected]999dd8c2013-11-12 06:45:549182 // If we try to upload an unreadable file, the transaction should fail.
mmenkee65e7af2015-10-13 17:16:429183 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:279184 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419185 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:369186
[email protected]999dd8c2013-11-12 06:45:549187 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079188 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369189
[email protected]49639fa2011-12-20 23:22:419190 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369191
[email protected]49639fa2011-12-20 23:22:419192 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:369193 EXPECT_EQ(ERR_IO_PENDING, rv);
9194
9195 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:549196 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:369197
[email protected]dd3aa792013-07-16 19:10:239198 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369199}
9200
[email protected]02cad5d2013-10-02 08:14:039201TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
9202 class FakeUploadElementReader : public UploadElementReader {
9203 public:
9204 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209205 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039206
9207 const CompletionCallback& callback() const { return callback_; }
9208
9209 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209210 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039211 callback_ = callback;
9212 return ERR_IO_PENDING;
9213 }
dchengb03027d2014-10-21 12:00:209214 uint64 GetContentLength() const override { return 0; }
9215 uint64 BytesRemaining() const override { return 0; }
9216 int Read(IOBuffer* buf,
9217 int buf_length,
9218 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039219 return ERR_FAILED;
9220 }
9221
9222 private:
9223 CompletionCallback callback_;
9224 };
9225
9226 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
olli.raula6df48b2a2015-11-26 07:40:229227 std::vector<scoped_ptr<UploadElementReader>> element_readers;
9228 element_readers.push_back(make_scoped_ptr(fake_reader));
9229 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039230
9231 HttpRequestInfo request;
9232 request.method = "POST";
bncce36dca22015-04-21 22:11:239233 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039234 request.upload_data_stream = &upload_data_stream;
9235 request.load_flags = 0;
9236
mmenkee65e7af2015-10-13 17:16:429237 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:039238 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419239 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039240
9241 StaticSocketDataProvider data;
9242 session_deps_.socket_factory->AddSocketDataProvider(&data);
9243
9244 TestCompletionCallback callback;
9245 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9246 EXPECT_EQ(ERR_IO_PENDING, rv);
9247 base::MessageLoop::current()->RunUntilIdle();
9248
9249 // Transaction is pending on request body initialization.
9250 ASSERT_FALSE(fake_reader->callback().is_null());
9251
9252 // Return Init()'s result after the transaction gets destroyed.
9253 trans.reset();
9254 fake_reader->callback().Run(OK); // Should not crash.
9255}
9256
[email protected]aeefc9e82010-02-19 16:18:279257// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:029258TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279259 HttpRequestInfo request;
9260 request.method = "GET";
bncce36dca22015-04-21 22:11:239261 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279262 request.load_flags = 0;
9263
9264 // First transaction will request a resource and receive a Basic challenge
9265 // with realm="first_realm".
9266 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239267 MockWrite(
9268 "GET / HTTP/1.1\r\n"
9269 "Host: www.example.org\r\n"
9270 "Connection: keep-alive\r\n"
9271 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279272 };
9273 MockRead data_reads1[] = {
9274 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9275 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9276 "\r\n"),
9277 };
9278
9279 // After calling trans->RestartWithAuth(), provide an Authentication header
9280 // for first_realm. The server will reject and provide a challenge with
9281 // second_realm.
9282 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239283 MockWrite(
9284 "GET / HTTP/1.1\r\n"
9285 "Host: www.example.org\r\n"
9286 "Connection: keep-alive\r\n"
9287 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9288 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279289 };
9290 MockRead data_reads2[] = {
9291 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9292 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9293 "\r\n"),
9294 };
9295
9296 // This again fails, and goes back to first_realm. Make sure that the
9297 // entry is removed from cache.
9298 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239299 MockWrite(
9300 "GET / HTTP/1.1\r\n"
9301 "Host: www.example.org\r\n"
9302 "Connection: keep-alive\r\n"
9303 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9304 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279305 };
9306 MockRead data_reads3[] = {
9307 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9308 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9309 "\r\n"),
9310 };
9311
9312 // Try one last time (with the correct password) and get the resource.
9313 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239314 MockWrite(
9315 "GET / HTTP/1.1\r\n"
9316 "Host: www.example.org\r\n"
9317 "Connection: keep-alive\r\n"
9318 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9319 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279320 };
9321 MockRead data_reads4[] = {
9322 MockRead("HTTP/1.1 200 OK\r\n"
9323 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509324 "Content-Length: 5\r\n"
9325 "\r\n"
9326 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279327 };
9328
9329 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9330 data_writes1, arraysize(data_writes1));
9331 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9332 data_writes2, arraysize(data_writes2));
9333 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9334 data_writes3, arraysize(data_writes3));
9335 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9336 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079337 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9338 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9339 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9340 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279341
[email protected]49639fa2011-12-20 23:22:419342 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279343
mmenkee65e7af2015-10-13 17:16:429344 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:509345 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419346 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509347
[email protected]aeefc9e82010-02-19 16:18:279348 // Issue the first request with Authorize headers. There should be a
9349 // password prompt for first_realm waiting to be filled in after the
9350 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419351 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:279352 EXPECT_EQ(ERR_IO_PENDING, rv);
9353 rv = callback1.WaitForResult();
9354 EXPECT_EQ(OK, rv);
9355 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509356 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049357 const AuthChallengeInfo* challenge = response->auth_challenge.get();
9358 ASSERT_FALSE(challenge == NULL);
9359 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239360 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049361 EXPECT_EQ("first_realm", challenge->realm);
9362 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279363
9364 // Issue the second request with an incorrect password. There should be a
9365 // password prompt for second_realm waiting to be filled in after the
9366 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419367 TestCompletionCallback callback2;
9368 rv = trans->RestartWithAuth(
9369 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:279370 EXPECT_EQ(ERR_IO_PENDING, rv);
9371 rv = callback2.WaitForResult();
9372 EXPECT_EQ(OK, rv);
9373 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509374 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049375 challenge = response->auth_challenge.get();
9376 ASSERT_FALSE(challenge == NULL);
9377 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239378 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049379 EXPECT_EQ("second_realm", challenge->realm);
9380 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279381
9382 // Issue the third request with another incorrect password. There should be
9383 // a password prompt for first_realm waiting to be filled in. If the password
9384 // prompt is not present, it indicates that the HttpAuthCacheEntry for
9385 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:419386 TestCompletionCallback callback3;
9387 rv = trans->RestartWithAuth(
9388 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:279389 EXPECT_EQ(ERR_IO_PENDING, rv);
9390 rv = callback3.WaitForResult();
9391 EXPECT_EQ(OK, rv);
9392 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509393 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049394 challenge = response->auth_challenge.get();
9395 ASSERT_FALSE(challenge == NULL);
9396 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239397 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049398 EXPECT_EQ("first_realm", challenge->realm);
9399 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279400
9401 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:419402 TestCompletionCallback callback4;
9403 rv = trans->RestartWithAuth(
9404 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:279405 EXPECT_EQ(ERR_IO_PENDING, rv);
9406 rv = callback4.WaitForResult();
9407 EXPECT_EQ(OK, rv);
9408 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509409 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:279410 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9411}
9412
bncc958faa2015-07-31 18:14:529413TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
9414 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359415 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529416
9417 std::string alternative_service_http_header =
9418 GetAlternativeServiceHttpHeader();
9419
9420 MockRead data_reads[] = {
9421 MockRead("HTTP/1.1 200 OK\r\n"),
9422 MockRead(alternative_service_http_header.c_str()),
9423 MockRead("\r\n"),
9424 MockRead("hello world"),
9425 MockRead(SYNCHRONOUS, OK),
9426 };
9427
9428 HttpRequestInfo request;
9429 request.method = "GET";
9430 request.url = GURL("http://www.example.org/");
9431 request.load_flags = 0;
9432
9433 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9434
9435 session_deps_.socket_factory->AddSocketDataProvider(&data);
9436
9437 TestCompletionCallback callback;
9438
mmenkee65e7af2015-10-13 17:16:429439 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529440 scoped_ptr<HttpTransaction> trans(
9441 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9442
9443 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9444 EXPECT_EQ(ERR_IO_PENDING, rv);
9445
9446 HostPortPair http_host_port_pair("www.example.org", 80);
9447 HttpServerProperties& http_server_properties =
9448 *session->http_server_properties();
9449 AlternativeServiceVector alternative_service_vector =
9450 http_server_properties.GetAlternativeServices(http_host_port_pair);
9451 EXPECT_TRUE(alternative_service_vector.empty());
9452
9453 EXPECT_EQ(OK, callback.WaitForResult());
9454
9455 const HttpResponseInfo* response = trans->GetResponseInfo();
9456 ASSERT_TRUE(response != NULL);
9457 ASSERT_TRUE(response->headers.get() != NULL);
9458 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9459 EXPECT_FALSE(response->was_fetched_via_spdy);
9460 EXPECT_FALSE(response->was_npn_negotiated);
9461
9462 std::string response_data;
9463 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9464 EXPECT_EQ("hello world", response_data);
9465
9466 alternative_service_vector =
9467 http_server_properties.GetAlternativeServices(http_host_port_pair);
9468 ASSERT_EQ(1u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:389469 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:529470 alternative_service_vector[0].protocol);
9471 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9472 EXPECT_EQ(443, alternative_service_vector[0].port);
9473}
9474
bnc4f575852015-10-14 18:35:089475TEST_P(HttpNetworkTransactionTest, ClearAlternativeServices) {
9476 session_deps_.next_protos = SpdyNextProtos();
9477 session_deps_.use_alternative_services = true;
9478
9479 // Set an alternative service for origin.
9480 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9481 HttpServerProperties& http_server_properties =
9482 *session->http_server_properties();
9483 HostPortPair http_host_port_pair("www.example.org", 80);
9484 AlternativeService alternative_service(QUIC, "", 80);
9485 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9486 http_server_properties.SetAlternativeService(
9487 http_host_port_pair, alternative_service, 1.0, expiration);
9488 AlternativeServiceVector alternative_service_vector =
9489 http_server_properties.GetAlternativeServices(http_host_port_pair);
9490 EXPECT_EQ(1u, alternative_service_vector.size());
9491
9492 // Send a clear header.
9493 MockRead data_reads[] = {
9494 MockRead("HTTP/1.1 200 OK\r\n"),
9495 MockRead("Alt-Svc: clear\r\n"),
9496 MockRead("\r\n"),
9497 MockRead("hello world"),
9498 MockRead(SYNCHRONOUS, OK),
9499 };
9500 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
9501 session_deps_.socket_factory->AddSocketDataProvider(&data);
9502
9503 HttpRequestInfo request;
9504 request.method = "GET";
9505 request.url = GURL("http://www.example.org/");
9506 request.load_flags = 0;
9507
9508 TestCompletionCallback callback;
9509
9510 scoped_ptr<HttpTransaction> trans(
9511 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9512
9513 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9514 EXPECT_EQ(OK, callback.GetResult(rv));
9515
9516 const HttpResponseInfo* response = trans->GetResponseInfo();
9517 ASSERT_TRUE(response != nullptr);
9518 ASSERT_TRUE(response->headers.get() != nullptr);
9519 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9520 EXPECT_FALSE(response->was_fetched_via_spdy);
9521 EXPECT_FALSE(response->was_npn_negotiated);
9522
9523 std::string response_data;
9524 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9525 EXPECT_EQ("hello world", response_data);
9526
9527 alternative_service_vector =
9528 http_server_properties.GetAlternativeServices(http_host_port_pair);
9529 EXPECT_TRUE(alternative_service_vector.empty());
9530}
9531
bnc54ec34b72015-08-26 19:34:569532// Alternative Service headers must be ignored when |use_alternative_services|
9533// is false.
9534TEST_P(HttpNetworkTransactionTest, DoNotHonorAlternativeServiceHeader) {
9535 session_deps_.next_protos = SpdyNextProtos();
9536 session_deps_.use_alternative_services = false;
9537
9538 std::string alternative_service_http_header =
9539 GetAlternativeServiceHttpHeader();
9540
9541 MockRead data_reads[] = {
9542 MockRead("HTTP/1.1 200 OK\r\n"),
9543 MockRead(alternative_service_http_header.c_str()),
9544 MockRead("\r\n"),
9545 MockRead("hello world"),
9546 MockRead(SYNCHRONOUS, OK),
9547 };
9548
9549 HttpRequestInfo request;
9550 request.method = "GET";
9551 request.url = GURL("http://www.example.org/");
9552 request.load_flags = 0;
9553
9554 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
9555
9556 session_deps_.socket_factory->AddSocketDataProvider(&data);
9557
9558 TestCompletionCallback callback;
9559
mmenkee65e7af2015-10-13 17:16:429560 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc54ec34b72015-08-26 19:34:569561 scoped_ptr<HttpTransaction> trans(
9562 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9563
9564 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9565 EXPECT_EQ(ERR_IO_PENDING, rv);
9566
9567 HostPortPair http_host_port_pair("www.example.org", 80);
9568 HttpServerProperties& http_server_properties =
9569 *session->http_server_properties();
9570 AlternativeServiceVector alternative_service_vector =
9571 http_server_properties.GetAlternativeServices(http_host_port_pair);
9572 EXPECT_TRUE(alternative_service_vector.empty());
9573
9574 EXPECT_EQ(OK, callback.WaitForResult());
9575
9576 const HttpResponseInfo* response = trans->GetResponseInfo();
9577 ASSERT_TRUE(response != nullptr);
9578 ASSERT_TRUE(response->headers.get() != nullptr);
9579 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9580 EXPECT_FALSE(response->was_fetched_via_spdy);
9581 EXPECT_FALSE(response->was_npn_negotiated);
9582
9583 std::string response_data;
9584 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9585 EXPECT_EQ("hello world", response_data);
9586
9587 alternative_service_vector =
9588 http_server_properties.GetAlternativeServices(http_host_port_pair);
9589 EXPECT_TRUE(alternative_service_vector.empty());
9590}
9591
bncc958faa2015-07-31 18:14:529592TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
9593 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359594 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529595
9596 MockRead data_reads[] = {
9597 MockRead("HTTP/1.1 200 OK\r\n"),
9598 MockRead("Alt-Svc: "),
9599 MockRead(GetAlternateProtocolFromParam()),
bnc44858c82015-10-16 11:57:219600 MockRead("=\"www.example.com:443\";p=\"1.0\","),
bncc958faa2015-07-31 18:14:529601 MockRead("quic=\":1234\"\r\n\r\n"),
9602 MockRead("hello world"),
9603 MockRead(SYNCHRONOUS, OK),
9604 };
9605
9606 HttpRequestInfo request;
9607 request.method = "GET";
9608 request.url = GURL("http://www.example.org/");
9609 request.load_flags = 0;
9610
9611 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9612
9613 session_deps_.socket_factory->AddSocketDataProvider(&data);
9614
9615 TestCompletionCallback callback;
9616
mmenkee65e7af2015-10-13 17:16:429617 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529618 scoped_ptr<HttpTransaction> trans(
9619 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9620
9621 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9622 EXPECT_EQ(ERR_IO_PENDING, rv);
9623
9624 HostPortPair http_host_port_pair("www.example.org", 80);
9625 HttpServerProperties& http_server_properties =
9626 *session->http_server_properties();
9627 AlternativeServiceVector alternative_service_vector =
9628 http_server_properties.GetAlternativeServices(http_host_port_pair);
9629 EXPECT_TRUE(alternative_service_vector.empty());
9630
9631 EXPECT_EQ(OK, callback.WaitForResult());
9632
9633 const HttpResponseInfo* response = trans->GetResponseInfo();
9634 ASSERT_TRUE(response != NULL);
9635 ASSERT_TRUE(response->headers.get() != NULL);
9636 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9637 EXPECT_FALSE(response->was_fetched_via_spdy);
9638 EXPECT_FALSE(response->was_npn_negotiated);
9639
9640 std::string response_data;
9641 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9642 EXPECT_EQ("hello world", response_data);
9643
9644 alternative_service_vector =
9645 http_server_properties.GetAlternativeServices(http_host_port_pair);
9646 ASSERT_EQ(2u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:389647 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:529648 alternative_service_vector[0].protocol);
9649 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9650 EXPECT_EQ(443, alternative_service_vector[0].port);
9651 EXPECT_EQ(QUIC, alternative_service_vector[1].protocol);
9652 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
9653 EXPECT_EQ(1234, alternative_service_vector[1].port);
9654}
9655
bnc54ec34b72015-08-26 19:34:569656// Alternate Protocol headers must be honored even if |use_alternative_services|
9657// is false.
[email protected]23e482282013-06-14 16:08:029658TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:239659 session_deps_.next_protos = SpdyNextProtos();
bnc54ec34b72015-08-26 19:34:569660 session_deps_.use_alternative_services = false;
[email protected]a2cb8122010-03-10 17:22:429661
[email protected]8a0fc822013-06-27 20:52:439662 std::string alternate_protocol_http_header =
9663 GetAlternateProtocolHttpHeader();
9664
[email protected]564b4912010-03-09 16:30:429665 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529666 MockRead("HTTP/1.1 200 OK\r\n"),
9667 MockRead(alternate_protocol_http_header.c_str()),
9668 MockRead("\r\n"),
9669 MockRead("hello world"),
9670 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:429671 };
9672
9673 HttpRequestInfo request;
9674 request.method = "GET";
bncce36dca22015-04-21 22:11:239675 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429676 request.load_flags = 0;
9677
9678 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9679
[email protected]bb88e1d32013-05-03 23:11:079680 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:429681
[email protected]49639fa2011-12-20 23:22:419682 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429683
mmenkee65e7af2015-10-13 17:16:429684 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369685 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509686 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:429687
[email protected]49639fa2011-12-20 23:22:419688 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429689 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:539690
bncce36dca22015-04-21 22:11:239691 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:559692 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:539693 *session->http_server_properties();
bncd9b132e2015-07-08 05:16:109694 AlternativeServiceVector alternative_service_vector =
9695 http_server_properties.GetAlternativeServices(http_host_port_pair);
9696 EXPECT_TRUE(alternative_service_vector.empty());
[email protected]564b4912010-03-09 16:30:429697
9698 EXPECT_EQ(OK, callback.WaitForResult());
9699
9700 const HttpResponseInfo* response = trans->GetResponseInfo();
9701 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509702 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429703 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539704 EXPECT_FALSE(response->was_fetched_via_spdy);
9705 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:429706
9707 std::string response_data;
9708 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9709 EXPECT_EQ("hello world", response_data);
9710
bncd9b132e2015-07-08 05:16:109711 alternative_service_vector =
9712 http_server_properties.GetAlternativeServices(http_host_port_pair);
9713 ASSERT_EQ(1u, alternative_service_vector.size());
9714 EXPECT_EQ(443, alternative_service_vector[0].port);
rdsmithebb50aa2015-11-12 03:44:389715 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncd9b132e2015-07-08 05:16:109716 alternative_service_vector[0].protocol);
[email protected]564b4912010-03-09 16:30:429717}
9718
rch89c6e102015-03-18 18:56:529719TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
9720 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359721 session_deps_.use_alternative_services = true;
rch89c6e102015-03-18 18:56:529722
9723 MockRead data_reads[] = {
9724 MockRead("HTTP/1.1 200 OK\r\n"),
9725 MockRead("Alternate-Protocol: \r\n\r\n"),
9726 MockRead("hello world"),
9727 MockRead(SYNCHRONOUS, OK),
9728 };
9729
9730 HttpRequestInfo request;
9731 request.method = "GET";
bncce36dca22015-04-21 22:11:239732 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:529733 request.load_flags = 0;
9734
9735 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9736
9737 session_deps_.socket_factory->AddSocketDataProvider(&data);
9738
9739 TestCompletionCallback callback;
9740
mmenkee65e7af2015-10-13 17:16:429741 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rch89c6e102015-03-18 18:56:529742
bncce36dca22015-04-21 22:11:239743 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:529744 HttpServerProperties& http_server_properties =
9745 *session->http_server_properties();
bnccacc0992015-03-20 20:22:229746 AlternativeService alternative_service(QUIC, "", 80);
bnc7dc7e1b42015-07-28 14:43:129747 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9748 http_server_properties.SetAlternativeService(
9749 http_host_port_pair, alternative_service, 1.0, expiration);
bnccacc0992015-03-20 20:22:229750
bncd9b132e2015-07-08 05:16:109751 AlternativeServiceVector alternative_service_vector =
9752 http_server_properties.GetAlternativeServices(http_host_port_pair);
9753 ASSERT_EQ(1u, alternative_service_vector.size());
9754 EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
rch89c6e102015-03-18 18:56:529755
9756 scoped_ptr<HttpTransaction> trans(
9757 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9758
9759 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9760 EXPECT_EQ(ERR_IO_PENDING, rv);
9761
9762 EXPECT_EQ(OK, callback.WaitForResult());
9763
9764 const HttpResponseInfo* response = trans->GetResponseInfo();
9765 ASSERT_TRUE(response != NULL);
9766 ASSERT_TRUE(response->headers.get() != NULL);
9767 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9768 EXPECT_FALSE(response->was_fetched_via_spdy);
9769 EXPECT_FALSE(response->was_npn_negotiated);
9770
9771 std::string response_data;
9772 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9773 EXPECT_EQ("hello world", response_data);
9774
bncd9b132e2015-07-08 05:16:109775 alternative_service_vector =
9776 http_server_properties.GetAlternativeServices(http_host_port_pair);
9777 EXPECT_TRUE(alternative_service_vector.empty());
rch89c6e102015-03-18 18:56:529778}
9779
bncc958faa2015-07-31 18:14:529780TEST_P(HttpNetworkTransactionTest, AltSvcOverwritesAlternateProtocol) {
9781 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359782 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529783
9784 std::string alternative_service_http_header =
9785 GetAlternativeServiceHttpHeader();
9786 std::string alternate_protocol_http_header = GetAlternateProtocolHttpHeader();
9787
9788 MockRead data_reads[] = {
9789 MockRead("HTTP/1.1 200 OK\r\n"),
9790 MockRead(alternative_service_http_header.c_str()),
9791 MockRead(alternate_protocol_http_header.c_str()),
9792 MockRead("\r\n"),
9793 MockRead("hello world"),
9794 MockRead(SYNCHRONOUS, OK),
9795 };
9796
9797 HttpRequestInfo request;
9798 request.method = "GET";
9799 request.url = GURL("http://www.example.org/");
9800 request.load_flags = 0;
9801
9802 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9803
9804 session_deps_.socket_factory->AddSocketDataProvider(&data);
9805
9806 TestCompletionCallback callback;
9807
mmenkee65e7af2015-10-13 17:16:429808 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529809 scoped_ptr<HttpTransaction> trans(
9810 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9811
9812 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9813 EXPECT_EQ(ERR_IO_PENDING, rv);
9814
9815 HostPortPair http_host_port_pair("www.example.org", 80);
9816 HttpServerProperties& http_server_properties =
9817 *session->http_server_properties();
9818 AlternativeServiceVector alternative_service_vector =
9819 http_server_properties.GetAlternativeServices(http_host_port_pair);
9820 EXPECT_TRUE(alternative_service_vector.empty());
9821
9822 EXPECT_EQ(OK, callback.WaitForResult());
9823
9824 const HttpResponseInfo* response = trans->GetResponseInfo();
9825 ASSERT_TRUE(response != NULL);
9826 ASSERT_TRUE(response->headers.get() != NULL);
9827 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9828 EXPECT_FALSE(response->was_fetched_via_spdy);
9829 EXPECT_FALSE(response->was_npn_negotiated);
9830
9831 std::string response_data;
9832 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9833 EXPECT_EQ("hello world", response_data);
9834
9835 alternative_service_vector =
9836 http_server_properties.GetAlternativeServices(http_host_port_pair);
9837 ASSERT_EQ(1u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:389838 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:529839 alternative_service_vector[0].protocol);
9840 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9841 EXPECT_EQ(443, alternative_service_vector[0].port);
9842}
9843
bnc54ec34b72015-08-26 19:34:569844// When |use_alternative_services| is false, do not observe alternative service
9845// entries that point to a different host.
9846TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
9847 session_deps_.use_alternative_services = false;
9848
9849 HttpRequestInfo request;
9850 request.method = "GET";
9851 request.url = GURL("http://www.example.org/");
9852 request.load_flags = 0;
9853
9854 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9855 StaticSocketDataProvider first_data;
9856 first_data.set_connect_data(mock_connect);
9857 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
9858
9859 MockRead data_reads[] = {
9860 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
9861 MockRead(ASYNC, OK),
9862 };
9863 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
9864 nullptr, 0);
9865 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
9866
mmenkee65e7af2015-10-13 17:16:429867 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc54ec34b72015-08-26 19:34:569868
9869 base::WeakPtr<HttpServerProperties> http_server_properties =
9870 session->http_server_properties();
9871 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:389872 AlternateProtocolFromNextProto(GetProtocol()), "different.example.org",
9873 80);
bnc54ec34b72015-08-26 19:34:569874 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9875 http_server_properties->SetAlternativeService(
9876 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
9877
9878 scoped_ptr<HttpTransaction> trans(
9879 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9880 TestCompletionCallback callback;
9881
9882 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9883 // The connetion to origin was refused, and the alternative service should not
9884 // be used (even though mock data are there), therefore the request should
9885 // fail.
9886 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
9887}
9888
[email protected]23e482282013-06-14 16:08:029889TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239890 MarkBrokenAlternateProtocolAndFallback) {
bnc55ff9da2015-08-19 18:42:359891 session_deps_.use_alternative_services = true;
[email protected]564b4912010-03-09 16:30:429892
9893 HttpRequestInfo request;
9894 request.method = "GET";
bncce36dca22015-04-21 22:11:239895 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429896 request.load_flags = 0;
9897
[email protected]d973e99a2012-02-17 21:02:369898 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:429899 StaticSocketDataProvider first_data;
9900 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079901 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:429902
9903 MockRead data_reads[] = {
9904 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9905 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069906 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:429907 };
9908 StaticSocketDataProvider second_data(
9909 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079910 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:429911
mmenkee65e7af2015-10-13 17:16:429912 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:429913
[email protected]30d4c022013-07-18 22:58:169914 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539915 session->http_server_properties();
bnc8445b3002015-03-13 01:57:099916 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:119917 // Port must be < 1024, or the header will be ignored (since initial port was
9918 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:109919 const AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:389920 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bncd9b132e2015-07-08 05:16:109921 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:129922 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9923 http_server_properties->SetAlternativeService(
9924 host_port_pair, alternative_service, 1.0, expiration);
[email protected]564b4912010-03-09 16:30:429925
[email protected]262eec82013-03-19 21:01:369926 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509927 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419928 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429929
[email protected]49639fa2011-12-20 23:22:419930 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429931 EXPECT_EQ(ERR_IO_PENDING, rv);
9932 EXPECT_EQ(OK, callback.WaitForResult());
9933
9934 const HttpResponseInfo* response = trans->GetResponseInfo();
9935 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509936 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429937 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9938
9939 std::string response_data;
9940 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9941 EXPECT_EQ("hello world", response_data);
9942
bncd9b132e2015-07-08 05:16:109943 const AlternativeServiceVector alternative_service_vector =
9944 http_server_properties->GetAlternativeServices(host_port_pair);
9945 ASSERT_EQ(1u, alternative_service_vector.size());
9946 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
9947 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
9948 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:429949}
9950
bnc55ff9da2015-08-19 18:42:359951// Ensure that we are not allowed to redirect traffic via an alternate protocol
9952// to an unrestricted (port >= 1024) when the original traffic was on a
9953// restricted port (port < 1024). Ensure that we can redirect in all other
9954// cases.
[email protected]23e482282013-06-14 16:08:029955TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239956 AlternateProtocolPortRestrictedBlocked) {
bnc55ff9da2015-08-19 18:42:359957 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119958
9959 HttpRequestInfo restricted_port_request;
9960 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239961 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119962 restricted_port_request.load_flags = 0;
9963
[email protected]d973e99a2012-02-17 21:02:369964 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119965 StaticSocketDataProvider first_data;
9966 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079967 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119968
9969 MockRead data_reads[] = {
9970 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9971 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069972 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119973 };
9974 StaticSocketDataProvider second_data(
9975 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079976 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119977
mmenkee65e7af2015-10-13 17:16:429978 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119979
[email protected]30d4c022013-07-18 22:58:169980 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539981 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119982 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229983 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:389984 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:229985 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129986 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229987 http_server_properties->SetAlternativeService(
9988 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129989 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119990
[email protected]262eec82013-03-19 21:01:369991 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509992 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419993 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119994
[email protected]49639fa2011-12-20 23:22:419995 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369996 &restricted_port_request,
9997 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119998 EXPECT_EQ(ERR_IO_PENDING, rv);
9999 // Invalid change to unrestricted port should fail.
10000 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:1910001}
[email protected]3912662a32011-10-04 00:51:1110002
bnc55ff9da2015-08-19 18:42:3510003// Ensure that we are allowed to redirect traffic via an alternate protocol to
10004// an unrestricted (port >= 1024) when the original traffic was on a restricted
10005// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:0210006TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:1910007 AlternateProtocolPortRestrictedPermitted) {
bnc55ff9da2015-08-19 18:42:3510008 session_deps_.use_alternative_services = true;
[email protected]bb88e1d32013-05-03 23:11:0710009 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910010
10011 HttpRequestInfo restricted_port_request;
10012 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310013 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910014 restricted_port_request.load_flags = 0;
10015
10016 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10017 StaticSocketDataProvider first_data;
10018 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710019 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910020
10021 MockRead data_reads[] = {
10022 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10023 MockRead("hello world"),
10024 MockRead(ASYNC, OK),
10025 };
10026 StaticSocketDataProvider second_data(
10027 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710028 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:1910029
mmenkee65e7af2015-10-13 17:16:4210030 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910031
[email protected]30d4c022013-07-18 22:58:1610032 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910033 session->http_server_properties();
10034 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210035 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810036 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210037 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210038 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210039 http_server_properties->SetAlternativeService(
10040 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:1210041 1.0, expiration);
[email protected]c54c6962013-02-01 04:53:1910042
[email protected]262eec82013-03-19 21:01:3610043 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010044 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:1910045 TestCompletionCallback callback;
10046
10047 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:3610048 &restricted_port_request,
10049 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:1910050 // Change to unrestricted port should succeed.
10051 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110052}
10053
bnc55ff9da2015-08-19 18:42:3510054// Ensure that we are not allowed to redirect traffic via an alternate protocol
10055// to an unrestricted (port >= 1024) when the original traffic was on a
10056// restricted port (port < 1024). Ensure that we can redirect in all other
10057// cases.
[email protected]23e482282013-06-14 16:08:0210058TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310059 AlternateProtocolPortRestrictedAllowed) {
bnc55ff9da2015-08-19 18:42:3510060 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:1110061
10062 HttpRequestInfo restricted_port_request;
10063 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310064 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110065 restricted_port_request.load_flags = 0;
10066
[email protected]d973e99a2012-02-17 21:02:3610067 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110068 StaticSocketDataProvider first_data;
10069 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710070 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110071
10072 MockRead data_reads[] = {
10073 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10074 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610075 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110076 };
10077 StaticSocketDataProvider second_data(
10078 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710079 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110080
mmenkee65e7af2015-10-13 17:16:4210081 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110082
[email protected]30d4c022013-07-18 22:58:1610083 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310084 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110085 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210086 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810087 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210088 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210089 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210090 http_server_properties->SetAlternativeService(
10091 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:1210092 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:1110093
[email protected]262eec82013-03-19 21:01:3610094 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010095 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110096 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110097
[email protected]49639fa2011-12-20 23:22:4110098 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610099 &restricted_port_request,
10100 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110101 EXPECT_EQ(ERR_IO_PENDING, rv);
10102 // Valid change to restricted port should pass.
10103 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110104}
10105
bnc55ff9da2015-08-19 18:42:3510106// Ensure that we are not allowed to redirect traffic via an alternate protocol
10107// to an unrestricted (port >= 1024) when the original traffic was on a
10108// restricted port (port < 1024). Ensure that we can redirect in all other
10109// cases.
[email protected]23e482282013-06-14 16:08:0210110TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310111 AlternateProtocolPortUnrestrictedAllowed1) {
bnc55ff9da2015-08-19 18:42:3510112 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:1110113
10114 HttpRequestInfo unrestricted_port_request;
10115 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310116 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110117 unrestricted_port_request.load_flags = 0;
10118
[email protected]d973e99a2012-02-17 21:02:3610119 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110120 StaticSocketDataProvider first_data;
10121 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710122 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110123
10124 MockRead data_reads[] = {
10125 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10126 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610127 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110128 };
10129 StaticSocketDataProvider second_data(
10130 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710131 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110132
mmenkee65e7af2015-10-13 17:16:4210133 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110134
[email protected]30d4c022013-07-18 22:58:1610135 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310136 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110137 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210138 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810139 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210140 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210141 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210142 http_server_properties->SetAlternativeService(
10143 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:1210144 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:1110145
[email protected]262eec82013-03-19 21:01:3610146 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010147 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110148 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110149
[email protected]49639fa2011-12-20 23:22:4110150 int rv = trans->Start(
10151 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110152 EXPECT_EQ(ERR_IO_PENDING, rv);
10153 // Valid change to restricted port should pass.
10154 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110155}
10156
bnc55ff9da2015-08-19 18:42:3510157// Ensure that we are not allowed to redirect traffic via an alternate protocol
10158// to an unrestricted (port >= 1024) when the original traffic was on a
10159// restricted port (port < 1024). Ensure that we can redirect in all other
10160// cases.
[email protected]23e482282013-06-14 16:08:0210161TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310162 AlternateProtocolPortUnrestrictedAllowed2) {
bnc55ff9da2015-08-19 18:42:3510163 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:1110164
10165 HttpRequestInfo unrestricted_port_request;
10166 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310167 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110168 unrestricted_port_request.load_flags = 0;
10169
[email protected]d973e99a2012-02-17 21:02:3610170 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110171 StaticSocketDataProvider first_data;
10172 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710173 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110174
10175 MockRead data_reads[] = {
10176 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10177 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610178 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110179 };
10180 StaticSocketDataProvider second_data(
10181 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710182 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110183
mmenkee65e7af2015-10-13 17:16:4210184 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110185
[email protected]30d4c022013-07-18 22:58:1610186 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310187 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210188 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:2210189 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810190 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210191 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210192 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210193 http_server_properties->SetAlternativeService(
10194 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:1210195 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:1110196
[email protected]262eec82013-03-19 21:01:3610197 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010198 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110199 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110200
[email protected]49639fa2011-12-20 23:22:4110201 int rv = trans->Start(
10202 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110203 EXPECT_EQ(ERR_IO_PENDING, rv);
10204 // Valid change to an unrestricted port should pass.
10205 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110206}
10207
bnc55ff9da2015-08-19 18:42:3510208// Ensure that we are not allowed to redirect traffic via an alternate protocol
10209// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10210// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:2310211TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bnc55ff9da2015-08-19 18:42:3510212 session_deps_.use_alternative_services = true;
[email protected]eb6234e2012-01-19 01:50:0210213
10214 HttpRequestInfo request;
10215 request.method = "GET";
bncce36dca22015-04-21 22:11:2310216 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210217 request.load_flags = 0;
10218
10219 // The alternate protocol request will error out before we attempt to connect,
10220 // so only the standard HTTP request will try to connect.
10221 MockRead data_reads[] = {
10222 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10223 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610224 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210225 };
10226 StaticSocketDataProvider data(
10227 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710228 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210229
mmenkee65e7af2015-10-13 17:16:4210230 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210231
[email protected]30d4c022013-07-18 22:58:1610232 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210233 session->http_server_properties();
10234 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:2210235 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810236 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210237 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210238 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210239 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:1210240 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
[email protected]eb6234e2012-01-19 01:50:0210241
[email protected]262eec82013-03-19 21:01:3610242 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010243 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:0210244 TestCompletionCallback callback;
10245
10246 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10247 EXPECT_EQ(ERR_IO_PENDING, rv);
10248 // The HTTP request should succeed.
10249 EXPECT_EQ(OK, callback.WaitForResult());
10250
[email protected]eb6234e2012-01-19 01:50:0210251 const HttpResponseInfo* response = trans->GetResponseInfo();
10252 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010253 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:0210254 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10255
10256 std::string response_data;
10257 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10258 EXPECT_EQ("hello world", response_data);
10259}
10260
[email protected]23e482282013-06-14 16:08:0210261TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:3510262 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310263 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:5410264
10265 HttpRequestInfo request;
10266 request.method = "GET";
bncce36dca22015-04-21 22:11:2310267 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410268 request.load_flags = 0;
10269
[email protected]8a0fc822013-06-27 20:52:4310270 std::string alternate_protocol_http_header =
10271 GetAlternateProtocolHttpHeader();
10272
[email protected]2ff8b312010-04-26 22:20:5410273 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210274 MockRead("HTTP/1.1 200 OK\r\n"),
10275 MockRead(alternate_protocol_http_header.c_str()),
10276 MockRead("\r\n"),
10277 MockRead("hello world"),
10278 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10279 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410280
10281 StaticSocketDataProvider first_transaction(
10282 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710283 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410284
[email protected]8ddf8322012-02-23 18:08:0610285 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810286 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310287 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10288 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710289 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410290
[email protected]cdf8f7e72013-05-23 10:56:4610291 scoped_ptr<SpdyFrame> req(
10292 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310293 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410294
[email protected]23e482282013-06-14 16:08:0210295 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10296 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410297 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310298 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410299 };
10300
rch8e6c6c42015-05-01 14:05:1310301 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10302 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710303 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410304
[email protected]d973e99a2012-02-17 21:02:3610305 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510306 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10307 NULL, 0, NULL, 0);
10308 hanging_non_alternate_protocol_socket.set_connect_data(
10309 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710310 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510311 &hanging_non_alternate_protocol_socket);
10312
[email protected]49639fa2011-12-20 23:22:4110313 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410314
mmenkee65e7af2015-10-13 17:16:4210315 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610316 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010317 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410318
[email protected]49639fa2011-12-20 23:22:4110319 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410320 EXPECT_EQ(ERR_IO_PENDING, rv);
10321 EXPECT_EQ(OK, callback.WaitForResult());
10322
10323 const HttpResponseInfo* response = trans->GetResponseInfo();
10324 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010325 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410326 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10327
10328 std::string response_data;
10329 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10330 EXPECT_EQ("hello world", response_data);
10331
[email protected]90499482013-06-01 00:39:5010332 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410333
[email protected]49639fa2011-12-20 23:22:4110334 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410335 EXPECT_EQ(ERR_IO_PENDING, rv);
10336 EXPECT_EQ(OK, callback.WaitForResult());
10337
10338 response = trans->GetResponseInfo();
10339 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010340 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0210341 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310342 EXPECT_TRUE(response->was_fetched_via_spdy);
10343 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410344
10345 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10346 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410347}
10348
[email protected]23e482282013-06-14 16:08:0210349TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
bnc55ff9da2015-08-19 18:42:3510350 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310351 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:5510352
10353 HttpRequestInfo request;
10354 request.method = "GET";
bncce36dca22015-04-21 22:11:2310355 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510356 request.load_flags = 0;
10357
[email protected]8a0fc822013-06-27 20:52:4310358 std::string alternate_protocol_http_header =
10359 GetAlternateProtocolHttpHeader();
10360
[email protected]2d6728692011-03-12 01:39:5510361 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210362 MockRead("HTTP/1.1 200 OK\r\n"),
10363 MockRead(alternate_protocol_http_header.c_str()),
10364 MockRead("\r\n"),
10365 MockRead("hello world"),
10366 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10367 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510368 };
10369
10370 StaticSocketDataProvider first_transaction(
10371 data_reads, arraysize(data_reads), NULL, 0);
10372 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:0710373 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510374
[email protected]d973e99a2012-02-17 21:02:3610375 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510376 StaticSocketDataProvider hanging_socket(
10377 NULL, 0, NULL, 0);
10378 hanging_socket.set_connect_data(never_finishing_connect);
10379 // Socket 2 and 3 are the hanging Alternate-Protocol and
10380 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:0710381 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
10382 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:5510383
[email protected]8ddf8322012-02-23 18:08:0610384 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810385 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310386 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10387 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710388 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510389
[email protected]cdf8f7e72013-05-23 10:56:4610390 scoped_ptr<SpdyFrame> req1(
10391 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
10392 scoped_ptr<SpdyFrame> req2(
10393 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:5510394 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310395 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:5510396 };
[email protected]23e482282013-06-14 16:08:0210397 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10398 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
10399 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10400 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510401 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310402 CreateMockRead(*resp1, 2),
10403 CreateMockRead(*data1, 3),
10404 CreateMockRead(*resp2, 4),
10405 CreateMockRead(*data2, 5),
10406 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510407 };
10408
rch8e6c6c42015-05-01 14:05:1310409 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10410 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:5510411 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:0710412 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510413
10414 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:0710415 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:5510416
mmenkee65e7af2015-10-13 17:16:4210417 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110418 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010419 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510420
[email protected]49639fa2011-12-20 23:22:4110421 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510422 EXPECT_EQ(ERR_IO_PENDING, rv);
10423 EXPECT_EQ(OK, callback1.WaitForResult());
10424
10425 const HttpResponseInfo* response = trans1.GetResponseInfo();
10426 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010427 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510428 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10429
10430 std::string response_data;
10431 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10432 EXPECT_EQ("hello world", response_data);
10433
[email protected]49639fa2011-12-20 23:22:4110434 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5010435 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110436 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510437 EXPECT_EQ(ERR_IO_PENDING, rv);
10438
[email protected]49639fa2011-12-20 23:22:4110439 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5010440 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110441 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510442 EXPECT_EQ(ERR_IO_PENDING, rv);
10443
10444 EXPECT_EQ(OK, callback2.WaitForResult());
10445 EXPECT_EQ(OK, callback3.WaitForResult());
10446
10447 response = trans2.GetResponseInfo();
10448 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010449 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0210450 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5510451 EXPECT_TRUE(response->was_fetched_via_spdy);
10452 EXPECT_TRUE(response->was_npn_negotiated);
10453 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10454 EXPECT_EQ("hello!", response_data);
10455
10456 response = trans3.GetResponseInfo();
10457 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010458 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0210459 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5510460 EXPECT_TRUE(response->was_fetched_via_spdy);
10461 EXPECT_TRUE(response->was_npn_negotiated);
10462 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
10463 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5510464}
10465
[email protected]23e482282013-06-14 16:08:0210466TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:3510467 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310468 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:5510469
10470 HttpRequestInfo request;
10471 request.method = "GET";
bncce36dca22015-04-21 22:11:2310472 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510473 request.load_flags = 0;
10474
[email protected]8a0fc822013-06-27 20:52:4310475 std::string alternate_protocol_http_header =
10476 GetAlternateProtocolHttpHeader();
10477
[email protected]2d6728692011-03-12 01:39:5510478 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210479 MockRead("HTTP/1.1 200 OK\r\n"),
10480 MockRead(alternate_protocol_http_header.c_str()),
10481 MockRead("\r\n"),
10482 MockRead("hello world"),
10483 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10484 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510485 };
10486
10487 StaticSocketDataProvider first_transaction(
10488 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710489 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510490
[email protected]8ddf8322012-02-23 18:08:0610491 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810492 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0710493 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510494
[email protected]d973e99a2012-02-17 21:02:3610495 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510496 StaticSocketDataProvider hanging_alternate_protocol_socket(
10497 NULL, 0, NULL, 0);
10498 hanging_alternate_protocol_socket.set_connect_data(
10499 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710500 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510501 &hanging_alternate_protocol_socket);
10502
10503 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:0710504 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510505
[email protected]49639fa2011-12-20 23:22:4110506 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5510507
mmenkee65e7af2015-10-13 17:16:4210508 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610509 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010510 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510511
[email protected]49639fa2011-12-20 23:22:4110512 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510513 EXPECT_EQ(ERR_IO_PENDING, rv);
10514 EXPECT_EQ(OK, callback.WaitForResult());
10515
10516 const HttpResponseInfo* response = trans->GetResponseInfo();
10517 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010518 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510519 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10520
10521 std::string response_data;
10522 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10523 EXPECT_EQ("hello world", response_data);
10524
[email protected]90499482013-06-01 00:39:5010525 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510526
[email protected]49639fa2011-12-20 23:22:4110527 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510528 EXPECT_EQ(ERR_IO_PENDING, rv);
10529 EXPECT_EQ(OK, callback.WaitForResult());
10530
10531 response = trans->GetResponseInfo();
10532 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010533 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510534 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10535 EXPECT_FALSE(response->was_fetched_via_spdy);
10536 EXPECT_FALSE(response->was_npn_negotiated);
10537
10538 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10539 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5510540}
10541
[email protected]631f1322010-04-30 17:59:1110542class CapturingProxyResolver : public ProxyResolver {
10543 public:
sammce90c9212015-05-27 23:43:3510544 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2010545 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1110546
dchengb03027d2014-10-21 12:00:2010547 int GetProxyForURL(const GURL& url,
10548 ProxyInfo* results,
10549 const CompletionCallback& callback,
10550 RequestHandle* request,
10551 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4010552 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
10553 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4210554 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1110555 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4210556 return OK;
[email protected]631f1322010-04-30 17:59:1110557 }
10558
dchengb03027d2014-10-21 12:00:2010559 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:1110560
dchengb03027d2014-10-21 12:00:2010561 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:1710562 NOTREACHED();
10563 return LOAD_STATE_IDLE;
10564 }
10565
[email protected]24476402010-07-20 20:55:1710566 const std::vector<GURL>& resolved() const { return resolved_; }
10567
10568 private:
[email protected]631f1322010-04-30 17:59:1110569 std::vector<GURL> resolved_;
10570
10571 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
10572};
10573
sammce64b2362015-04-29 03:50:2310574class CapturingProxyResolverFactory : public ProxyResolverFactory {
10575 public:
10576 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
10577 : ProxyResolverFactory(false), resolver_(resolver) {}
10578
10579 int CreateProxyResolver(
10580 const scoped_refptr<ProxyResolverScriptData>& pac_script,
10581 scoped_ptr<ProxyResolver>* resolver,
10582 const net::CompletionCallback& callback,
10583 scoped_ptr<Request>* request) override {
10584 resolver->reset(new ForwardingProxyResolver(resolver_));
10585 return OK;
10586 }
10587
10588 private:
10589 ProxyResolver* resolver_;
10590};
10591
[email protected]23e482282013-06-14 16:08:0210592TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310593 UseAlternateProtocolForTunneledNpnSpdy) {
bnc55ff9da2015-08-19 18:42:3510594 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310595 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:1110596
10597 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4210598 proxy_config.set_auto_detect(true);
10599 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1110600
sammc5dd160c2015-04-02 02:43:1310601 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710602 session_deps_.proxy_service.reset(new ProxyService(
csharrisonb7e3a082015-09-22 19:13:0410603 make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)),
sammc5dd160c2015-04-02 02:43:1310604 make_scoped_ptr(
sammce64b2362015-04-29 03:50:2310605 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:3810606 NULL));
vishal.b62985ca92015-04-17 08:45:5110607 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710608 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1110609
10610 HttpRequestInfo request;
10611 request.method = "GET";
bncce36dca22015-04-21 22:11:2310612 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:1110613 request.load_flags = 0;
10614
[email protected]8a0fc822013-06-27 20:52:4310615 std::string alternate_protocol_http_header =
10616 GetAlternateProtocolHttpHeader();
10617
[email protected]631f1322010-04-30 17:59:1110618 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210619 MockRead("HTTP/1.1 200 OK\r\n"),
10620 MockRead(alternate_protocol_http_header.c_str()),
10621 MockRead("\r\n"),
10622 MockRead("hello world"),
10623 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10624 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1110625 };
10626
10627 StaticSocketDataProvider first_transaction(
10628 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710629 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:1110630
[email protected]8ddf8322012-02-23 18:08:0610631 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810632 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310633 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10634 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710635 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:1110636
[email protected]cdf8f7e72013-05-23 10:56:4610637 scoped_ptr<SpdyFrame> req(
10638 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:1110639 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310640 MockWrite(ASYNC, 0,
10641 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1710642 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1310643 "Proxy-Connection: keep-alive\r\n\r\n"),
10644 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:1110645 };
10646
[email protected]d911f1b2010-05-05 22:39:4210647 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10648
[email protected]23e482282013-06-14 16:08:0210649 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10650 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1110651 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310652 MockRead(ASYNC, 1, kCONNECTResponse),
10653 CreateMockRead(*resp.get(), 3),
10654 CreateMockRead(*data.get(), 4),
10655 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1110656 };
10657
rch8e6c6c42015-05-01 14:05:1310658 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10659 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710660 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1110661
[email protected]d973e99a2012-02-17 21:02:3610662 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510663 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10664 NULL, 0, NULL, 0);
10665 hanging_non_alternate_protocol_socket.set_connect_data(
10666 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710667 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510668 &hanging_non_alternate_protocol_socket);
10669
[email protected]49639fa2011-12-20 23:22:4110670 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1110671
mmenkee65e7af2015-10-13 17:16:4210672 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610673 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010674 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110675
[email protected]49639fa2011-12-20 23:22:4110676 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110677 EXPECT_EQ(ERR_IO_PENDING, rv);
10678 EXPECT_EQ(OK, callback.WaitForResult());
10679
10680 const HttpResponseInfo* response = trans->GetResponseInfo();
10681 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010682 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110683 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310684 EXPECT_FALSE(response->was_fetched_via_spdy);
10685 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110686
10687 std::string response_data;
10688 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10689 EXPECT_EQ("hello world", response_data);
10690
[email protected]90499482013-06-01 00:39:5010691 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110692
[email protected]49639fa2011-12-20 23:22:4110693 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110694 EXPECT_EQ(ERR_IO_PENDING, rv);
10695 EXPECT_EQ(OK, callback.WaitForResult());
10696
10697 response = trans->GetResponseInfo();
10698 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010699 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0210700 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310701 EXPECT_TRUE(response->was_fetched_via_spdy);
10702 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110703
10704 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10705 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1310706 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2310707 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310708 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2310709 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310710 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1110711
[email protected]029c83b62013-01-24 05:28:2010712 LoadTimingInfo load_timing_info;
10713 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10714 TestLoadTimingNotReusedWithPac(load_timing_info,
10715 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1110716}
[email protected]631f1322010-04-30 17:59:1110717
[email protected]23e482282013-06-14 16:08:0210718TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:5410719 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
bnc55ff9da2015-08-19 18:42:3510720 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310721 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:5410722
10723 HttpRequestInfo request;
10724 request.method = "GET";
bncce36dca22015-04-21 22:11:2310725 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410726 request.load_flags = 0;
10727
[email protected]8a0fc822013-06-27 20:52:4310728 std::string alternate_protocol_http_header =
10729 GetAlternateProtocolHttpHeader();
10730
[email protected]2ff8b312010-04-26 22:20:5410731 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210732 MockRead("HTTP/1.1 200 OK\r\n"),
10733 MockRead(alternate_protocol_http_header.c_str()),
10734 MockRead("\r\n"),
10735 MockRead("hello world"),
10736 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5410737 };
10738
10739 StaticSocketDataProvider first_transaction(
10740 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710741 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410742
[email protected]8ddf8322012-02-23 18:08:0610743 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810744 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310745 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10746 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710747 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410748
[email protected]cdf8f7e72013-05-23 10:56:4610749 scoped_ptr<SpdyFrame> req(
10750 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310751 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410752
[email protected]23e482282013-06-14 16:08:0210753 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10754 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410755 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310756 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410757 };
10758
rch8e6c6c42015-05-01 14:05:1310759 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10760 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710761 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410762
[email protected]83039bb2011-12-09 18:43:5510763 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410764
mmenkee65e7af2015-10-13 17:16:4210765 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5410766
[email protected]262eec82013-03-19 21:01:3610767 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010768 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410769
[email protected]49639fa2011-12-20 23:22:4110770 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410771 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110772 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410773
10774 const HttpResponseInfo* response = trans->GetResponseInfo();
10775 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010776 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410777 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10778
10779 std::string response_data;
10780 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10781 EXPECT_EQ("hello world", response_data);
10782
10783 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310784 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010785 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310786 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710787 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4210788 CreateSecureSpdySession(session.get(), key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3810789
[email protected]90499482013-06-01 00:39:5010790 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410791
[email protected]49639fa2011-12-20 23:22:4110792 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410793 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110794 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410795
10796 response = trans->GetResponseInfo();
10797 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010798 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0210799 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310800 EXPECT_TRUE(response->was_fetched_via_spdy);
10801 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410802
10803 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10804 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4210805}
10806
[email protected]044de0642010-06-17 10:42:1510807// GenerateAuthToken is a mighty big test.
10808// It tests all permutation of GenerateAuthToken behavior:
10809// - Synchronous and Asynchronous completion.
10810// - OK or error on completion.
10811// - Direct connection, non-authenticating proxy, and authenticating proxy.
10812// - HTTP or HTTPS backend (to include proxy tunneling).
10813// - Non-authenticating and authenticating backend.
10814//
[email protected]fe3b7dc2012-02-03 19:52:0910815// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1510816// problems generating an auth token for an authenticating proxy, we don't
10817// need to test all permutations of the backend server).
10818//
10819// The test proceeds by going over each of the configuration cases, and
10820// potentially running up to three rounds in each of the tests. The TestConfig
10821// specifies both the configuration for the test as well as the expectations
10822// for the results.
[email protected]23e482282013-06-14 16:08:0210823TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5010824 static const char kServer[] = "http://www.example.com";
10825 static const char kSecureServer[] = "https://www.example.com";
10826 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1510827 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
10828
10829 enum AuthTiming {
10830 AUTH_NONE,
10831 AUTH_SYNC,
10832 AUTH_ASYNC,
10833 };
10834
10835 const MockWrite kGet(
10836 "GET / HTTP/1.1\r\n"
10837 "Host: www.example.com\r\n"
10838 "Connection: keep-alive\r\n\r\n");
10839 const MockWrite kGetProxy(
10840 "GET http://www.example.com/ HTTP/1.1\r\n"
10841 "Host: www.example.com\r\n"
10842 "Proxy-Connection: keep-alive\r\n\r\n");
10843 const MockWrite kGetAuth(
10844 "GET / HTTP/1.1\r\n"
10845 "Host: www.example.com\r\n"
10846 "Connection: keep-alive\r\n"
10847 "Authorization: auth_token\r\n\r\n");
10848 const MockWrite kGetProxyAuth(
10849 "GET http://www.example.com/ HTTP/1.1\r\n"
10850 "Host: www.example.com\r\n"
10851 "Proxy-Connection: keep-alive\r\n"
10852 "Proxy-Authorization: auth_token\r\n\r\n");
10853 const MockWrite kGetAuthThroughProxy(
10854 "GET http://www.example.com/ HTTP/1.1\r\n"
10855 "Host: www.example.com\r\n"
10856 "Proxy-Connection: keep-alive\r\n"
10857 "Authorization: auth_token\r\n\r\n");
10858 const MockWrite kGetAuthWithProxyAuth(
10859 "GET http://www.example.com/ HTTP/1.1\r\n"
10860 "Host: www.example.com\r\n"
10861 "Proxy-Connection: keep-alive\r\n"
10862 "Proxy-Authorization: auth_token\r\n"
10863 "Authorization: auth_token\r\n\r\n");
10864 const MockWrite kConnect(
10865 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1710866 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1510867 "Proxy-Connection: keep-alive\r\n\r\n");
10868 const MockWrite kConnectProxyAuth(
10869 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1710870 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1510871 "Proxy-Connection: keep-alive\r\n"
10872 "Proxy-Authorization: auth_token\r\n\r\n");
10873
10874 const MockRead kSuccess(
10875 "HTTP/1.1 200 OK\r\n"
10876 "Content-Type: text/html; charset=iso-8859-1\r\n"
10877 "Content-Length: 3\r\n\r\n"
10878 "Yes");
10879 const MockRead kFailure(
10880 "Should not be called.");
10881 const MockRead kServerChallenge(
10882 "HTTP/1.1 401 Unauthorized\r\n"
10883 "WWW-Authenticate: Mock realm=server\r\n"
10884 "Content-Type: text/html; charset=iso-8859-1\r\n"
10885 "Content-Length: 14\r\n\r\n"
10886 "Unauthorized\r\n");
10887 const MockRead kProxyChallenge(
10888 "HTTP/1.1 407 Unauthorized\r\n"
10889 "Proxy-Authenticate: Mock realm=proxy\r\n"
10890 "Proxy-Connection: close\r\n"
10891 "Content-Type: text/html; charset=iso-8859-1\r\n"
10892 "Content-Length: 14\r\n\r\n"
10893 "Unauthorized\r\n");
10894 const MockRead kProxyConnected(
10895 "HTTP/1.1 200 Connection Established\r\n\r\n");
10896
10897 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
10898 // no constructors, but the C++ compiler on Windows warns about
10899 // unspecified data in compound literals. So, moved to using constructors,
10900 // and TestRound's created with the default constructor should not be used.
10901 struct TestRound {
10902 TestRound()
10903 : expected_rv(ERR_UNEXPECTED),
10904 extra_write(NULL),
10905 extra_read(NULL) {
10906 }
10907 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10908 int expected_rv_arg)
10909 : write(write_arg),
10910 read(read_arg),
10911 expected_rv(expected_rv_arg),
10912 extra_write(NULL),
10913 extra_read(NULL) {
10914 }
10915 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10916 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0110917 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1510918 : write(write_arg),
10919 read(read_arg),
10920 expected_rv(expected_rv_arg),
10921 extra_write(extra_write_arg),
10922 extra_read(extra_read_arg) {
10923 }
10924 MockWrite write;
10925 MockRead read;
10926 int expected_rv;
10927 const MockWrite* extra_write;
10928 const MockRead* extra_read;
10929 };
10930
10931 static const int kNoSSL = 500;
10932
10933 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5110934 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1510935 AuthTiming proxy_auth_timing;
10936 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5110937 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1510938 AuthTiming server_auth_timing;
10939 int server_auth_rv;
10940 int num_auth_rounds;
10941 int first_ssl_round;
10942 TestRound rounds[3];
10943 } test_configs[] = {
10944 // Non-authenticating HTTP server with a direct connection.
10945 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10946 { TestRound(kGet, kSuccess, OK)}},
10947 // Authenticating HTTP server with a direct connection.
10948 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10949 { TestRound(kGet, kServerChallenge, OK),
10950 TestRound(kGetAuth, kSuccess, OK)}},
10951 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10952 { TestRound(kGet, kServerChallenge, OK),
10953 TestRound(kGetAuth, kFailure, kAuthErr)}},
10954 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10955 { TestRound(kGet, kServerChallenge, OK),
10956 TestRound(kGetAuth, kSuccess, OK)}},
10957 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10958 { TestRound(kGet, kServerChallenge, OK),
10959 TestRound(kGetAuth, kFailure, kAuthErr)}},
10960 // Non-authenticating HTTP server through a non-authenticating proxy.
10961 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10962 { TestRound(kGetProxy, kSuccess, OK)}},
10963 // Authenticating HTTP server through a non-authenticating proxy.
10964 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10965 { TestRound(kGetProxy, kServerChallenge, OK),
10966 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10967 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10968 { TestRound(kGetProxy, kServerChallenge, OK),
10969 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10970 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10971 { TestRound(kGetProxy, kServerChallenge, OK),
10972 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10973 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10974 { TestRound(kGetProxy, kServerChallenge, OK),
10975 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10976 // Non-authenticating HTTP server through an authenticating proxy.
10977 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10978 { TestRound(kGetProxy, kProxyChallenge, OK),
10979 TestRound(kGetProxyAuth, kSuccess, OK)}},
10980 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10981 { TestRound(kGetProxy, kProxyChallenge, OK),
10982 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10983 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10984 { TestRound(kGetProxy, kProxyChallenge, OK),
10985 TestRound(kGetProxyAuth, kSuccess, OK)}},
10986 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10987 { TestRound(kGetProxy, kProxyChallenge, OK),
10988 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10989 // Authenticating HTTP server through an authenticating proxy.
10990 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10991 { TestRound(kGetProxy, kProxyChallenge, OK),
10992 TestRound(kGetProxyAuth, kServerChallenge, OK),
10993 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10994 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10995 { TestRound(kGetProxy, kProxyChallenge, OK),
10996 TestRound(kGetProxyAuth, kServerChallenge, OK),
10997 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10998 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10999 { TestRound(kGetProxy, kProxyChallenge, OK),
11000 TestRound(kGetProxyAuth, kServerChallenge, OK),
11001 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11002 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11003 { TestRound(kGetProxy, kProxyChallenge, OK),
11004 TestRound(kGetProxyAuth, kServerChallenge, OK),
11005 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11006 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11007 { TestRound(kGetProxy, kProxyChallenge, OK),
11008 TestRound(kGetProxyAuth, kServerChallenge, OK),
11009 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11010 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11011 { TestRound(kGetProxy, kProxyChallenge, OK),
11012 TestRound(kGetProxyAuth, kServerChallenge, OK),
11013 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11014 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11015 { TestRound(kGetProxy, kProxyChallenge, OK),
11016 TestRound(kGetProxyAuth, kServerChallenge, OK),
11017 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11018 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11019 { TestRound(kGetProxy, kProxyChallenge, OK),
11020 TestRound(kGetProxyAuth, kServerChallenge, OK),
11021 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11022 // Non-authenticating HTTPS server with a direct connection.
11023 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11024 { TestRound(kGet, kSuccess, OK)}},
11025 // Authenticating HTTPS server with a direct connection.
11026 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11027 { TestRound(kGet, kServerChallenge, OK),
11028 TestRound(kGetAuth, kSuccess, OK)}},
11029 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11030 { TestRound(kGet, kServerChallenge, OK),
11031 TestRound(kGetAuth, kFailure, kAuthErr)}},
11032 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11033 { TestRound(kGet, kServerChallenge, OK),
11034 TestRound(kGetAuth, kSuccess, OK)}},
11035 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11036 { TestRound(kGet, kServerChallenge, OK),
11037 TestRound(kGetAuth, kFailure, kAuthErr)}},
11038 // Non-authenticating HTTPS server with a non-authenticating proxy.
11039 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11040 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11041 // Authenticating HTTPS server through a non-authenticating proxy.
11042 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11043 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11044 TestRound(kGetAuth, kSuccess, OK)}},
11045 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11046 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11047 TestRound(kGetAuth, kFailure, kAuthErr)}},
11048 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11049 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11050 TestRound(kGetAuth, kSuccess, OK)}},
11051 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11052 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11053 TestRound(kGetAuth, kFailure, kAuthErr)}},
11054 // Non-Authenticating HTTPS server through an authenticating proxy.
11055 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11056 { TestRound(kConnect, kProxyChallenge, OK),
11057 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11058 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11059 { TestRound(kConnect, kProxyChallenge, OK),
11060 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11061 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11062 { TestRound(kConnect, kProxyChallenge, OK),
11063 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11064 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11065 { TestRound(kConnect, kProxyChallenge, OK),
11066 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11067 // Authenticating HTTPS server through an authenticating proxy.
11068 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11069 { TestRound(kConnect, kProxyChallenge, OK),
11070 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11071 &kGet, &kServerChallenge),
11072 TestRound(kGetAuth, kSuccess, OK)}},
11073 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11074 { TestRound(kConnect, kProxyChallenge, OK),
11075 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11076 &kGet, &kServerChallenge),
11077 TestRound(kGetAuth, kFailure, kAuthErr)}},
11078 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11079 { TestRound(kConnect, kProxyChallenge, OK),
11080 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11081 &kGet, &kServerChallenge),
11082 TestRound(kGetAuth, kSuccess, OK)}},
11083 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11084 { TestRound(kConnect, kProxyChallenge, OK),
11085 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11086 &kGet, &kServerChallenge),
11087 TestRound(kGetAuth, kFailure, kAuthErr)}},
11088 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11089 { TestRound(kConnect, kProxyChallenge, OK),
11090 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11091 &kGet, &kServerChallenge),
11092 TestRound(kGetAuth, kSuccess, OK)}},
11093 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11094 { TestRound(kConnect, kProxyChallenge, OK),
11095 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11096 &kGet, &kServerChallenge),
11097 TestRound(kGetAuth, kFailure, kAuthErr)}},
11098 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11099 { TestRound(kConnect, kProxyChallenge, OK),
11100 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11101 &kGet, &kServerChallenge),
11102 TestRound(kGetAuth, kSuccess, OK)}},
11103 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11104 { TestRound(kConnect, kProxyChallenge, OK),
11105 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11106 &kGet, &kServerChallenge),
11107 TestRound(kGetAuth, kFailure, kAuthErr)}},
11108 };
11109
viettrungluue4a8b882014-10-16 06:17:3811110 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0811111 HttpAuthHandlerMock::Factory* auth_factory(
11112 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711113 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1511114 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2611115
11116 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1511117 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0811118 for (int n = 0; n < 2; n++) {
11119 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11120 std::string auth_challenge = "Mock realm=proxy";
11121 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2411122 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11123 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0811124 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
11125 origin, BoundNetLog());
11126 auth_handler->SetGenerateExpectation(
11127 test_config.proxy_auth_timing == AUTH_ASYNC,
11128 test_config.proxy_auth_rv);
11129 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11130 }
[email protected]044de0642010-06-17 10:42:1511131 }
11132 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0011133 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1511134 std::string auth_challenge = "Mock realm=server";
11135 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2411136 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11137 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1511138 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
11139 origin, BoundNetLog());
11140 auth_handler->SetGenerateExpectation(
11141 test_config.server_auth_timing == AUTH_ASYNC,
11142 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0811143 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1511144 }
11145 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0311146 session_deps_.proxy_service =
11147 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1511148 } else {
rdsmith82957ad2015-09-16 19:42:0311149 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1511150 }
11151
11152 HttpRequestInfo request;
11153 request.method = "GET";
11154 request.url = GURL(test_config.server_url);
11155 request.load_flags = 0;
11156
mmenkee65e7af2015-10-13 17:16:4211157 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4111158 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1511159
rchcb68dc62015-05-21 04:45:3611160 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
11161
11162 std::vector<std::vector<MockRead>> mock_reads(1);
11163 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1511164 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11165 const TestRound& read_write_round = test_config.rounds[round];
11166
11167 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3611168 mock_reads.back().push_back(read_write_round.read);
11169 mock_writes.back().push_back(read_write_round.write);
11170
11171 // kProxyChallenge uses Proxy-Connection: close which means that the
11172 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5411173 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3611174 mock_reads.push_back(std::vector<MockRead>());
11175 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1511176 }
11177
rchcb68dc62015-05-21 04:45:3611178 if (read_write_round.extra_read) {
11179 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1511180 }
rchcb68dc62015-05-21 04:45:3611181 if (read_write_round.extra_write) {
11182 mock_writes.back().push_back(*read_write_round.extra_write);
11183 }
[email protected]044de0642010-06-17 10:42:1511184
11185 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1511186 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0711187 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1511188 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3611189 }
[email protected]044de0642010-06-17 10:42:1511190
rchcb68dc62015-05-21 04:45:3611191 ScopedVector<StaticSocketDataProvider> data_providers;
11192 for (size_t i = 0; i < mock_reads.size(); ++i) {
11193 data_providers.push_back(new StaticSocketDataProvider(
davidben5f8b6bc2015-11-25 03:19:5411194 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
11195 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3611196 session_deps_.socket_factory->AddSocketDataProvider(
11197 data_providers.back());
11198 }
11199
11200 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11201 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1511202 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4111203 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1511204 int rv;
11205 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4111206 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511207 } else {
[email protected]49639fa2011-12-20 23:22:4111208 rv = trans.RestartWithAuth(
11209 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1511210 }
11211 if (rv == ERR_IO_PENDING)
11212 rv = callback.WaitForResult();
11213
11214 // Compare results with expected data.
11215 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5011216 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5511217 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1511218 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
11219 continue;
11220 }
11221 if (round + 1 < test_config.num_auth_rounds) {
11222 EXPECT_FALSE(response->auth_challenge.get() == NULL);
11223 } else {
11224 EXPECT_TRUE(response->auth_challenge.get() == NULL);
11225 }
11226 }
[email protected]e5ae96a2010-04-14 20:12:4511227 }
11228}
11229
[email protected]23e482282013-06-14 16:08:0211230TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1411231 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1411232 HttpAuthHandlerMock::Factory* auth_factory(
11233 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711234 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0311235 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0711236 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
11237 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1411238
11239 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11240 auth_handler->set_connection_based(true);
11241 std::string auth_challenge = "Mock realm=server";
11242 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2411243 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11244 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1411245 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
11246 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811247 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1411248
[email protected]c871bce92010-07-15 21:51:1411249 int rv = OK;
11250 const HttpResponseInfo* response = NULL;
11251 HttpRequestInfo request;
11252 request.method = "GET";
11253 request.url = origin;
11254 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2711255
mmenkee65e7af2015-10-13 17:16:4211256 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1011257
11258 // Use a TCP Socket Pool with only one connection per group. This is used
11259 // to validate that the TCP socket is not released to the pool between
11260 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4211261 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2811262 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1011263 50, // Max sockets for pool
11264 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0711265 session_deps_.host_resolver.get(),
11266 session_deps_.socket_factory.get(),
11267 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4411268 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
11269 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0211270 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5111271 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1011272
[email protected]262eec82013-03-19 21:01:3611273 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011274 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111275 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1411276
11277 const MockWrite kGet(
11278 "GET / HTTP/1.1\r\n"
11279 "Host: www.example.com\r\n"
11280 "Connection: keep-alive\r\n\r\n");
11281 const MockWrite kGetAuth(
11282 "GET / HTTP/1.1\r\n"
11283 "Host: www.example.com\r\n"
11284 "Connection: keep-alive\r\n"
11285 "Authorization: auth_token\r\n\r\n");
11286
11287 const MockRead kServerChallenge(
11288 "HTTP/1.1 401 Unauthorized\r\n"
11289 "WWW-Authenticate: Mock realm=server\r\n"
11290 "Content-Type: text/html; charset=iso-8859-1\r\n"
11291 "Content-Length: 14\r\n\r\n"
11292 "Unauthorized\r\n");
11293 const MockRead kSuccess(
11294 "HTTP/1.1 200 OK\r\n"
11295 "Content-Type: text/html; charset=iso-8859-1\r\n"
11296 "Content-Length: 3\r\n\r\n"
11297 "Yes");
11298
11299 MockWrite writes[] = {
11300 // First round
11301 kGet,
11302 // Second round
11303 kGetAuth,
11304 // Third round
11305 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3011306 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1011307 kGetAuth,
11308 // Competing request
11309 kGet,
[email protected]c871bce92010-07-15 21:51:1411310 };
11311 MockRead reads[] = {
11312 // First round
11313 kServerChallenge,
11314 // Second round
11315 kServerChallenge,
11316 // Third round
[email protected]eca50e122010-09-11 14:03:3011317 kServerChallenge,
11318 // Fourth round
[email protected]c871bce92010-07-15 21:51:1411319 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1011320 // Competing response
11321 kSuccess,
[email protected]c871bce92010-07-15 21:51:1411322 };
11323 StaticSocketDataProvider data_provider(reads, arraysize(reads),
11324 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0711325 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1411326
thestig9d3bb0c2015-01-24 00:49:5111327 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1011328
11329 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1411330 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111331 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1411332 if (rv == ERR_IO_PENDING)
11333 rv = callback.WaitForResult();
11334 EXPECT_EQ(OK, rv);
11335 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011336 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1411337 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811338 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411339
[email protected]7ef4cbbb2011-02-06 11:19:1011340 // In between rounds, another request comes in for the same domain.
11341 // It should not be able to grab the TCP socket that trans has already
11342 // claimed.
11343 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5011344 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111345 TestCompletionCallback callback_compete;
11346 rv = trans_compete->Start(
11347 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1011348 EXPECT_EQ(ERR_IO_PENDING, rv);
11349 // callback_compete.WaitForResult at this point would stall forever,
11350 // since the HttpNetworkTransaction does not release the request back to
11351 // the pool until after authentication completes.
11352
11353 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1411354 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111355 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411356 if (rv == ERR_IO_PENDING)
11357 rv = callback.WaitForResult();
11358 EXPECT_EQ(OK, rv);
11359 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011360 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1411361 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811362 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411363
[email protected]7ef4cbbb2011-02-06 11:19:1011364 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1411365 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111366 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411367 if (rv == ERR_IO_PENDING)
11368 rv = callback.WaitForResult();
11369 EXPECT_EQ(OK, rv);
11370 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011371 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1411372 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811373 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3011374
[email protected]7ef4cbbb2011-02-06 11:19:1011375 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3011376 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111377 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3011378 if (rv == ERR_IO_PENDING)
11379 rv = callback.WaitForResult();
11380 EXPECT_EQ(OK, rv);
11381 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011382 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3011383 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811384 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011385
11386 // Read the body since the fourth round was successful. This will also
11387 // release the socket back to the pool.
11388 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5011389 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011390 if (rv == ERR_IO_PENDING)
11391 rv = callback.WaitForResult();
11392 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011393 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011394 EXPECT_EQ(0, rv);
11395 // There are still 0 idle sockets, since the trans_compete transaction
11396 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2811397 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011398
11399 // The competing request can now finish. Wait for the headers and then
11400 // read the body.
11401 rv = callback_compete.WaitForResult();
11402 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5011403 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011404 if (rv == ERR_IO_PENDING)
11405 rv = callback.WaitForResult();
11406 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011407 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011408 EXPECT_EQ(0, rv);
11409
11410 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2811411 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411412}
11413
[email protected]65041fa2010-05-21 06:56:5311414// This tests the case that a request is issued via http instead of spdy after
11415// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0211416TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bnc55ff9da2015-08-19 18:42:3511417 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311418 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1611419 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2311420 session_deps_.next_protos = next_protos;
11421
[email protected]65041fa2010-05-21 06:56:5311422 HttpRequestInfo request;
11423 request.method = "GET";
bncce36dca22015-04-21 22:11:2311424 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5311425 request.load_flags = 0;
11426
11427 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2311428 MockWrite(
11429 "GET / HTTP/1.1\r\n"
11430 "Host: www.example.org\r\n"
11431 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5311432 };
11433
[email protected]8a0fc822013-06-27 20:52:4311434 std::string alternate_protocol_http_header =
11435 GetAlternateProtocolHttpHeader();
11436
[email protected]65041fa2010-05-21 06:56:5311437 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211438 MockRead("HTTP/1.1 200 OK\r\n"),
11439 MockRead(alternate_protocol_http_header.c_str()),
11440 MockRead("\r\n"),
11441 MockRead("hello world"),
11442 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5311443 };
11444
[email protected]8ddf8322012-02-23 18:08:0611445 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4811446 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5311447
[email protected]bb88e1d32013-05-03 23:11:0711448 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5311449
11450 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11451 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711452 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5311453
[email protected]49639fa2011-12-20 23:22:4111454 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5311455
mmenkee65e7af2015-10-13 17:16:4211456 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611457 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011458 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5311459
[email protected]49639fa2011-12-20 23:22:4111460 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5311461
11462 EXPECT_EQ(ERR_IO_PENDING, rv);
11463 EXPECT_EQ(OK, callback.WaitForResult());
11464
11465 const HttpResponseInfo* response = trans->GetResponseInfo();
11466 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011467 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5311468 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11469
11470 std::string response_data;
11471 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11472 EXPECT_EQ("hello world", response_data);
11473
11474 EXPECT_FALSE(response->was_fetched_via_spdy);
11475 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5311476}
[email protected]26ef6582010-06-24 02:30:4711477
bnc55ff9da2015-08-19 18:42:3511478// Simulate the SSL handshake completing with an NPN negotiation followed by an
11479// immediate server closing of the socket.
11480// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0211481TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bnc55ff9da2015-08-19 18:42:3511482 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311483 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4711484
11485 HttpRequestInfo request;
11486 request.method = "GET";
bncce36dca22015-04-21 22:11:2311487 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4711488 request.load_flags = 0;
11489
[email protected]8ddf8322012-02-23 18:08:0611490 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811491 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0711492 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4711493
[email protected]cdf8f7e72013-05-23 10:56:4611494 scoped_ptr<SpdyFrame> req(
11495 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1311496 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4711497
11498 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611499 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4711500 };
11501
rch8e6c6c42015-05-01 14:05:1311502 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11503 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711504 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4711505
[email protected]49639fa2011-12-20 23:22:4111506 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4711507
mmenkee65e7af2015-10-13 17:16:4211508 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611509 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011510 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4711511
[email protected]49639fa2011-12-20 23:22:4111512 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4711513 EXPECT_EQ(ERR_IO_PENDING, rv);
11514 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4711515}
[email protected]65d34382010-07-01 18:12:2611516
[email protected]795cbf82013-07-22 09:37:2711517// A subclass of HttpAuthHandlerMock that records the request URL when
11518// it gets it. This is needed since the auth handler may get destroyed
11519// before we get a chance to query it.
11520class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
11521 public:
11522 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
11523
dchengb03027d2014-10-21 12:00:2011524 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2711525
11526 protected:
dchengb03027d2014-10-21 12:00:2011527 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
11528 const HttpRequestInfo* request,
11529 const CompletionCallback& callback,
11530 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2711531 *url_ = request->url;
11532 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
11533 credentials, request, callback, auth_token);
11534 }
11535
11536 private:
11537 GURL* url_;
11538};
11539
bnc55ff9da2015-08-19 18:42:3511540// This test ensures that the URL passed into the proxy is upgraded to https
11541// when doing an Alternate Protocol upgrade.
[email protected]23e482282013-06-14 16:08:0211542TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
bnc55ff9da2015-08-19 18:42:3511543 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311544 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3011545
rdsmith82957ad2015-09-16 19:42:0311546 session_deps_.proxy_service =
11547 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111548 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711549 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2711550 GURL request_url;
11551 {
11552 HttpAuthHandlerMock::Factory* auth_factory =
11553 new HttpAuthHandlerMock::Factory();
11554 UrlRecordingHttpAuthHandlerMock* auth_handler =
11555 new UrlRecordingHttpAuthHandlerMock(&request_url);
11556 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11557 auth_factory->set_do_init_from_challenge(true);
11558 session_deps_.http_auth_handler_factory.reset(auth_factory);
11559 }
[email protected]f45c1ee2010-08-03 00:54:3011560
11561 HttpRequestInfo request;
11562 request.method = "GET";
bncce36dca22015-04-21 22:11:2311563 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3011564 request.load_flags = 0;
11565
11566 // First round goes unauthenticated through the proxy.
11567 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2311568 MockWrite(
11569 "GET http://www.example.org/ HTTP/1.1\r\n"
11570 "Host: www.example.org\r\n"
11571 "Proxy-Connection: keep-alive\r\n"
11572 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011573 };
11574 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0611575 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3811576 MockRead("HTTP/1.1 200 OK\r\n"),
11577 MockRead("Alternate-Protocol: 443:"),
11578 MockRead(GetAlternateProtocolFromParam()),
11579 MockRead("\r\n"),
11580 MockRead("Proxy-Connection: close\r\n"),
11581 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011582 };
11583 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
11584 data_writes_1, arraysize(data_writes_1));
11585
bncce36dca22015-04-21 22:11:2311586 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3011587 // Alternate-Protocol announcement in the first round. It fails due
11588 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2311589 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5911590 // Proxy-Authorization headers. There is then a SPDY request round.
11591 //
[email protected]fe3b7dc2012-02-03 19:52:0911592 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
11593 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
11594 // does a Disconnect and Connect on the same socket, rather than trying
11595 // to obtain a new one.
11596 //
[email protected]394816e92010-08-03 07:38:5911597 // NOTE: Originally, the proxy response to the second CONNECT request
11598 // simply returned another 407 so the unit test could skip the SSL connection
11599 // establishment and SPDY framing issues. Alas, the
11600 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3011601 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5911602
[email protected]cdf8f7e72013-05-23 10:56:4611603 scoped_ptr<SpdyFrame> req(
11604 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0211605 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11606 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3011607
[email protected]394816e92010-08-03 07:38:5911608 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2311609 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311610 MockWrite(ASYNC, 0,
11611 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711612 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311613 "Proxy-Connection: keep-alive\r\n"
11614 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911615
bncce36dca22015-04-21 22:11:2311616 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311617 MockWrite(ASYNC, 2,
11618 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711619 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311620 "Proxy-Connection: keep-alive\r\n"
11621 "Proxy-Authorization: auth_token\r\n"
11622 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011623
bncce36dca22015-04-21 22:11:2311624 // SPDY request
rch8e6c6c42015-05-01 14:05:1311625 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3011626 };
[email protected]394816e92010-08-03 07:38:5911627 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1311628 // First connection attempt fails
mmenkee71e15332015-10-07 16:39:5411629 MockRead(ASYNC, 1,
11630 "HTTP/1.1 407 Unauthorized\r\n"
11631 "Proxy-Authenticate: Mock\r\n"
11632 "Content-Length: 0\r\n"
11633 "Proxy-Connection: keep-alive\r\n"
11634 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911635
rch8e6c6c42015-05-01 14:05:1311636 // Second connection attempt passes
mmenkee71e15332015-10-07 16:39:5411637 MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:5911638
rch8e6c6c42015-05-01 14:05:1311639 // SPDY response
mmenkee71e15332015-10-07 16:39:5411640 CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1311641 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5911642 };
rch8e6c6c42015-05-01 14:05:1311643 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
11644 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3011645
[email protected]8ddf8322012-02-23 18:08:0611646 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811647 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2311648 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
11649 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3011650
[email protected]d973e99a2012-02-17 21:02:3611651 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511652 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11653 NULL, 0, NULL, 0);
11654 hanging_non_alternate_protocol_socket.set_connect_data(
11655 never_finishing_connect);
11656
[email protected]bb88e1d32013-05-03 23:11:0711657 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
11658 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
11659 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11660 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511661 &hanging_non_alternate_protocol_socket);
mmenkee65e7af2015-10-13 17:16:4211662 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3011663
11664 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4111665 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3611666 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5011667 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111668 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011669 EXPECT_EQ(ERR_IO_PENDING, rv);
11670 EXPECT_EQ(OK, callback_1.WaitForResult());
11671
11672 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4111673 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3611674 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5011675 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111676 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011677 EXPECT_EQ(ERR_IO_PENDING, rv);
11678 EXPECT_EQ(OK, callback_2.WaitForResult());
11679 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011680 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3011681 ASSERT_FALSE(response->auth_challenge.get() == NULL);
11682
11683 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4111684 TestCompletionCallback callback_3;
11685 rv = trans_2->RestartWithAuth(
11686 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3011687 EXPECT_EQ(ERR_IO_PENDING, rv);
11688 EXPECT_EQ(OK, callback_3.WaitForResult());
11689
11690 // After all that work, these two lines (or actually, just the scheme) are
11691 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3011692 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2311693 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3011694
[email protected]029c83b62013-01-24 05:28:2011695 LoadTimingInfo load_timing_info;
11696 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
11697 TestLoadTimingNotReusedWithPac(load_timing_info,
11698 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3811699}
11700
11701// Test that if we cancel the transaction as the connection is completing, that
11702// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0211703TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3811704 // Setup everything about the connection to complete synchronously, so that
11705 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
11706 // for is the callback from the HttpStreamRequest.
11707 // Then cancel the transaction.
11708 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3611709 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3811710 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611711 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
11712 MockRead(SYNCHRONOUS, "hello world"),
11713 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3811714 };
11715
[email protected]8e6441ca2010-08-19 05:56:3811716 HttpRequestInfo request;
11717 request.method = "GET";
bncce36dca22015-04-21 22:11:2311718 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3811719 request.load_flags = 0;
11720
[email protected]bb88e1d32013-05-03 23:11:0711721 session_deps_.host_resolver->set_synchronous_mode(true);
mmenkee65e7af2015-10-13 17:16:4211722 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2711723 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111724 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2711725
[email protected]8e6441ca2010-08-19 05:56:3811726 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11727 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711728 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3811729
[email protected]49639fa2011-12-20 23:22:4111730 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3811731
vishal.b62985ca92015-04-17 08:45:5111732 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4111733 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3811734 EXPECT_EQ(ERR_IO_PENDING, rv);
11735 trans.reset(); // Cancel the transaction here.
11736
[email protected]2da659e2013-05-23 20:51:3411737 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3011738}
11739
[email protected]ecab6e052014-05-16 14:58:1211740// Test that if a transaction is cancelled after receiving the headers, the
11741// stream is drained properly and added back to the socket pool. The main
11742// purpose of this test is to make sure that an HttpStreamParser can be read
11743// from after the HttpNetworkTransaction and the objects it owns have been
11744// deleted.
11745// See http://crbug.com/368418
11746TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
11747 MockRead data_reads[] = {
11748 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
11749 MockRead(ASYNC, "Content-Length: 2\r\n"),
11750 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
11751 MockRead(ASYNC, "1"),
11752 // 2 async reads are necessary to trigger a ReadResponseBody call after the
11753 // HttpNetworkTransaction has been deleted.
11754 MockRead(ASYNC, "2"),
11755 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
11756 };
11757 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11758 session_deps_.socket_factory->AddSocketDataProvider(&data);
11759
mmenkee65e7af2015-10-13 17:16:4211760 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1211761
11762 {
11763 HttpRequestInfo request;
11764 request.method = "GET";
bncce36dca22015-04-21 22:11:2311765 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1211766 request.load_flags = 0;
11767
dcheng48459ac22014-08-26 00:46:4111768 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1211769 TestCompletionCallback callback;
11770
11771 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
11772 EXPECT_EQ(ERR_IO_PENDING, rv);
11773 callback.WaitForResult();
11774
11775 const HttpResponseInfo* response = trans.GetResponseInfo();
11776 ASSERT_TRUE(response != NULL);
11777 EXPECT_TRUE(response->headers.get() != NULL);
11778 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11779
11780 // The transaction and HttpRequestInfo are deleted.
11781 }
11782
11783 // Let the HttpResponseBodyDrainer drain the socket.
11784 base::MessageLoop::current()->RunUntilIdle();
11785
11786 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4111787 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1211788}
11789
[email protected]76a505b2010-08-25 06:23:0011790// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211791TEST_P(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0311792 session_deps_.proxy_service =
11793 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111794 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711795 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:4211796 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011797
[email protected]76a505b2010-08-25 06:23:0011798 HttpRequestInfo request;
11799 request.method = "GET";
bncce36dca22015-04-21 22:11:2311800 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011801
11802 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311803 MockWrite(
11804 "GET http://www.example.org/ HTTP/1.1\r\n"
11805 "Host: www.example.org\r\n"
11806 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011807 };
11808
11809 MockRead data_reads1[] = {
11810 MockRead("HTTP/1.1 200 OK\r\n"),
11811 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11812 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611813 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011814 };
11815
11816 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11817 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711818 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0011819
[email protected]49639fa2011-12-20 23:22:4111820 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011821
[email protected]262eec82013-03-19 21:01:3611822 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011823 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2711824 BeforeProxyHeadersSentHandler proxy_headers_handler;
11825 trans->SetBeforeProxyHeadersSentCallback(
11826 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
11827 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5011828
[email protected]49639fa2011-12-20 23:22:4111829 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011830 EXPECT_EQ(ERR_IO_PENDING, rv);
11831
11832 rv = callback1.WaitForResult();
11833 EXPECT_EQ(OK, rv);
11834
11835 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011836 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011837
11838 EXPECT_TRUE(response->headers->IsKeepAlive());
11839 EXPECT_EQ(200, response->headers->response_code());
11840 EXPECT_EQ(100, response->headers->GetContentLength());
11841 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511842 EXPECT_TRUE(
11843 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2711844 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
11845 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0011846 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2011847
11848 LoadTimingInfo load_timing_info;
11849 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11850 TestLoadTimingNotReusedWithPac(load_timing_info,
11851 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0011852}
11853
11854// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211855TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0311856 session_deps_.proxy_service =
11857 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111858 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711859 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:4211860 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011861
[email protected]76a505b2010-08-25 06:23:0011862 HttpRequestInfo request;
11863 request.method = "GET";
bncce36dca22015-04-21 22:11:2311864 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011865
11866 // Since we have proxy, should try to establish tunnel.
11867 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1711868 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
11869 "Host: www.example.org:443\r\n"
11870 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011871
rsleevidb16bb02015-11-12 23:47:1711872 MockWrite("GET / HTTP/1.1\r\n"
11873 "Host: www.example.org\r\n"
11874 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011875 };
11876
11877 MockRead data_reads1[] = {
11878 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
11879
11880 MockRead("HTTP/1.1 200 OK\r\n"),
11881 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11882 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611883 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011884 };
11885
11886 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11887 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711888 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611889 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711890 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011891
[email protected]49639fa2011-12-20 23:22:4111892 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011893
[email protected]262eec82013-03-19 21:01:3611894 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011895 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011896
[email protected]49639fa2011-12-20 23:22:4111897 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011898 EXPECT_EQ(ERR_IO_PENDING, rv);
11899
11900 rv = callback1.WaitForResult();
11901 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4611902 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011903 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011904 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011905 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011906 NetLog::PHASE_NONE);
11907 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011908 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011909 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11910 NetLog::PHASE_NONE);
11911
11912 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011913 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011914
11915 EXPECT_TRUE(response->headers->IsKeepAlive());
11916 EXPECT_EQ(200, response->headers->response_code());
11917 EXPECT_EQ(100, response->headers->GetContentLength());
11918 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
11919 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511920 EXPECT_TRUE(
11921 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2011922
11923 LoadTimingInfo load_timing_info;
11924 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11925 TestLoadTimingNotReusedWithPac(load_timing_info,
11926 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0011927}
11928
rsleevidb16bb02015-11-12 23:47:1711929// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
11930// literal host.
11931TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
11932 session_deps_.proxy_service =
11933 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
11934 BoundTestNetLog log;
11935 session_deps_.net_log = log.bound().net_log();
11936 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11937
11938 HttpRequestInfo request;
11939 request.method = "GET";
11940 request.url = GURL("https://[::1]:443/");
11941
11942 // Since we have proxy, should try to establish tunnel.
11943 MockWrite data_writes1[] = {
11944 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
11945 "Host: [::1]:443\r\n"
11946 "Proxy-Connection: keep-alive\r\n\r\n"),
11947
11948 MockWrite("GET / HTTP/1.1\r\n"
11949 "Host: [::1]\r\n"
11950 "Connection: keep-alive\r\n\r\n"),
11951 };
11952
11953 MockRead data_reads1[] = {
11954 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
11955
11956 MockRead("HTTP/1.1 200 OK\r\n"),
11957 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11958 MockRead("Content-Length: 100\r\n\r\n"),
11959 MockRead(SYNCHRONOUS, OK),
11960 };
11961
11962 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11963 data_writes1, arraysize(data_writes1));
11964 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11965 SSLSocketDataProvider ssl(ASYNC, OK);
11966 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11967
11968 TestCompletionCallback callback1;
11969
11970 scoped_ptr<HttpTransaction> trans(
11971 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11972
11973 int rv = trans->Start(&request, callback1.callback(), log.bound());
11974 EXPECT_EQ(ERR_IO_PENDING, rv);
11975
11976 rv = callback1.WaitForResult();
11977 EXPECT_EQ(OK, rv);
11978 TestNetLogEntry::List entries;
11979 log.GetEntries(&entries);
11980 size_t pos = ExpectLogContainsSomewhere(
11981 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
11982 NetLog::PHASE_NONE);
11983 ExpectLogContainsSomewhere(
11984 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11985 NetLog::PHASE_NONE);
11986
11987 const HttpResponseInfo* response = trans->GetResponseInfo();
11988 ASSERT_TRUE(response != NULL);
11989
11990 EXPECT_TRUE(response->headers->IsKeepAlive());
11991 EXPECT_EQ(200, response->headers->response_code());
11992 EXPECT_EQ(100, response->headers->GetContentLength());
11993 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
11994 EXPECT_TRUE(response->was_fetched_via_proxy);
11995 EXPECT_TRUE(
11996 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
11997
11998 LoadTimingInfo load_timing_info;
11999 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12000 TestLoadTimingNotReusedWithPac(load_timing_info,
12001 CONNECT_TIMING_HAS_SSL_TIMES);
12002}
12003
[email protected]76a505b2010-08-25 06:23:0012004// Test a basic HTTPS GET request through a proxy, but the server hangs up
12005// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0212006TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312007 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112008 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712009 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:4212010 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012011
[email protected]76a505b2010-08-25 06:23:0012012 HttpRequestInfo request;
12013 request.method = "GET";
bncce36dca22015-04-21 22:11:2312014 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012015
12016 // Since we have proxy, should try to establish tunnel.
12017 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712018 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12019 "Host: www.example.org:443\r\n"
12020 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012021
rsleevidb16bb02015-11-12 23:47:1712022 MockWrite("GET / HTTP/1.1\r\n"
12023 "Host: www.example.org\r\n"
12024 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012025 };
12026
12027 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0612028 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0012029 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612030 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0012031 };
12032
12033 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12034 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712035 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612036 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712037 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012038
[email protected]49639fa2011-12-20 23:22:4112039 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012040
[email protected]262eec82013-03-19 21:01:3612041 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012042 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5012043
[email protected]49639fa2011-12-20 23:22:4112044 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012045 EXPECT_EQ(ERR_IO_PENDING, rv);
12046
12047 rv = callback1.WaitForResult();
12048 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4612049 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012050 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012051 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012052 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0012053 NetLog::PHASE_NONE);
12054 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012055 entries, pos,
[email protected]76a505b2010-08-25 06:23:0012056 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12057 NetLog::PHASE_NONE);
12058}
12059
[email protected]749eefa82010-09-13 22:14:0312060// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0212061TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4612062 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2312063 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1312064 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0312065
[email protected]23e482282013-06-14 16:08:0212066 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12067 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0312068 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312069 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0312070 };
12071
rch8e6c6c42015-05-01 14:05:1312072 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12073 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712074 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0312075
[email protected]8ddf8322012-02-23 18:08:0612076 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812077 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712078 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0312079
mmenkee65e7af2015-10-13 17:16:4212080 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0312081
12082 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2312083 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012084 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5312085 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2712086 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4212087 CreateInsecureSpdySession(session.get(), key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312088
12089 HttpRequestInfo request;
12090 request.method = "GET";
bncce36dca22015-04-21 22:11:2312091 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0312092 request.load_flags = 0;
12093
12094 // This is the important line that marks this as a preconnect.
12095 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
12096
[email protected]262eec82013-03-19 21:01:3612097 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012098 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0312099
[email protected]41d64e82013-07-03 22:44:2612100 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4112101 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312102 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112103 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0312104}
12105
[email protected]73b8dd222010-11-11 19:55:2412106// Given a net error, cause that error to be returned from the first Write()
12107// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0212108void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0712109 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2912110 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712111 request_info.url = GURL("https://www.example.com/");
12112 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912113 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712114
[email protected]8ddf8322012-02-23 18:08:0612115 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2912116 MockWrite data_writes[] = {
12117 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2412118 };
ttuttle859dc7a2015-04-23 19:42:2912119 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712120 session_deps_.socket_factory->AddSocketDataProvider(&data);
12121 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2412122
mmenkee65e7af2015-10-13 17:16:4212123 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3612124 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012125 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2412126
[email protected]49639fa2011-12-20 23:22:4112127 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912128 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12129 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2412130 rv = callback.WaitForResult();
12131 ASSERT_EQ(error, rv);
12132}
12133
[email protected]23e482282013-06-14 16:08:0212134TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2412135 // Just check a grab bag of cert errors.
12136 static const int kErrors[] = {
12137 ERR_CERT_COMMON_NAME_INVALID,
12138 ERR_CERT_AUTHORITY_INVALID,
12139 ERR_CERT_DATE_INVALID,
12140 };
12141 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0612142 CheckErrorIsPassedBack(kErrors[i], ASYNC);
12143 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2412144 }
12145}
12146
[email protected]bd0b6772011-01-11 19:59:3012147// Ensure that a client certificate is removed from the SSL client auth
12148// cache when:
12149// 1) No proxy is involved.
12150// 2) TLS False Start is disabled.
12151// 3) The initial TLS handshake requests a client certificate.
12152// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212153TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312154 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912155 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712156 request_info.url = GURL("https://www.example.com/");
12157 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912158 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712159
[email protected]bd0b6772011-01-11 19:59:3012160 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112161 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012162
12163 // [ssl_]data1 contains the data for the first SSL handshake. When a
12164 // CertificateRequest is received for the first time, the handshake will
12165 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2912166 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012167 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712168 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912169 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712170 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012171
12172 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
12173 // False Start is not being used, the result of the SSL handshake will be
12174 // returned as part of the SSLClientSocket::Connect() call. This test
12175 // matches the result of a server sending a handshake_failure alert,
12176 // rather than a Finished message, because it requires a client
12177 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2912178 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012179 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712180 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912181 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712182 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012183
12184 // [ssl_]data3 contains the data for the third SSL handshake. When a
12185 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212186 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
12187 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3012188 // of the HttpNetworkTransaction. Because this test failure is due to
12189 // requiring a client certificate, this fallback handshake should also
12190 // fail.
ttuttle859dc7a2015-04-23 19:42:2912191 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012192 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712193 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912194 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712195 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012196
[email protected]80c75f682012-05-26 16:22:1712197 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
12198 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212199 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
12200 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1712201 // of the HttpNetworkTransaction. Because this test failure is due to
12202 // requiring a client certificate, this fallback handshake should also
12203 // fail.
ttuttle859dc7a2015-04-23 19:42:2912204 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1712205 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712206 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912207 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712208 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712209
mmenkee65e7af2015-10-13 17:16:4212210 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3612211 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012213
[email protected]bd0b6772011-01-11 19:59:3012214 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4112215 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912216 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12217 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012218
12219 // Complete the SSL handshake, which should abort due to requiring a
12220 // client certificate.
12221 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912222 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012223
12224 // Indicate that no certificate should be supplied. From the perspective
12225 // of SSLClientCertCache, NULL is just as meaningful as a real
12226 // certificate, so this is the same as supply a
12227 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412228 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912229 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012230
12231 // Ensure the certificate was added to the client auth cache before
12232 // allowing the connection to continue restarting.
12233 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412234 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112235 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412236 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012237 ASSERT_EQ(NULL, client_cert.get());
12238
12239 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712240 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12241 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012242 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912243 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012244
12245 // Ensure that the client certificate is removed from the cache on a
12246 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112247 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412248 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012249}
12250
12251// Ensure that a client certificate is removed from the SSL client auth
12252// cache when:
12253// 1) No proxy is involved.
12254// 2) TLS False Start is enabled.
12255// 3) The initial TLS handshake requests a client certificate.
12256// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212257TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312258 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912259 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712260 request_info.url = GURL("https://www.example.com/");
12261 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912262 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712263
[email protected]bd0b6772011-01-11 19:59:3012264 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112265 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012266
12267 // When TLS False Start is used, SSLClientSocket::Connect() calls will
12268 // return successfully after reading up to the peer's Certificate message.
12269 // This is to allow the caller to call SSLClientSocket::Write(), which can
12270 // enqueue application data to be sent in the same packet as the
12271 // ChangeCipherSpec and Finished messages.
12272 // The actual handshake will be finished when SSLClientSocket::Read() is
12273 // called, which expects to process the peer's ChangeCipherSpec and
12274 // Finished messages. If there was an error negotiating with the peer,
12275 // such as due to the peer requiring a client certificate when none was
12276 // supplied, the alert sent by the peer won't be processed until Read() is
12277 // called.
12278
12279 // Like the non-False Start case, when a client certificate is requested by
12280 // the peer, the handshake is aborted during the Connect() call.
12281 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2912282 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012283 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712284 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912285 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712286 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012287
12288 // When a client certificate is supplied, Connect() will not be aborted
12289 // when the peer requests the certificate. Instead, the handshake will
12290 // artificially succeed, allowing the caller to write the HTTP request to
12291 // the socket. The handshake messages are not processed until Read() is
12292 // called, which then detects that the handshake was aborted, due to the
12293 // peer sending a handshake_failure because it requires a client
12294 // certificate.
ttuttle859dc7a2015-04-23 19:42:2912295 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012296 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712297 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912298 MockRead data2_reads[] = {
12299 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3012300 };
ttuttle859dc7a2015-04-23 19:42:2912301 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712302 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012303
12304 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1712305 // the data for the SSL handshake once the TLSv1.1 connection falls back to
12306 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912307 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012308 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712309 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912310 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712311 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012312
[email protected]80c75f682012-05-26 16:22:1712313 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
12314 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912315 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1712316 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712317 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912318 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712319 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712320
[email protected]7799de12013-05-30 05:52:5112321 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2912322 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5112323 ssl_data5.cert_request_info = cert_request.get();
12324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2912325 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5112326 session_deps_.socket_factory->AddSocketDataProvider(&data5);
12327
mmenkee65e7af2015-10-13 17:16:4212328 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3612329 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012330 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012331
[email protected]bd0b6772011-01-11 19:59:3012332 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4112333 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912334 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12335 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012336
12337 // Complete the SSL handshake, which should abort due to requiring a
12338 // client certificate.
12339 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912340 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012341
12342 // Indicate that no certificate should be supplied. From the perspective
12343 // of SSLClientCertCache, NULL is just as meaningful as a real
12344 // certificate, so this is the same as supply a
12345 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412346 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912347 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012348
12349 // Ensure the certificate was added to the client auth cache before
12350 // allowing the connection to continue restarting.
12351 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412352 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112353 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412354 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012355 ASSERT_EQ(NULL, client_cert.get());
12356
[email protected]bd0b6772011-01-11 19:59:3012357 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712358 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12359 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012360 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912361 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012362
12363 // Ensure that the client certificate is removed from the cache on a
12364 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112365 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412366 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012367}
12368
[email protected]8c405132011-01-11 22:03:1812369// Ensure that a client certificate is removed from the SSL client auth
12370// cache when:
12371// 1) An HTTPS proxy is involved.
12372// 3) The HTTPS proxy requests a client certificate.
12373// 4) The client supplies an invalid/unacceptable certificate for the
12374// proxy.
12375// The test is repeated twice, first for connecting to an HTTPS endpoint,
12376// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0212377TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0312378 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5112379 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712380 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1812381
12382 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112383 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1812384
12385 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
12386 // [ssl_]data[1-3]. Rather than represending the endpoint
12387 // (www.example.com:443), they represent failures with the HTTPS proxy
12388 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2912389 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1812390 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712391 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912392 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712393 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1812394
ttuttle859dc7a2015-04-23 19:42:2912395 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812396 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712397 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912398 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712399 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1812400
[email protected]80c75f682012-05-26 16:22:1712401 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
12402#if 0
ttuttle859dc7a2015-04-23 19:42:2912403 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812404 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712405 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912406 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712407 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1712408#endif
[email protected]8c405132011-01-11 22:03:1812409
ttuttle859dc7a2015-04-23 19:42:2912410 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1812411 requests[0].url = GURL("https://www.example.com/");
12412 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912413 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812414
12415 requests[1].url = GURL("http://www.example.com/");
12416 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912417 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812418
12419 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0712420 session_deps_.socket_factory->ResetNextMockIndexes();
mmenkee65e7af2015-10-13 17:16:4212421 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1812422 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012423 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1812424
12425 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4112426 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912427 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
12428 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1812429
12430 // Complete the SSL handshake, which should abort due to requiring a
12431 // client certificate.
12432 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912433 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1812434
12435 // Indicate that no certificate should be supplied. From the perspective
12436 // of SSLClientCertCache, NULL is just as meaningful as a real
12437 // certificate, so this is the same as supply a
12438 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412439 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912440 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1812441
12442 // Ensure the certificate was added to the client auth cache before
12443 // allowing the connection to continue restarting.
12444 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412445 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112446 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412447 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]8c405132011-01-11 22:03:1812448 ASSERT_EQ(NULL, client_cert.get());
12449 // Ensure the certificate was NOT cached for the endpoint. This only
12450 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4112451 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412452 HostPortPair("www.example.com", 443), &client_cert,
12453 &client_private_key));
[email protected]8c405132011-01-11 22:03:1812454
12455 // Restart the handshake. This will consume ssl_data2, which fails, and
12456 // then consume ssl_data3, which should also fail. The result code is
12457 // checked against what ssl_data3 should return.
12458 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912459 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1812460
12461 // Now that the new handshake has failed, ensure that the client
12462 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4112463 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412464 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4112465 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412466 HostPortPair("www.example.com", 443), &client_cert,
12467 &client_private_key));
[email protected]8c405132011-01-11 22:03:1812468 }
12469}
12470
mmenke5c642132015-06-02 16:05:1312471TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bnc55ff9da2015-08-19 18:42:3512472 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2312473 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4612474
12475 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712476 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenkee65e7af2015-10-13 17:16:4212477 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612478 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12479 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612480
[email protected]8ddf8322012-02-23 18:08:0612481 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812482 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712483 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612484
[email protected]cdf8f7e72013-05-23 10:56:4612485 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2312486 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812487 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]cdf8f7e72013-05-23 10:56:4612488 scoped_ptr<SpdyFrame> host2_req(
12489 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612490 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312491 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612492 };
[email protected]23e482282013-06-14 16:08:0212493 scoped_ptr<SpdyFrame> host1_resp(
12494 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12495 scoped_ptr<SpdyFrame> host1_resp_body(
12496 spdy_util_.ConstructSpdyBodyFrame(1, true));
12497 scoped_ptr<SpdyFrame> host2_resp(
12498 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12499 scoped_ptr<SpdyFrame> host2_resp_body(
12500 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612501 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312502 CreateMockRead(*host1_resp, 1),
12503 CreateMockRead(*host1_resp_body, 2),
12504 CreateMockRead(*host2_resp, 4),
12505 CreateMockRead(*host2_resp_body, 5),
12506 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612507 };
12508
[email protected]d2b5f092012-06-08 23:55:0212509 IPAddressNumber ip;
12510 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12511 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12512 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312513 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12514 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712515 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612516
[email protected]aa22b242011-11-16 18:58:2912517 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612518 HttpRequestInfo request1;
12519 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312520 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612521 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012522 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612523
[email protected]49639fa2011-12-20 23:22:4112524 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612525 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112526 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612527
12528 const HttpResponseInfo* response = trans1.GetResponseInfo();
12529 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012530 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0212531 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612532
12533 std::string response_data;
12534 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12535 EXPECT_EQ("hello!", response_data);
12536
12537 // Preload www.gmail.com into HostCache.
12538 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1012539 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4612540 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012541 rv = session_deps_.host_resolver->Resolve(resolve_info,
12542 DEFAULT_PRIORITY,
12543 &ignored,
12544 callback.callback(),
12545 NULL,
12546 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712547 EXPECT_EQ(ERR_IO_PENDING, rv);
12548 rv = callback.WaitForResult();
12549 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612550
12551 HttpRequestInfo request2;
12552 request2.method = "GET";
12553 request2.url = GURL("https://www.gmail.com/");
12554 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012555 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612556
[email protected]49639fa2011-12-20 23:22:4112557 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612558 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112559 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612560
12561 response = trans2.GetResponseInfo();
12562 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012563 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0212564 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612565 EXPECT_TRUE(response->was_fetched_via_spdy);
12566 EXPECT_TRUE(response->was_npn_negotiated);
12567 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12568 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612569}
12570
[email protected]23e482282013-06-14 16:08:0212571TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bnc55ff9da2015-08-19 18:42:3512572 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2312573 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0212574
12575 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712576 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenkee65e7af2015-10-13 17:16:4212577 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0212578 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12579 pool_peer.DisableDomainAuthenticationVerification();
12580
12581 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812582 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712583 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0212584
[email protected]cdf8f7e72013-05-23 10:56:4612585 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2312586 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812587 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]cdf8f7e72013-05-23 10:56:4612588 scoped_ptr<SpdyFrame> host2_req(
12589 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0212590 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312591 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0212592 };
[email protected]23e482282013-06-14 16:08:0212593 scoped_ptr<SpdyFrame> host1_resp(
12594 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12595 scoped_ptr<SpdyFrame> host1_resp_body(
12596 spdy_util_.ConstructSpdyBodyFrame(1, true));
12597 scoped_ptr<SpdyFrame> host2_resp(
12598 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12599 scoped_ptr<SpdyFrame> host2_resp_body(
12600 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0212601 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312602 CreateMockRead(*host1_resp, 1),
12603 CreateMockRead(*host1_resp_body, 2),
12604 CreateMockRead(*host2_resp, 4),
12605 CreateMockRead(*host2_resp_body, 5),
12606 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0212607 };
12608
12609 IPAddressNumber ip;
12610 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12611 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12612 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312613 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12614 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712615 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0212616
12617 TestCompletionCallback callback;
12618 HttpRequestInfo request1;
12619 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312620 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0212621 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012622 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212623
12624 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
12625 EXPECT_EQ(ERR_IO_PENDING, rv);
12626 EXPECT_EQ(OK, callback.WaitForResult());
12627
12628 const HttpResponseInfo* response = trans1.GetResponseInfo();
12629 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012630 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0212631 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0212632
12633 std::string response_data;
12634 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12635 EXPECT_EQ("hello!", response_data);
12636
12637 HttpRequestInfo request2;
12638 request2.method = "GET";
12639 request2.url = GURL("https://www.gmail.com/");
12640 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012641 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212642
12643 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
12644 EXPECT_EQ(ERR_IO_PENDING, rv);
12645 EXPECT_EQ(OK, callback.WaitForResult());
12646
12647 response = trans2.GetResponseInfo();
12648 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012649 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0212650 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0212651 EXPECT_TRUE(response->was_fetched_via_spdy);
12652 EXPECT_TRUE(response->was_npn_negotiated);
12653 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12654 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0212655}
12656
ttuttle859dc7a2015-04-23 19:42:2912657class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4612658 public:
12659 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
12660 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2012661 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4612662
12663 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
12664
12665 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2012666 int Resolve(const RequestInfo& info,
12667 RequestPriority priority,
12668 AddressList* addresses,
12669 const CompletionCallback& callback,
12670 RequestHandle* out_req,
12671 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012672 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1012673 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4012674 }
12675
dchengb03027d2014-10-21 12:00:2012676 int ResolveFromCache(const RequestInfo& info,
12677 AddressList* addresses,
12678 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012679 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
12680 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0912681 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4612682 return rv;
12683 }
12684
dchengb03027d2014-10-21 12:00:2012685 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4612686 host_resolver_.CancelRequest(req);
12687 }
12688
[email protected]46da33be2011-07-19 21:58:0412689 MockCachingHostResolver* GetMockHostResolver() {
12690 return &host_resolver_;
12691 }
12692
[email protected]e3ceb682011-06-28 23:55:4612693 private:
12694 MockCachingHostResolver host_resolver_;
12695 const HostPortPair host_port_;
12696};
12697
mmenke5c642132015-06-02 16:05:1312698TEST_P(HttpNetworkTransactionTest,
12699 UseIPConnectionPoolingWithHostCacheExpiration) {
bnc55ff9da2015-08-19 18:42:3512700 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2312701 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4612702
12703 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4612704 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3412705 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0712706 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4612707 params.host_resolver = &host_resolver;
mmenkee65e7af2015-10-13 17:16:4212708 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612709 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12710 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612711
[email protected]8ddf8322012-02-23 18:08:0612712 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812713 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712714 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612715
[email protected]cdf8f7e72013-05-23 10:56:4612716 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2312717 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812718 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]cdf8f7e72013-05-23 10:56:4612719 scoped_ptr<SpdyFrame> host2_req(
12720 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612721 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312722 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612723 };
[email protected]23e482282013-06-14 16:08:0212724 scoped_ptr<SpdyFrame> host1_resp(
12725 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12726 scoped_ptr<SpdyFrame> host1_resp_body(
12727 spdy_util_.ConstructSpdyBodyFrame(1, true));
12728 scoped_ptr<SpdyFrame> host2_resp(
12729 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12730 scoped_ptr<SpdyFrame> host2_resp_body(
12731 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612732 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312733 CreateMockRead(*host1_resp, 1),
12734 CreateMockRead(*host1_resp_body, 2),
12735 CreateMockRead(*host2_resp, 4),
12736 CreateMockRead(*host2_resp_body, 5),
12737 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612738 };
12739
[email protected]d2b5f092012-06-08 23:55:0212740 IPAddressNumber ip;
12741 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12742 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12743 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312744 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12745 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712746 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612747
[email protected]aa22b242011-11-16 18:58:2912748 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612749 HttpRequestInfo request1;
12750 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312751 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612752 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012753 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612754
[email protected]49639fa2011-12-20 23:22:4112755 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612756 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112757 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612758
12759 const HttpResponseInfo* response = trans1.GetResponseInfo();
12760 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012761 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0212762 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612763
12764 std::string response_data;
12765 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12766 EXPECT_EQ("hello!", response_data);
12767
12768 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1012769 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4612770 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012771 rv = host_resolver.Resolve(resolve_info,
12772 DEFAULT_PRIORITY,
12773 &ignored,
12774 callback.callback(),
12775 NULL,
12776 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712777 EXPECT_EQ(ERR_IO_PENDING, rv);
12778 rv = callback.WaitForResult();
12779 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612780
12781 HttpRequestInfo request2;
12782 request2.method = "GET";
12783 request2.url = GURL("https://www.gmail.com/");
12784 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012785 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612786
[email protected]49639fa2011-12-20 23:22:4112787 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612788 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112789 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612790
12791 response = trans2.GetResponseInfo();
12792 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012793 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0212794 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612795 EXPECT_TRUE(response->was_fetched_via_spdy);
12796 EXPECT_TRUE(response->was_npn_negotiated);
12797 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12798 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612799}
12800
[email protected]23e482282013-06-14 16:08:0212801TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2312802 const std::string https_url = "https://www.example.org:8080/";
12803 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412804
12805 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4612806 scoped_ptr<SpdyFrame> req1(
12807 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0412808
12809 MockWrite writes1[] = {
12810 CreateMockWrite(*req1, 0),
12811 };
12812
[email protected]23e482282013-06-14 16:08:0212813 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12814 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0412815 MockRead reads1[] = {
12816 CreateMockRead(*resp1, 1),
12817 CreateMockRead(*body1, 2),
12818 MockRead(ASYNC, ERR_IO_PENDING, 3)
12819 };
12820
rch8e6c6c42015-05-01 14:05:1312821 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
12822 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412823 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712824 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412825
12826 // HTTP GET for the HTTP URL
12827 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1312828 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3412829 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2312830 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3412831 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0412832 };
12833
12834 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1312835 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12836 MockRead(ASYNC, 2, "hello"),
12837 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0412838 };
12839
rch8e6c6c42015-05-01 14:05:1312840 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12841 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0412842
[email protected]8450d722012-07-02 19:14:0412843 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812844 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712845 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12846 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12847 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0412848
mmenkee65e7af2015-10-13 17:16:4212849 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412850
12851 // Start the first transaction to set up the SpdySession
12852 HttpRequestInfo request1;
12853 request1.method = "GET";
12854 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412855 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012856 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412857 TestCompletionCallback callback1;
12858 EXPECT_EQ(ERR_IO_PENDING,
12859 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412860 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412861
12862 EXPECT_EQ(OK, callback1.WaitForResult());
12863 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12864
12865 // Now, start the HTTP request
12866 HttpRequestInfo request2;
12867 request2.method = "GET";
12868 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412869 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012870 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412871 TestCompletionCallback callback2;
12872 EXPECT_EQ(ERR_IO_PENDING,
12873 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412874 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412875
12876 EXPECT_EQ(OK, callback2.WaitForResult());
12877 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12878}
12879
bnc1b0e36852015-04-28 15:32:5912880class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
12881 public:
12882 void Run(bool pooling, bool valid) {
12883 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
12884 443);
12885 HostPortPair alternative("www.example.org", 443);
12886
12887 base::FilePath certs_dir = GetTestCertsDirectory();
12888 scoped_refptr<X509Certificate> cert(
12889 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
12890 ASSERT_TRUE(cert.get());
12891 bool common_name_fallback_used;
12892 EXPECT_EQ(valid,
12893 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
12894 EXPECT_TRUE(
12895 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
12896 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812897 ssl.SetNextProto(GetProtocol());
bnc1b0e36852015-04-28 15:32:5912898 ssl.cert = cert;
12899 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12900
12901 // If pooling, then start a request to alternative first to create a
12902 // SpdySession.
12903 std::string url0 = "https://www.example.org:443";
12904 // Second request to origin, which has an alternative service, and could
12905 // open a connection to the alternative host or pool to the existing one.
12906 std::string url1("https://");
12907 url1.append(origin.host());
12908 url1.append(":443");
12909
12910 scoped_ptr<SpdyFrame> req0;
12911 scoped_ptr<SpdyFrame> req1;
12912 scoped_ptr<SpdyFrame> resp0;
12913 scoped_ptr<SpdyFrame> body0;
12914 scoped_ptr<SpdyFrame> resp1;
12915 scoped_ptr<SpdyFrame> body1;
12916 std::vector<MockWrite> writes;
12917 std::vector<MockRead> reads;
12918
12919 if (pooling) {
12920 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812921 spdy_util_.UpdateWithStreamDestruction(1);
bnc1b0e36852015-04-28 15:32:5912922 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
12923
12924 writes.push_back(CreateMockWrite(*req0, 0));
12925 writes.push_back(CreateMockWrite(*req1, 3));
12926
12927 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12928 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12929 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12930 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
12931
12932 reads.push_back(CreateMockRead(*resp0, 1));
12933 reads.push_back(CreateMockRead(*body0, 2));
12934 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
12935 reads.push_back(CreateMockRead(*resp1, 5));
12936 reads.push_back(CreateMockRead(*body1, 6));
12937 reads.push_back(MockRead(ASYNC, OK, 7));
12938 } else {
12939 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
12940
12941 writes.push_back(CreateMockWrite(*req1, 0));
12942
12943 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12944 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12945
12946 reads.push_back(CreateMockRead(*resp1, 1));
12947 reads.push_back(CreateMockRead(*body1, 2));
12948 reads.push_back(MockRead(ASYNC, OK, 3));
12949 }
12950
davidben5f8b6bc2015-11-25 03:19:5412951 SequencedSocketData data(reads.data(), reads.size(), writes.data(),
12952 writes.size());
bnc1b0e36852015-04-28 15:32:5912953 session_deps_.socket_factory->AddSocketDataProvider(&data);
12954
12955 // Connection to the origin fails.
12956 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12957 StaticSocketDataProvider data_refused;
12958 data_refused.set_connect_data(mock_connect);
12959 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12960
bnc55ff9da2015-08-19 18:42:3512961 session_deps_.use_alternative_services = true;
mmenkee65e7af2015-10-13 17:16:4212962 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc1b0e36852015-04-28 15:32:5912963 base::WeakPtr<HttpServerProperties> http_server_properties =
12964 session->http_server_properties();
12965 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3812966 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212967 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc1b0e36852015-04-28 15:32:5912968 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212969 1.0, expiration);
bnc1b0e36852015-04-28 15:32:5912970
12971 // First request to alternative.
12972 if (pooling) {
12973 scoped_ptr<HttpTransaction> trans0(
12974 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12975 HttpRequestInfo request0;
12976 request0.method = "GET";
12977 request0.url = GURL(url0);
12978 request0.load_flags = 0;
12979 TestCompletionCallback callback0;
12980
12981 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
12982 EXPECT_EQ(ERR_IO_PENDING, rv);
12983 rv = callback0.WaitForResult();
12984 EXPECT_EQ(OK, rv);
12985 }
12986
12987 // Second request to origin.
12988 scoped_ptr<HttpTransaction> trans1(
12989 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12990 HttpRequestInfo request1;
12991 request1.method = "GET";
12992 request1.url = GURL(url1);
12993 request1.load_flags = 0;
12994 TestCompletionCallback callback1;
12995
12996 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12997 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0912998 base::MessageLoop::current()->RunUntilIdle();
12999 if (data.IsReadPaused()) {
13000 data.CompleteRead();
13001 }
bnc1b0e36852015-04-28 15:32:5913002 rv = callback1.WaitForResult();
13003 if (valid) {
13004 EXPECT_EQ(OK, rv);
13005 } else {
13006 if (pooling) {
13007 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
13008 } else {
13009 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
13010 }
13011 }
13012 }
13013};
13014
rdsmithebb50aa2015-11-12 03:44:3813015INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
bnc1b0e36852015-04-28 15:32:5913016 AltSvcCertificateVerificationTest,
rdsmithebb50aa2015-11-12 03:44:3813017 testing::Values(kTestCaseSPDY31,
13018 kTestCaseHTTP2NoPriorityDependencies,
13019 kTestCaseHTTP2PriorityDependencies));
bnc1b0e36852015-04-28 15:32:5913020
13021// The alternative service host must exhibit a certificate that is valid for the
13022// origin host. Test that this is enforced when pooling to an existing
13023// connection.
13024TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
13025 Run(true, true);
13026}
13027
13028TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
13029 Run(true, false);
13030}
13031
13032// The alternative service host must exhibit a certificate that is valid for the
13033// origin host. Test that this is enforced when opening a new connection.
13034TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
13035 Run(false, true);
13036}
13037
13038TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
13039 Run(false, false);
13040}
13041
bnc5452e2a2015-05-08 16:27:4213042// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
13043// with the alternative server. That connection should not be used.
13044TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
13045 HostPortPair origin("origin.example.org", 443);
13046 HostPortPair alternative("alternative.example.org", 443);
13047
13048 // Negotiate HTTP/1.1 with alternative.example.org.
13049 SSLSocketDataProvider ssl(ASYNC, OK);
13050 ssl.SetNextProto(kProtoHTTP11);
13051 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13052
13053 // No data should be read from the alternative, because HTTP/1.1 is
13054 // negotiated.
13055 StaticSocketDataProvider data;
13056 session_deps_.socket_factory->AddSocketDataProvider(&data);
13057
13058 // This test documents that an alternate Job should not be used if HTTP/1.1 is
13059 // negotiated. In order to test this, a failed connection to the origin is
13060 // mocked. This way the request relies on the alternate Job.
13061 StaticSocketDataProvider data_refused;
13062 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13063 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13064
13065 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3513066 session_deps_.use_alternative_services = true;
mmenkee65e7af2015-10-13 17:16:4213067 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213068 base::WeakPtr<HttpServerProperties> http_server_properties =
13069 session->http_server_properties();
13070 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813071 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213072 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4213073 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1213074 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4213075
13076 scoped_ptr<HttpTransaction> trans(
13077 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13078 HttpRequestInfo request;
13079 request.method = "GET";
13080 request.url = GURL("https://origin.example.org:443");
13081 request.load_flags = 0;
13082 TestCompletionCallback callback;
13083
13084 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
13085 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
13086 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13087 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
13088}
13089
bnc40448a532015-05-11 19:13:1413090// A request to a server with an alternative service fires two Jobs: one to the
13091// origin, and an alternate one to the alternative server. If the former
13092// succeeds, the request should succeed, even if the latter fails because
13093// HTTP/1.1 is negotiated which is insufficient for alternative service.
13094TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
13095 HostPortPair origin("origin.example.org", 443);
13096 HostPortPair alternative("alternative.example.org", 443);
13097
13098 // Negotiate HTTP/1.1 with alternative.
13099 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
13100 alternative_ssl.SetNextProto(kProtoHTTP11);
13101 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13102
13103 // No data should be read from the alternative, because HTTP/1.1 is
13104 // negotiated.
13105 StaticSocketDataProvider data;
13106 session_deps_.socket_factory->AddSocketDataProvider(&data);
13107
13108 // Negotiate HTTP/1.1 with origin.
13109 SSLSocketDataProvider origin_ssl(ASYNC, OK);
13110 origin_ssl.SetNextProto(kProtoHTTP11);
13111 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13112
13113 MockWrite http_writes[] = {
13114 MockWrite(
13115 "GET / HTTP/1.1\r\n"
13116 "Host: origin.example.org\r\n"
13117 "Connection: keep-alive\r\n\r\n"),
13118 MockWrite(
13119 "GET /second HTTP/1.1\r\n"
13120 "Host: origin.example.org\r\n"
13121 "Connection: keep-alive\r\n\r\n"),
13122 };
13123
13124 MockRead http_reads[] = {
13125 MockRead("HTTP/1.1 200 OK\r\n"),
13126 MockRead("Content-Type: text/html\r\n"),
13127 MockRead("Content-Length: 6\r\n\r\n"),
13128 MockRead("foobar"),
13129 MockRead("HTTP/1.1 200 OK\r\n"),
13130 MockRead("Content-Type: text/html\r\n"),
13131 MockRead("Content-Length: 7\r\n\r\n"),
13132 MockRead("another"),
13133 };
13134 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13135 http_writes, arraysize(http_writes));
13136 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13137
13138 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3513139 session_deps_.use_alternative_services = true;
mmenkee65e7af2015-10-13 17:16:4213140 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc40448a532015-05-11 19:13:1413141 base::WeakPtr<HttpServerProperties> http_server_properties =
13142 session->http_server_properties();
13143 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813144 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213145 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc40448a532015-05-11 19:13:1413146 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1213147 1.0, expiration);
bnc40448a532015-05-11 19:13:1413148
13149 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13150 HttpRequestInfo request1;
13151 request1.method = "GET";
13152 request1.url = GURL("https://origin.example.org:443");
13153 request1.load_flags = 0;
13154 TestCompletionCallback callback1;
13155
13156 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
13157 rv = callback1.GetResult(rv);
13158 EXPECT_EQ(OK, rv);
13159
13160 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
13161 ASSERT_TRUE(response1 != nullptr);
13162 ASSERT_TRUE(response1->headers.get() != nullptr);
13163 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13164
13165 std::string response_data1;
13166 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
13167 EXPECT_EQ("foobar", response_data1);
13168
13169 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13170 // for alternative service.
13171 EXPECT_TRUE(
13172 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13173
13174 // Since |alternative_service| is broken, a second transaction to origin
13175 // should not start an alternate Job. It should pool to existing connection
13176 // to origin.
13177 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13178 HttpRequestInfo request2;
13179 request2.method = "GET";
13180 request2.url = GURL("https://origin.example.org:443/second");
13181 request2.load_flags = 0;
13182 TestCompletionCallback callback2;
13183
13184 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
13185 rv = callback2.GetResult(rv);
13186 EXPECT_EQ(OK, rv);
13187
13188 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
13189 ASSERT_TRUE(response2 != nullptr);
13190 ASSERT_TRUE(response2->headers.get() != nullptr);
13191 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13192
13193 std::string response_data2;
13194 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
13195 EXPECT_EQ("another", response_data2);
13196}
13197
bnc5452e2a2015-05-08 16:27:4213198// Alternative service requires HTTP/2 (or SPDY), but there is already a
13199// HTTP/1.1 socket open to the alternative server. That socket should not be
13200// used.
13201TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
13202 HostPortPair origin("origin.example.org", 443);
13203 HostPortPair alternative("alternative.example.org", 443);
13204 std::string origin_url = "https://origin.example.org:443";
13205 std::string alternative_url = "https://alternative.example.org:443";
13206
13207 // Negotiate HTTP/1.1 with alternative.example.org.
13208 SSLSocketDataProvider ssl(ASYNC, OK);
13209 ssl.SetNextProto(kProtoHTTP11);
13210 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13211
13212 // HTTP/1.1 data for |request1| and |request2|.
13213 MockWrite http_writes[] = {
13214 MockWrite(
13215 "GET / HTTP/1.1\r\n"
13216 "Host: alternative.example.org\r\n"
13217 "Connection: keep-alive\r\n\r\n"),
13218 MockWrite(
13219 "GET / HTTP/1.1\r\n"
13220 "Host: alternative.example.org\r\n"
13221 "Connection: keep-alive\r\n\r\n"),
13222 };
13223
13224 MockRead http_reads[] = {
13225 MockRead(
13226 "HTTP/1.1 200 OK\r\n"
13227 "Content-Type: text/html; charset=iso-8859-1\r\n"
13228 "Content-Length: 40\r\n\r\n"
13229 "first HTTP/1.1 response from alternative"),
13230 MockRead(
13231 "HTTP/1.1 200 OK\r\n"
13232 "Content-Type: text/html; charset=iso-8859-1\r\n"
13233 "Content-Length: 41\r\n\r\n"
13234 "second HTTP/1.1 response from alternative"),
13235 };
13236 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13237 http_writes, arraysize(http_writes));
13238 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13239
13240 // This test documents that an alternate Job should not pool to an already
13241 // existing HTTP/1.1 connection. In order to test this, a failed connection
13242 // to the origin is mocked. This way |request2| relies on the alternate Job.
13243 StaticSocketDataProvider data_refused;
13244 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13245 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13246
13247 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3513248 session_deps_.use_alternative_services = true;
mmenkee65e7af2015-10-13 17:16:4213249 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213250 base::WeakPtr<HttpServerProperties> http_server_properties =
13251 session->http_server_properties();
13252 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813253 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213254 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4213255 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1213256 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4213257
13258 // First transaction to alternative to open an HTTP/1.1 socket.
13259 scoped_ptr<HttpTransaction> trans1(
13260 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13261 HttpRequestInfo request1;
13262 request1.method = "GET";
13263 request1.url = GURL(alternative_url);
13264 request1.load_flags = 0;
13265 TestCompletionCallback callback1;
13266
13267 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13268 EXPECT_EQ(OK, callback1.GetResult(rv));
13269 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13270 ASSERT_TRUE(response1);
13271 ASSERT_TRUE(response1->headers.get());
13272 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13273 EXPECT_TRUE(response1->was_npn_negotiated);
13274 EXPECT_FALSE(response1->was_fetched_via_spdy);
13275 std::string response_data1;
13276 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
13277 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
13278
13279 // Request for origin.example.org, which has an alternative service. This
13280 // will start two Jobs: the alternative looks for connections to pool to,
13281 // finds one which is HTTP/1.1, and should ignore it, and should not try to
13282 // open other connections to alternative server. The Job to origin fails, so
13283 // this request fails.
13284 scoped_ptr<HttpTransaction> trans2(
13285 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13286 HttpRequestInfo request2;
13287 request2.method = "GET";
13288 request2.url = GURL(origin_url);
13289 request2.load_flags = 0;
13290 TestCompletionCallback callback2;
13291
13292 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
13293 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
13294
13295 // Another transaction to alternative. This is to test that the HTTP/1.1
13296 // socket is still open and in the pool.
13297 scoped_ptr<HttpTransaction> trans3(
13298 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13299 HttpRequestInfo request3;
13300 request3.method = "GET";
13301 request3.url = GURL(alternative_url);
13302 request3.load_flags = 0;
13303 TestCompletionCallback callback3;
13304
13305 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
13306 EXPECT_EQ(OK, callback3.GetResult(rv));
13307 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
13308 ASSERT_TRUE(response3);
13309 ASSERT_TRUE(response3->headers.get());
13310 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
13311 EXPECT_TRUE(response3->was_npn_negotiated);
13312 EXPECT_FALSE(response3->was_fetched_via_spdy);
13313 std::string response_data3;
13314 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
13315 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
13316}
13317
[email protected]23e482282013-06-14 16:08:0213318TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2313319 const std::string https_url = "https://www.example.org:8080/";
13320 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413321
rdsmithebb50aa2015-11-12 03:44:3813322 // Separate SPDY util instance for naked and wrapped requests.
13323 SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
13324
[email protected]8450d722012-07-02 19:14:0413325 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2313326 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3413327 scoped_ptr<SpdyFrame> connect(
13328 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4613329 scoped_ptr<SpdyFrame> req1(
rdsmithebb50aa2015-11-12 03:44:3813330 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0213331 scoped_ptr<SpdyFrame> wrapped_req1(
13332 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3913333
13334 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2913335 SpdyHeaderBlock req2_block;
bnc7ecc1122015-09-28 13:22:4913336 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]745aa9c2014-06-27 02:21:2913337 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2313338 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2913339 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4913340 req2_block[spdy_util_.GetPathKey()] = "/";
[email protected]601e03f12014-04-06 16:26:3913341 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2913342 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0413343
13344 MockWrite writes1[] = {
13345 CreateMockWrite(*connect, 0),
13346 CreateMockWrite(*wrapped_req1, 2),
13347 CreateMockWrite(*req2, 5),
13348 };
13349
[email protected]23e482282013-06-14 16:08:0213350 scoped_ptr<SpdyFrame> conn_resp(
13351 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13352 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13353 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
13354 scoped_ptr<SpdyFrame> wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3813355 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
[email protected]23e482282013-06-14 16:08:0213356 scoped_ptr<SpdyFrame> wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3813357 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
[email protected]23e482282013-06-14 16:08:0213358 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
13359 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0413360 MockRead reads1[] = {
13361 CreateMockRead(*conn_resp, 1),
13362 CreateMockRead(*wrapped_resp1, 3),
13363 CreateMockRead(*wrapped_body1, 4),
13364 CreateMockRead(*resp2, 6),
13365 CreateMockRead(*body2, 7),
13366 MockRead(ASYNC, ERR_IO_PENDING, 8)
13367 };
13368
[email protected]dd54bd82012-07-19 23:44:5713369 DeterministicSocketData data1(reads1, arraysize(reads1),
13370 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413371 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713372 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413373
rdsmith82957ad2015-09-16 19:42:0313374 session_deps_.proxy_service =
13375 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5113376 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713377 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0413378 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3813379 ssl1.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713380 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0413381 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3813382 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713383 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
13384 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0413385
mmenkee65e7af2015-10-13 17:16:4213386 scoped_ptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0713387 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413388
13389 // Start the first transaction to set up the SpdySession
13390 HttpRequestInfo request1;
13391 request1.method = "GET";
13392 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413393 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013394 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413395 TestCompletionCallback callback1;
13396 EXPECT_EQ(ERR_IO_PENDING,
13397 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413398 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5713399 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0413400
13401 EXPECT_EQ(OK, callback1.WaitForResult());
13402 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13403
[email protected]f6c63db52013-02-02 00:35:2213404 LoadTimingInfo load_timing_info1;
13405 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
13406 TestLoadTimingNotReusedWithPac(load_timing_info1,
13407 CONNECT_TIMING_HAS_SSL_TIMES);
13408
[email protected]8450d722012-07-02 19:14:0413409 // Now, start the HTTP request
13410 HttpRequestInfo request2;
13411 request2.method = "GET";
13412 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413413 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013414 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413415 TestCompletionCallback callback2;
13416 EXPECT_EQ(ERR_IO_PENDING,
13417 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413418 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5713419 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0413420
13421 EXPECT_EQ(OK, callback2.WaitForResult());
13422 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2213423
13424 LoadTimingInfo load_timing_info2;
13425 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
13426 // The established SPDY sessions is considered reused by the HTTP request.
13427 TestLoadTimingReusedWithPac(load_timing_info2);
13428 // HTTP requests over a SPDY session should have a different connection
13429 // socket_log_id than requests over a tunnel.
13430 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0413431}
13432
[email protected]2d88e7d2012-07-19 17:55:1713433// Test that in the case where we have a SPDY session to a SPDY proxy
13434// that we do not pool other origins that resolve to the same IP when
13435// the certificate does not match the new origin.
13436// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0213437TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2313438 const std::string url1 = "http://www.example.org/";
13439 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1713440 const std::string ip_addr = "1.2.3.4";
13441
rdsmithebb50aa2015-11-12 03:44:3813442 // Second SpdyTestUtil instance for the second socket.
13443 SpdyTestUtil spdy_util_secure(GetProtocol(), GetDependenciesFromPriority());
13444
[email protected]2d88e7d2012-07-19 17:55:1713445 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0213446 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2313447 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2913448 scoped_ptr<SpdyFrame> req1(
13449 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1713450
13451 MockWrite writes1[] = {
13452 CreateMockWrite(*req1, 0),
13453 };
13454
[email protected]23e482282013-06-14 16:08:0213455 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13456 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1713457 MockRead reads1[] = {
bncb9e20fc62015-08-17 17:19:3713458 CreateMockRead(*resp1, 1),
13459 CreateMockRead(*body1, 2),
13460 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1713461 };
13462
13463 scoped_ptr<DeterministicSocketData> data1(
13464 new DeterministicSocketData(reads1, arraysize(reads1),
13465 writes1, arraysize(writes1)));
13466 IPAddressNumber ip;
13467 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
13468 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13469 MockConnect connect_data1(ASYNC, OK, peer_addr);
13470 data1->set_connect_data(connect_data1);
13471
13472 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4613473 scoped_ptr<SpdyFrame> req2(
rdsmithebb50aa2015-11-12 03:44:3813474 spdy_util_secure.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1713475
13476 MockWrite writes2[] = {
13477 CreateMockWrite(*req2, 0),
13478 };
13479
rdsmithebb50aa2015-11-12 03:44:3813480 scoped_ptr<SpdyFrame> resp2(
13481 spdy_util_secure.ConstructSpdyGetSynReply(NULL, 0, 1));
13482 scoped_ptr<SpdyFrame> body2(spdy_util_secure.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1713483 MockRead reads2[] = {
bncb9e20fc62015-08-17 17:19:3713484 CreateMockRead(*resp2, 1),
13485 CreateMockRead(*body2, 2),
13486 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1713487 };
13488
13489 scoped_ptr<DeterministicSocketData> data2(
13490 new DeterministicSocketData(reads2, arraysize(reads2),
13491 writes2, arraysize(writes2)));
13492 MockConnect connect_data2(ASYNC, OK);
13493 data2->set_connect_data(connect_data2);
13494
13495 // Set up a proxy config that sends HTTP requests to a proxy, and
13496 // all others direct.
13497 ProxyConfig proxy_config;
13498 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0713499 session_deps_.proxy_service.reset(new ProxyService(
csharrisonb7e3a082015-09-22 19:13:0413500 make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)), nullptr,
13501 NULL));
[email protected]2d88e7d2012-07-19 17:55:1713502
bncce36dca22015-04-21 22:11:2313503 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3813504 ssl1.SetNextProto(GetProtocol());
[email protected]2d88e7d2012-07-19 17:55:1713505 // Load a valid cert. Note, that this does not need to
13506 // be valid for proxy because the MockSSLClientSocket does
13507 // not actually verify it. But SpdySession will use this
13508 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2313509 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
13510 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0713511 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
13512 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
13513 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1713514
13515 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3813516 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713517 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
13518 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
13519 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1713520
[email protected]bb88e1d32013-05-03 23:11:0713521 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2313522 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0713523 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1713524
mmenkee65e7af2015-10-13 17:16:4213525 scoped_ptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0713526 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1713527
13528 // Start the first transaction to set up the SpdySession
13529 HttpRequestInfo request1;
13530 request1.method = "GET";
13531 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1713532 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013533 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713534 TestCompletionCallback callback1;
13535 ASSERT_EQ(ERR_IO_PENDING,
13536 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
13537 data1->RunFor(3);
13538
13539 ASSERT_TRUE(callback1.have_result());
13540 EXPECT_EQ(OK, callback1.WaitForResult());
13541 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13542
13543 // Now, start the HTTP request
13544 HttpRequestInfo request2;
13545 request2.method = "GET";
13546 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1713547 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013548 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713549 TestCompletionCallback callback2;
13550 EXPECT_EQ(ERR_IO_PENDING,
13551 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413552 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1713553 data2->RunFor(3);
13554
13555 ASSERT_TRUE(callback2.have_result());
13556 EXPECT_EQ(OK, callback2.WaitForResult());
13557 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13558}
13559
[email protected]85f97342013-04-17 06:12:2413560// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
13561// error) in SPDY session, removes the socket from pool and closes the SPDY
13562// session. Verify that new url's from the same HttpNetworkSession (and a new
13563// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0213564TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2313565 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2413566
13567 MockRead reads1[] = {
13568 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
13569 };
13570
mmenke11eb5152015-06-09 14:50:5013571 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2413572
[email protected]cdf8f7e72013-05-23 10:56:4613573 scoped_ptr<SpdyFrame> req2(
13574 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2413575 MockWrite writes2[] = {
13576 CreateMockWrite(*req2, 0),
13577 };
13578
[email protected]23e482282013-06-14 16:08:0213579 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13580 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2413581 MockRead reads2[] = {
13582 CreateMockRead(*resp2, 1),
13583 CreateMockRead(*body2, 2),
13584 MockRead(ASYNC, OK, 3) // EOF
13585 };
13586
mmenke11eb5152015-06-09 14:50:5013587 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13588 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2413589
[email protected]85f97342013-04-17 06:12:2413590 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813591 ssl1.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5013592 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13593 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2413594
13595 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813596 ssl2.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5013597 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13598 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2413599
mmenkee65e7af2015-10-13 17:16:4213600 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5013601 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2413602
13603 // Start the first transaction to set up the SpdySession and verify that
13604 // connection was closed.
13605 HttpRequestInfo request1;
13606 request1.method = "GET";
13607 request1.url = GURL(https_url);
13608 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013609 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413610 TestCompletionCallback callback1;
13611 EXPECT_EQ(ERR_IO_PENDING,
13612 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2413613 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
13614
13615 // Now, start the second request and make sure it succeeds.
13616 HttpRequestInfo request2;
13617 request2.method = "GET";
13618 request2.url = GURL(https_url);
13619 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013620 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413621 TestCompletionCallback callback2;
13622 EXPECT_EQ(ERR_IO_PENDING,
13623 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2413624
mmenke11eb5152015-06-09 14:50:5013625 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2413626 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13627}
13628
[email protected]23e482282013-06-14 16:08:0213629TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2313630 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0313631 ClientSocketPoolManager::set_max_sockets_per_group(
13632 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13633 ClientSocketPoolManager::set_max_sockets_per_pool(
13634 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13635
13636 // Use two different hosts with different IPs so they don't get pooled.
13637 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
13638 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
mmenkee65e7af2015-10-13 17:16:4213639 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0313640
13641 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813642 ssl1.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0313643 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813644 ssl2.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0313645 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13646 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13647
[email protected]cdf8f7e72013-05-23 10:56:4613648 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0313649 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
13650 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1313651 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0313652 };
[email protected]23e482282013-06-14 16:08:0213653 scoped_ptr<SpdyFrame> host1_resp(
13654 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13655 scoped_ptr<SpdyFrame> host1_resp_body(
13656 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313657 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1313658 CreateMockRead(*host1_resp, 1),
13659 CreateMockRead(*host1_resp_body, 2),
13660 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313661 };
13662
rdsmithebb50aa2015-11-12 03:44:3813663 // Use a separate test instance for the separate SpdySession that will be
13664 // created.
13665 SpdyTestUtil spdy_util_2(GetProtocol(), GetDependenciesFromPriority());
rch8e6c6c42015-05-01 14:05:1313666 scoped_ptr<SequencedSocketData> spdy1_data(
13667 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
13668 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0313669 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
13670
rdsmithebb50aa2015-11-12 03:44:3813671 scoped_ptr<SpdyFrame> host2_req(spdy_util_2.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0313672 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
13673 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1313674 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0313675 };
[email protected]23e482282013-06-14 16:08:0213676 scoped_ptr<SpdyFrame> host2_resp(
rdsmithebb50aa2015-11-12 03:44:3813677 spdy_util_2.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]23e482282013-06-14 16:08:0213678 scoped_ptr<SpdyFrame> host2_resp_body(
rdsmithebb50aa2015-11-12 03:44:3813679 spdy_util_2.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313680 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1313681 CreateMockRead(*host2_resp, 1),
13682 CreateMockRead(*host2_resp_body, 2),
13683 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313684 };
13685
rch8e6c6c42015-05-01 14:05:1313686 scoped_ptr<SequencedSocketData> spdy2_data(
13687 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
13688 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0313689 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
13690
13691 MockWrite http_write[] = {
13692 MockWrite("GET / HTTP/1.1\r\n"
13693 "Host: www.a.com\r\n"
13694 "Connection: keep-alive\r\n\r\n"),
13695 };
13696
13697 MockRead http_read[] = {
13698 MockRead("HTTP/1.1 200 OK\r\n"),
13699 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13700 MockRead("Content-Length: 6\r\n\r\n"),
13701 MockRead("hello!"),
13702 };
13703 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
13704 http_write, arraysize(http_write));
13705 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13706
13707 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4013708 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5313709 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313710 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613711 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313712
13713 TestCompletionCallback callback;
13714 HttpRequestInfo request1;
13715 request1.method = "GET";
13716 request1.url = GURL("https://www.a.com/");
13717 request1.load_flags = 0;
13718 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5013719 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313720
13721 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
13722 EXPECT_EQ(ERR_IO_PENDING, rv);
13723 EXPECT_EQ(OK, callback.WaitForResult());
13724
13725 const HttpResponseInfo* response = trans->GetResponseInfo();
13726 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013727 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0213728 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0313729 EXPECT_TRUE(response->was_fetched_via_spdy);
13730 EXPECT_TRUE(response->was_npn_negotiated);
13731
13732 std::string response_data;
13733 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13734 EXPECT_EQ("hello!", response_data);
13735 trans.reset();
13736 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613737 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313738
13739 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4013740 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5313741 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313742 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613743 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313744 HttpRequestInfo request2;
13745 request2.method = "GET";
13746 request2.url = GURL("https://www.b.com/");
13747 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013748 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313749
13750 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
13751 EXPECT_EQ(ERR_IO_PENDING, rv);
13752 EXPECT_EQ(OK, callback.WaitForResult());
13753
13754 response = trans->GetResponseInfo();
13755 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013756 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0213757 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0313758 EXPECT_TRUE(response->was_fetched_via_spdy);
13759 EXPECT_TRUE(response->was_npn_negotiated);
13760 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13761 EXPECT_EQ("hello!", response_data);
13762 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613763 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313764 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613765 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313766
13767 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4013768 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5313769 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313770 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613771 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0313772 HttpRequestInfo request3;
13773 request3.method = "GET";
13774 request3.url = GURL("http://www.a.com/");
13775 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013776 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313777
13778 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
13779 EXPECT_EQ(ERR_IO_PENDING, rv);
13780 EXPECT_EQ(OK, callback.WaitForResult());
13781
13782 response = trans->GetResponseInfo();
13783 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013784 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313785 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13786 EXPECT_FALSE(response->was_fetched_via_spdy);
13787 EXPECT_FALSE(response->was_npn_negotiated);
13788 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13789 EXPECT_EQ("hello!", response_data);
13790 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613791 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313792 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613793 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313794}
13795
[email protected]79e1fd62013-06-20 06:50:0413796TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
13797 HttpRequestInfo request;
13798 request.method = "GET";
bncce36dca22015-04-21 22:11:2313799 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413800 request.load_flags = 0;
13801
mmenkee65e7af2015-10-13 17:16:4213802 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413803 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113804 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413805
ttuttled9dbc652015-09-29 20:00:5913806 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413807 StaticSocketDataProvider data;
13808 data.set_connect_data(mock_connect);
13809 session_deps_.socket_factory->AddSocketDataProvider(&data);
13810
13811 TestCompletionCallback callback;
13812
13813 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13814 EXPECT_EQ(ERR_IO_PENDING, rv);
13815
13816 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5913817 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0413818
[email protected]79e1fd62013-06-20 06:50:0413819 // We don't care whether this succeeds or fails, but it shouldn't crash.
13820 HttpRequestHeaders request_headers;
13821 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713822
13823 ConnectionAttempts attempts;
13824 trans->GetConnectionAttempts(&attempts);
13825 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5913826 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
13827
13828 IPEndPoint endpoint;
13829 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
13830 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413831}
13832
13833TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
13834 HttpRequestInfo request;
13835 request.method = "GET";
bncce36dca22015-04-21 22:11:2313836 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413837 request.load_flags = 0;
13838
mmenkee65e7af2015-10-13 17:16:4213839 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413840 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113841 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413842
ttuttled9dbc652015-09-29 20:00:5913843 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413844 StaticSocketDataProvider data;
13845 data.set_connect_data(mock_connect);
13846 session_deps_.socket_factory->AddSocketDataProvider(&data);
13847
13848 TestCompletionCallback callback;
13849
13850 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13851 EXPECT_EQ(ERR_IO_PENDING, rv);
13852
13853 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5913854 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0413855
[email protected]79e1fd62013-06-20 06:50:0413856 // We don't care whether this succeeds or fails, but it shouldn't crash.
13857 HttpRequestHeaders request_headers;
13858 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713859
13860 ConnectionAttempts attempts;
13861 trans->GetConnectionAttempts(&attempts);
13862 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5913863 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
13864
13865 IPEndPoint endpoint;
13866 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
13867 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413868}
13869
13870TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
13871 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
mmenkee65e7af2015-10-13 17:16:4213876 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413877 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113878 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413879
13880 MockWrite data_writes[] = {
13881 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13882 };
13883 MockRead data_reads[] = {
13884 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13885 };
13886
13887 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13888 data_writes, arraysize(data_writes));
13889 session_deps_.socket_factory->AddSocketDataProvider(&data);
13890
13891 TestCompletionCallback callback;
13892
13893 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13894 EXPECT_EQ(ERR_IO_PENDING, rv);
13895
13896 rv = callback.WaitForResult();
13897 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13898
[email protected]79e1fd62013-06-20 06:50:0413899 HttpRequestHeaders request_headers;
13900 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13901 EXPECT_TRUE(request_headers.HasHeader("Host"));
13902}
13903
13904TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
13905 HttpRequestInfo request;
13906 request.method = "GET";
bncce36dca22015-04-21 22:11:2313907 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413908 request.load_flags = 0;
13909
mmenkee65e7af2015-10-13 17:16:4213910 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413911 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113912 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413913
13914 MockWrite data_writes[] = {
13915 MockWrite(ASYNC, ERR_CONNECTION_RESET),
13916 };
13917 MockRead data_reads[] = {
13918 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13919 };
13920
13921 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13922 data_writes, arraysize(data_writes));
13923 session_deps_.socket_factory->AddSocketDataProvider(&data);
13924
13925 TestCompletionCallback callback;
13926
13927 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13928 EXPECT_EQ(ERR_IO_PENDING, rv);
13929
13930 rv = callback.WaitForResult();
13931 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13932
[email protected]79e1fd62013-06-20 06:50:0413933 HttpRequestHeaders request_headers;
13934 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13935 EXPECT_TRUE(request_headers.HasHeader("Host"));
13936}
13937
13938TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
13939 HttpRequestInfo request;
13940 request.method = "GET";
bncce36dca22015-04-21 22:11:2313941 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413942 request.load_flags = 0;
13943
mmenkee65e7af2015-10-13 17:16:4213944 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413945 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113946 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413947
13948 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313949 MockWrite(
13950 "GET / HTTP/1.1\r\n"
13951 "Host: www.example.org\r\n"
13952 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413953 };
13954 MockRead data_reads[] = {
13955 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
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
13964 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13965 EXPECT_EQ(ERR_IO_PENDING, rv);
13966
13967 rv = callback.WaitForResult();
13968 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13969
[email protected]79e1fd62013-06-20 06:50:0413970 HttpRequestHeaders request_headers;
13971 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13972 EXPECT_TRUE(request_headers.HasHeader("Host"));
13973}
13974
13975TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
13976 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
mmenkee65e7af2015-10-13 17:16:4213981 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413982 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113983 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413984
13985 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313986 MockWrite(
13987 "GET / HTTP/1.1\r\n"
13988 "Host: www.example.org\r\n"
13989 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413990 };
13991 MockRead data_reads[] = {
13992 MockRead(ASYNC, ERR_CONNECTION_RESET),
13993 };
13994
13995 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13996 data_writes, arraysize(data_writes));
13997 session_deps_.socket_factory->AddSocketDataProvider(&data);
13998
13999 TestCompletionCallback callback;
14000
14001 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14002 EXPECT_EQ(ERR_IO_PENDING, rv);
14003
14004 rv = callback.WaitForResult();
14005 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14006
[email protected]79e1fd62013-06-20 06:50:0414007 HttpRequestHeaders request_headers;
14008 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14009 EXPECT_TRUE(request_headers.HasHeader("Host"));
14010}
14011
14012TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
14013 HttpRequestInfo request;
14014 request.method = "GET";
bncce36dca22015-04-21 22:11:2314015 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414016 request.load_flags = 0;
14017 request.extra_headers.SetHeader("X-Foo", "bar");
14018
mmenkee65e7af2015-10-13 17:16:4214019 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0414020 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114021 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414022
14023 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314024 MockWrite(
14025 "GET / HTTP/1.1\r\n"
14026 "Host: www.example.org\r\n"
14027 "Connection: keep-alive\r\n"
14028 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414029 };
14030 MockRead data_reads[] = {
14031 MockRead("HTTP/1.1 200 OK\r\n"
14032 "Content-Length: 5\r\n\r\n"
14033 "hello"),
14034 MockRead(ASYNC, ERR_UNEXPECTED),
14035 };
14036
14037 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14038 data_writes, arraysize(data_writes));
14039 session_deps_.socket_factory->AddSocketDataProvider(&data);
14040
14041 TestCompletionCallback callback;
14042
14043 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14044 EXPECT_EQ(ERR_IO_PENDING, rv);
14045
14046 rv = callback.WaitForResult();
14047 EXPECT_EQ(OK, rv);
14048
14049 HttpRequestHeaders request_headers;
14050 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14051 std::string foo;
14052 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14053 EXPECT_EQ("bar", foo);
14054}
14055
[email protected]bf828982013-08-14 18:01:4714056namespace {
14057
yhiranoa7e05bb2014-11-06 05:40:3914058// Fake HttpStream that simply records calls to SetPriority().
14059class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0314060 public base::SupportsWeakPtr<FakeStream> {
14061 public:
14062 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2014063 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0314064
14065 RequestPriority priority() const { return priority_; }
14066
dchengb03027d2014-10-21 12:00:2014067 int InitializeStream(const HttpRequestInfo* request_info,
14068 RequestPriority priority,
14069 const BoundNetLog& net_log,
14070 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314071 return ERR_IO_PENDING;
14072 }
14073
dchengb03027d2014-10-21 12:00:2014074 int SendRequest(const HttpRequestHeaders& request_headers,
14075 HttpResponseInfo* response,
14076 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314077 ADD_FAILURE();
14078 return ERR_UNEXPECTED;
14079 }
14080
dchengb03027d2014-10-21 12:00:2014081 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314082 ADD_FAILURE();
14083 return ERR_UNEXPECTED;
14084 }
14085
dchengb03027d2014-10-21 12:00:2014086 int ReadResponseBody(IOBuffer* buf,
14087 int buf_len,
14088 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314089 ADD_FAILURE();
14090 return ERR_UNEXPECTED;
14091 }
14092
dchengb03027d2014-10-21 12:00:2014093 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0314094
dchengb03027d2014-10-21 12:00:2014095 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0314096 ADD_FAILURE();
14097 return false;
14098 }
14099
dchengb03027d2014-10-21 12:00:2014100 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0314101 ADD_FAILURE();
14102 return false;
14103 }
14104
dchengb03027d2014-10-21 12:00:2014105 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314106
mmenkebd84c392015-09-02 14:12:3414107 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314108
sclittle4de1bab92015-09-22 21:28:2414109 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914110 ADD_FAILURE();
14111 return 0;
14112 }
14113
sclittlebe1ccf62015-09-02 19:40:3614114 int64_t GetTotalSentBytes() const override {
14115 ADD_FAILURE();
14116 return 0;
14117 }
14118
dchengb03027d2014-10-21 12:00:2014119 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314120 ADD_FAILURE();
14121 return false;
14122 }
14123
dchengb03027d2014-10-21 12:00:2014124 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14125
14126 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314127 ADD_FAILURE();
14128 }
14129
ttuttled9dbc652015-09-29 20:00:5914130 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14131
dchengb03027d2014-10-21 12:00:2014132 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314133
dchengb03027d2014-10-21 12:00:2014134 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314135
yhiranoa7e05bb2014-11-06 05:40:3914136 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
14137
14138 HttpStream* RenewStreamForAuth() override { return NULL; }
14139
[email protected]e86839fd2013-08-14 18:29:0314140 private:
14141 RequestPriority priority_;
14142
14143 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14144};
14145
14146// Fake HttpStreamRequest that simply records calls to SetPriority()
14147// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714148class FakeStreamRequest : public HttpStreamRequest,
14149 public base::SupportsWeakPtr<FakeStreamRequest> {
14150 public:
[email protected]e86839fd2013-08-14 18:29:0314151 FakeStreamRequest(RequestPriority priority,
14152 HttpStreamRequest::Delegate* delegate)
14153 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414154 delegate_(delegate),
14155 websocket_stream_create_helper_(NULL) {}
14156
14157 FakeStreamRequest(RequestPriority priority,
14158 HttpStreamRequest::Delegate* delegate,
14159 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14160 : priority_(priority),
14161 delegate_(delegate),
14162 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314163
dchengb03027d2014-10-21 12:00:2014164 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714165
14166 RequestPriority priority() const { return priority_; }
14167
[email protected]831e4a32013-11-14 02:14:4414168 const WebSocketHandshakeStreamBase::CreateHelper*
14169 websocket_stream_create_helper() const {
14170 return websocket_stream_create_helper_;
14171 }
14172
[email protected]e86839fd2013-08-14 18:29:0314173 // Create a new FakeStream and pass it to the request's
14174 // delegate. Returns a weak pointer to the FakeStream.
14175 base::WeakPtr<FakeStream> FinishStreamRequest() {
14176 FakeStream* fake_stream = new FakeStream(priority_);
14177 // Do this before calling OnStreamReady() as OnStreamReady() may
14178 // immediately delete |fake_stream|.
14179 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14180 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14181 return weak_stream;
14182 }
14183
dchengb03027d2014-10-21 12:00:2014184 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714185 ADD_FAILURE();
14186 return ERR_UNEXPECTED;
14187 }
14188
dchengb03027d2014-10-21 12:00:2014189 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714190 ADD_FAILURE();
14191 return LoadState();
14192 }
14193
dchengb03027d2014-10-21 12:00:2014194 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714195
dchengb03027d2014-10-21 12:00:2014196 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714197
dchengb03027d2014-10-21 12:00:2014198 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714199
dchengb03027d2014-10-21 12:00:2014200 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714201
ttuttle1f2d7e92015-04-28 16:17:4714202 const ConnectionAttempts& connection_attempts() const override {
14203 static ConnectionAttempts no_attempts;
14204 return no_attempts;
14205 }
14206
[email protected]bf828982013-08-14 18:01:4714207 private:
14208 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314209 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414210 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714211
14212 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14213};
14214
14215// Fake HttpStreamFactory that vends FakeStreamRequests.
14216class FakeStreamFactory : public HttpStreamFactory {
14217 public:
14218 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014219 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714220
14221 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14222 // RequestStream() (which may be NULL if it was destroyed already).
14223 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14224 return last_stream_request_;
14225 }
14226
dchengb03027d2014-10-21 12:00:2014227 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14228 RequestPriority priority,
14229 const SSLConfig& server_ssl_config,
14230 const SSLConfig& proxy_ssl_config,
14231 HttpStreamRequest::Delegate* delegate,
14232 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314233 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714234 last_stream_request_ = fake_request->AsWeakPtr();
14235 return fake_request;
14236 }
14237
dchengb03027d2014-10-21 12:00:2014238 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714239 const HttpRequestInfo& info,
14240 RequestPriority priority,
14241 const SSLConfig& server_ssl_config,
14242 const SSLConfig& proxy_ssl_config,
14243 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614244 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1314245 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414246 FakeStreamRequest* fake_request =
14247 new FakeStreamRequest(priority, delegate, create_helper);
14248 last_stream_request_ = fake_request->AsWeakPtr();
14249 return fake_request;
[email protected]bf828982013-08-14 18:01:4714250 }
14251
dchengb03027d2014-10-21 12:00:2014252 void PreconnectStreams(int num_streams,
14253 const HttpRequestInfo& info,
dchengb03027d2014-10-21 12:00:2014254 const SSLConfig& server_ssl_config,
14255 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4714256 ADD_FAILURE();
14257 }
14258
dchengb03027d2014-10-21 12:00:2014259 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714260 ADD_FAILURE();
14261 return NULL;
14262 }
14263
14264 private:
14265 base::WeakPtr<FakeStreamRequest> last_stream_request_;
14266
14267 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
14268};
14269
Adam Rice425cf122015-01-19 06:18:2414270// TODO(ricea): Maybe unify this with the one in
14271// url_request_http_job_unittest.cc ?
14272class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
14273 public:
14274 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
14275 bool using_proxy)
14276 : state_(connection.release(), using_proxy) {}
14277
14278 // Fake implementation of HttpStreamBase methods.
14279 // This ends up being quite "real" because this object has to really send data
14280 // on the mock socket. It might be easier to use the real implementation, but
14281 // the fact that the WebSocket code is not compiled on iOS makes that
14282 // difficult.
14283 int InitializeStream(const HttpRequestInfo* request_info,
14284 RequestPriority priority,
14285 const BoundNetLog& net_log,
14286 const CompletionCallback& callback) override {
14287 state_.Initialize(request_info, priority, net_log, callback);
14288 return OK;
14289 }
14290
14291 int SendRequest(const HttpRequestHeaders& request_headers,
14292 HttpResponseInfo* response,
14293 const CompletionCallback& callback) override {
14294 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
14295 response, callback);
14296 }
14297
14298 int ReadResponseHeaders(const CompletionCallback& callback) override {
14299 return parser()->ReadResponseHeaders(callback);
14300 }
14301
14302 int ReadResponseBody(IOBuffer* buf,
14303 int buf_len,
14304 const CompletionCallback& callback) override {
14305 NOTREACHED();
14306 return ERR_IO_PENDING;
14307 }
14308
14309 void Close(bool not_reusable) override {
14310 if (parser())
14311 parser()->Close(true);
14312 }
14313
14314 bool IsResponseBodyComplete() const override {
14315 NOTREACHED();
14316 return false;
14317 }
14318
Adam Rice425cf122015-01-19 06:18:2414319 bool IsConnectionReused() const override {
14320 NOTREACHED();
14321 return false;
14322 }
14323 void SetConnectionReused() override { NOTREACHED(); }
14324
mmenkebd84c392015-09-02 14:12:3414325 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2414326
sclittle4de1bab92015-09-22 21:28:2414327 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2414328 NOTREACHED();
14329 return 0;
14330 }
14331
sclittlebe1ccf62015-09-02 19:40:3614332 int64_t GetTotalSentBytes() const override {
14333 NOTREACHED();
14334 return 0;
14335 }
14336
Adam Rice425cf122015-01-19 06:18:2414337 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
14338 NOTREACHED();
14339 return false;
14340 }
14341
Adam Ricecb76ac62015-02-20 05:33:2514342 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2414343
14344 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
14345 NOTREACHED();
14346 }
14347
ttuttled9dbc652015-09-29 20:00:5914348 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14349
Adam Rice425cf122015-01-19 06:18:2414350 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
14351
14352 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
14353
14354 UploadProgress GetUploadProgress() const override {
14355 NOTREACHED();
14356 return UploadProgress();
14357 }
14358
14359 HttpStream* RenewStreamForAuth() override {
14360 NOTREACHED();
14361 return nullptr;
14362 }
14363
14364 // Fake implementation of WebSocketHandshakeStreamBase method(s)
14365 scoped_ptr<WebSocketStream> Upgrade() override {
14366 NOTREACHED();
14367 return scoped_ptr<WebSocketStream>();
14368 }
14369
14370 private:
14371 HttpStreamParser* parser() const { return state_.parser(); }
14372 HttpBasicState state_;
14373
14374 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
14375};
14376
[email protected]831e4a32013-11-14 02:14:4414377// TODO(yhirano): Split this class out into a net/websockets file, if it is
14378// worth doing.
14379class FakeWebSocketStreamCreateHelper :
14380 public WebSocketHandshakeStreamBase::CreateHelper {
14381 public:
dchengb03027d2014-10-21 12:00:2014382 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2114383 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1314384 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2414385 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
14386 using_proxy);
[email protected]831e4a32013-11-14 02:14:4414387 }
14388
dchengb03027d2014-10-21 12:00:2014389 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4414390 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1314391 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4414392 NOTREACHED();
14393 return NULL;
14394 };
14395
dchengb03027d2014-10-21 12:00:2014396 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4414397
14398 virtual scoped_ptr<WebSocketStream> Upgrade() {
14399 NOTREACHED();
14400 return scoped_ptr<WebSocketStream>();
14401 }
14402};
14403
[email protected]bf828982013-08-14 18:01:4714404} // namespace
14405
14406// Make sure that HttpNetworkTransaction passes on its priority to its
14407// stream request on start.
14408TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
mmenkee65e7af2015-10-13 17:16:4214409 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14410 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714411 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4414412 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714413
dcheng48459ac22014-08-26 00:46:4114414 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714415
14416 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
14417
14418 HttpRequestInfo request;
14419 TestCompletionCallback callback;
14420 EXPECT_EQ(ERR_IO_PENDING,
14421 trans.Start(&request, callback.callback(), BoundNetLog()));
14422
14423 base::WeakPtr<FakeStreamRequest> fake_request =
14424 fake_factory->last_stream_request();
14425 ASSERT_TRUE(fake_request != NULL);
14426 EXPECT_EQ(LOW, fake_request->priority());
14427}
14428
14429// Make sure that HttpNetworkTransaction passes on its priority
14430// updates to its stream request.
14431TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
mmenkee65e7af2015-10-13 17:16:4214432 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14433 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714434 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4414435 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714436
dcheng48459ac22014-08-26 00:46:4114437 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714438
14439 HttpRequestInfo request;
14440 TestCompletionCallback callback;
14441 EXPECT_EQ(ERR_IO_PENDING,
14442 trans.Start(&request, callback.callback(), BoundNetLog()));
14443
14444 base::WeakPtr<FakeStreamRequest> fake_request =
14445 fake_factory->last_stream_request();
14446 ASSERT_TRUE(fake_request != NULL);
14447 EXPECT_EQ(LOW, fake_request->priority());
14448
14449 trans.SetPriority(LOWEST);
14450 ASSERT_TRUE(fake_request != NULL);
14451 EXPECT_EQ(LOWEST, fake_request->priority());
14452}
14453
[email protected]e86839fd2013-08-14 18:29:0314454// Make sure that HttpNetworkTransaction passes on its priority
14455// updates to its stream.
14456TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
mmenkee65e7af2015-10-13 17:16:4214457 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14458 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0314459 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4414460 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0314461
dcheng48459ac22014-08-26 00:46:4114462 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0314463
14464 HttpRequestInfo request;
14465 TestCompletionCallback callback;
14466 EXPECT_EQ(ERR_IO_PENDING,
14467 trans.Start(&request, callback.callback(), BoundNetLog()));
14468
14469 base::WeakPtr<FakeStreamRequest> fake_request =
14470 fake_factory->last_stream_request();
14471 ASSERT_TRUE(fake_request != NULL);
14472 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
14473 ASSERT_TRUE(fake_stream != NULL);
14474 EXPECT_EQ(LOW, fake_stream->priority());
14475
14476 trans.SetPriority(LOWEST);
14477 EXPECT_EQ(LOWEST, fake_stream->priority());
14478}
14479
[email protected]831e4a32013-11-14 02:14:4414480TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
14481 // The same logic needs to be tested for both ws: and wss: schemes, but this
14482 // test is already parameterised on NextProto, so it uses a loop to verify
14483 // that the different schemes work.
bncce36dca22015-04-21 22:11:2314484 std::string test_cases[] = {"ws://www.example.org/",
14485 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4414486 for (size_t i = 0; i < arraysize(test_cases); ++i) {
mmenkee65e7af2015-10-13 17:16:4214487 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14488 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4414489 FakeStreamFactory* fake_factory = new FakeStreamFactory();
14490 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2314491 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4414492 scoped_ptr<HttpStreamFactory>(fake_factory));
14493
dcheng48459ac22014-08-26 00:46:4114494 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4414495 trans.SetWebSocketHandshakeStreamCreateHelper(
14496 &websocket_stream_create_helper);
14497
14498 HttpRequestInfo request;
14499 TestCompletionCallback callback;
14500 request.method = "GET";
14501 request.url = GURL(test_cases[i]);
14502
14503 EXPECT_EQ(ERR_IO_PENDING,
14504 trans.Start(&request, callback.callback(), BoundNetLog()));
14505
14506 base::WeakPtr<FakeStreamRequest> fake_request =
14507 fake_factory->last_stream_request();
14508 ASSERT_TRUE(fake_request != NULL);
14509 EXPECT_EQ(&websocket_stream_create_helper,
14510 fake_request->websocket_stream_create_helper());
14511 }
14512}
14513
[email protected]043b68c82013-08-22 23:41:5214514// Tests that when a used socket is returned to the SSL socket pool, it's closed
14515// if the transport socket pool is stalled on the global socket limit.
14516TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
14517 ClientSocketPoolManager::set_max_sockets_per_group(
14518 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14519 ClientSocketPoolManager::set_max_sockets_per_pool(
14520 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14521
14522 // Set up SSL request.
14523
14524 HttpRequestInfo ssl_request;
14525 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2314526 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214527
14528 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2314529 MockWrite(
14530 "GET / HTTP/1.1\r\n"
14531 "Host: www.example.org\r\n"
14532 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214533 };
14534 MockRead ssl_reads[] = {
14535 MockRead("HTTP/1.1 200 OK\r\n"),
14536 MockRead("Content-Length: 11\r\n\r\n"),
14537 MockRead("hello world"),
14538 MockRead(SYNCHRONOUS, OK),
14539 };
14540 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
14541 ssl_writes, arraysize(ssl_writes));
14542 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14543
14544 SSLSocketDataProvider ssl(ASYNC, OK);
14545 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14546
14547 // Set up HTTP request.
14548
14549 HttpRequestInfo http_request;
14550 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314551 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214552
14553 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314554 MockWrite(
14555 "GET / HTTP/1.1\r\n"
14556 "Host: www.example.org\r\n"
14557 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214558 };
14559 MockRead http_reads[] = {
14560 MockRead("HTTP/1.1 200 OK\r\n"),
14561 MockRead("Content-Length: 7\r\n\r\n"),
14562 MockRead("falafel"),
14563 MockRead(SYNCHRONOUS, OK),
14564 };
14565 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14566 http_writes, arraysize(http_writes));
14567 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14568
mmenkee65e7af2015-10-13 17:16:4214569 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5214570
14571 // Start the SSL request.
14572 TestCompletionCallback ssl_callback;
14573 scoped_ptr<HttpTransaction> ssl_trans(
14574 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14575 ASSERT_EQ(ERR_IO_PENDING,
14576 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
14577 BoundNetLog()));
14578
14579 // Start the HTTP request. Pool should stall.
14580 TestCompletionCallback http_callback;
14581 scoped_ptr<HttpTransaction> http_trans(
14582 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14583 ASSERT_EQ(ERR_IO_PENDING,
14584 http_trans->Start(&http_request, http_callback.callback(),
14585 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4114586 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214587
14588 // Wait for response from SSL request.
14589 ASSERT_EQ(OK, ssl_callback.WaitForResult());
14590 std::string response_data;
14591 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
14592 EXPECT_EQ("hello world", response_data);
14593
14594 // The SSL socket should automatically be closed, so the HTTP request can
14595 // start.
dcheng48459ac22014-08-26 00:46:4114596 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
14597 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214598
14599 // The HTTP request can now complete.
14600 ASSERT_EQ(OK, http_callback.WaitForResult());
14601 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
14602 EXPECT_EQ("falafel", response_data);
14603
dcheng48459ac22014-08-26 00:46:4114604 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214605}
14606
14607// Tests that when a SSL connection is established but there's no corresponding
14608// request that needs it, the new socket is closed if the transport socket pool
14609// is stalled on the global socket limit.
14610TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
14611 ClientSocketPoolManager::set_max_sockets_per_group(
14612 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14613 ClientSocketPoolManager::set_max_sockets_per_pool(
14614 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14615
14616 // Set up an ssl request.
14617
14618 HttpRequestInfo ssl_request;
14619 ssl_request.method = "GET";
14620 ssl_request.url = GURL("https://www.foopy.com/");
14621
14622 // No data will be sent on the SSL socket.
14623 StaticSocketDataProvider ssl_data;
14624 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14625
14626 SSLSocketDataProvider ssl(ASYNC, OK);
14627 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14628
14629 // Set up HTTP request.
14630
14631 HttpRequestInfo http_request;
14632 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314633 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214634
14635 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314636 MockWrite(
14637 "GET / HTTP/1.1\r\n"
14638 "Host: www.example.org\r\n"
14639 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214640 };
14641 MockRead http_reads[] = {
14642 MockRead("HTTP/1.1 200 OK\r\n"),
14643 MockRead("Content-Length: 7\r\n\r\n"),
14644 MockRead("falafel"),
14645 MockRead(SYNCHRONOUS, OK),
14646 };
14647 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14648 http_writes, arraysize(http_writes));
14649 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14650
mmenkee65e7af2015-10-13 17:16:4214651 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5214652
14653 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
14654 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2914655 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
14656 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5214657 session->ssl_config_service()->GetSSLConfig(&ssl_config);
mmenked1205bd2015-07-15 22:26:3514658 http_stream_factory->PreconnectStreams(1, ssl_request, ssl_config,
14659 ssl_config);
dcheng48459ac22014-08-26 00:46:4114660 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214661
14662 // Start the HTTP request. Pool should stall.
14663 TestCompletionCallback http_callback;
14664 scoped_ptr<HttpTransaction> http_trans(
14665 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14666 ASSERT_EQ(ERR_IO_PENDING,
14667 http_trans->Start(&http_request, http_callback.callback(),
14668 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4114669 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214670
14671 // The SSL connection will automatically be closed once the connection is
14672 // established, to let the HTTP request start.
14673 ASSERT_EQ(OK, http_callback.WaitForResult());
14674 std::string response_data;
14675 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
14676 EXPECT_EQ("falafel", response_data);
14677
dcheng48459ac22014-08-26 00:46:4114678 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214679}
14680
[email protected]02d74a02014-04-23 18:10:5414681TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
olli.raula6df48b2a2015-11-26 07:40:2214682 std::vector<scoped_ptr<UploadElementReader>> element_readers;
14683 element_readers.push_back(
14684 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
14685 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5414686
14687 HttpRequestInfo request;
14688 request.method = "POST";
14689 request.url = GURL("http://www.foo.com/");
14690 request.upload_data_stream = &upload_data_stream;
14691 request.load_flags = 0;
14692
mmenkee65e7af2015-10-13 17:16:4214693 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414694 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114695 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414696 // Send headers successfully, but get an error while sending the body.
14697 MockWrite data_writes[] = {
14698 MockWrite("POST / HTTP/1.1\r\n"
14699 "Host: www.foo.com\r\n"
14700 "Connection: keep-alive\r\n"
14701 "Content-Length: 3\r\n\r\n"),
14702 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14703 };
14704
14705 MockRead data_reads[] = {
14706 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14707 MockRead("hello world"),
14708 MockRead(SYNCHRONOUS, OK),
14709 };
14710 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14711 arraysize(data_writes));
14712 session_deps_.socket_factory->AddSocketDataProvider(&data);
14713
14714 TestCompletionCallback callback;
14715
14716 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14717 EXPECT_EQ(ERR_IO_PENDING, rv);
14718
14719 rv = callback.WaitForResult();
14720 EXPECT_EQ(OK, rv);
14721
14722 const HttpResponseInfo* response = trans->GetResponseInfo();
14723 ASSERT_TRUE(response != NULL);
14724
14725 EXPECT_TRUE(response->headers.get() != NULL);
14726 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14727
14728 std::string response_data;
14729 rv = ReadTransaction(trans.get(), &response_data);
14730 EXPECT_EQ(OK, rv);
14731 EXPECT_EQ("hello world", response_data);
14732}
14733
14734// This test makes sure the retry logic doesn't trigger when reading an error
14735// response from a server that rejected a POST with a CONNECTION_RESET.
14736TEST_P(HttpNetworkTransactionTest,
14737 PostReadsErrorResponseAfterResetOnReusedSocket) {
mmenkee65e7af2015-10-13 17:16:4214738 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414739 MockWrite data_writes[] = {
14740 MockWrite("GET / HTTP/1.1\r\n"
14741 "Host: www.foo.com\r\n"
14742 "Connection: keep-alive\r\n\r\n"),
14743 MockWrite("POST / HTTP/1.1\r\n"
14744 "Host: www.foo.com\r\n"
14745 "Connection: keep-alive\r\n"
14746 "Content-Length: 3\r\n\r\n"),
14747 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14748 };
14749
14750 MockRead data_reads[] = {
14751 MockRead("HTTP/1.1 200 Peachy\r\n"
14752 "Content-Length: 14\r\n\r\n"),
14753 MockRead("first response"),
14754 MockRead("HTTP/1.1 400 Not OK\r\n"
14755 "Content-Length: 15\r\n\r\n"),
14756 MockRead("second response"),
14757 MockRead(SYNCHRONOUS, OK),
14758 };
14759 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14760 arraysize(data_writes));
14761 session_deps_.socket_factory->AddSocketDataProvider(&data);
14762
14763 TestCompletionCallback callback;
14764 HttpRequestInfo request1;
14765 request1.method = "GET";
14766 request1.url = GURL("http://www.foo.com/");
14767 request1.load_flags = 0;
14768
14769 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4114770 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414771 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
14772 EXPECT_EQ(ERR_IO_PENDING, rv);
14773
14774 rv = callback.WaitForResult();
14775 EXPECT_EQ(OK, rv);
14776
14777 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
14778 ASSERT_TRUE(response1 != NULL);
14779
14780 EXPECT_TRUE(response1->headers.get() != NULL);
14781 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
14782
14783 std::string response_data1;
14784 rv = ReadTransaction(trans1.get(), &response_data1);
14785 EXPECT_EQ(OK, rv);
14786 EXPECT_EQ("first response", response_data1);
14787 // Delete the transaction to release the socket back into the socket pool.
14788 trans1.reset();
14789
olli.raula6df48b2a2015-11-26 07:40:2214790 std::vector<scoped_ptr<UploadElementReader>> element_readers;
14791 element_readers.push_back(
14792 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
14793 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5414794
14795 HttpRequestInfo request2;
14796 request2.method = "POST";
14797 request2.url = GURL("http://www.foo.com/");
14798 request2.upload_data_stream = &upload_data_stream;
14799 request2.load_flags = 0;
14800
14801 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4114802 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414803 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
14804 EXPECT_EQ(ERR_IO_PENDING, rv);
14805
14806 rv = callback.WaitForResult();
14807 EXPECT_EQ(OK, rv);
14808
14809 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
14810 ASSERT_TRUE(response2 != NULL);
14811
14812 EXPECT_TRUE(response2->headers.get() != NULL);
14813 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
14814
14815 std::string response_data2;
14816 rv = ReadTransaction(trans2.get(), &response_data2);
14817 EXPECT_EQ(OK, rv);
14818 EXPECT_EQ("second response", response_data2);
14819}
14820
14821TEST_P(HttpNetworkTransactionTest,
14822 PostReadsErrorResponseAfterResetPartialBodySent) {
olli.raula6df48b2a2015-11-26 07:40:2214823 std::vector<scoped_ptr<UploadElementReader>> element_readers;
14824 element_readers.push_back(
14825 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
14826 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5414827
14828 HttpRequestInfo request;
14829 request.method = "POST";
14830 request.url = GURL("http://www.foo.com/");
14831 request.upload_data_stream = &upload_data_stream;
14832 request.load_flags = 0;
14833
mmenkee65e7af2015-10-13 17:16:4214834 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414835 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114836 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414837 // Send headers successfully, but get an error while sending the body.
14838 MockWrite data_writes[] = {
14839 MockWrite("POST / HTTP/1.1\r\n"
14840 "Host: www.foo.com\r\n"
14841 "Connection: keep-alive\r\n"
14842 "Content-Length: 3\r\n\r\n"
14843 "fo"),
14844 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14845 };
14846
14847 MockRead data_reads[] = {
14848 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14849 MockRead("hello world"),
14850 MockRead(SYNCHRONOUS, OK),
14851 };
14852 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14853 arraysize(data_writes));
14854 session_deps_.socket_factory->AddSocketDataProvider(&data);
14855
14856 TestCompletionCallback callback;
14857
14858 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14859 EXPECT_EQ(ERR_IO_PENDING, rv);
14860
14861 rv = callback.WaitForResult();
14862 EXPECT_EQ(OK, rv);
14863
14864 const HttpResponseInfo* response = trans->GetResponseInfo();
14865 ASSERT_TRUE(response != NULL);
14866
14867 EXPECT_TRUE(response->headers.get() != NULL);
14868 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14869
14870 std::string response_data;
14871 rv = ReadTransaction(trans.get(), &response_data);
14872 EXPECT_EQ(OK, rv);
14873 EXPECT_EQ("hello world", response_data);
14874}
14875
14876// This tests the more common case than the previous test, where headers and
14877// body are not merged into a single request.
14878TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0714879 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5414880
14881 HttpRequestInfo request;
14882 request.method = "POST";
14883 request.url = GURL("http://www.foo.com/");
14884 request.upload_data_stream = &upload_data_stream;
14885 request.load_flags = 0;
14886
mmenkee65e7af2015-10-13 17:16:4214887 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414888 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114889 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414890 // Send headers successfully, but get an error while sending the body.
14891 MockWrite data_writes[] = {
14892 MockWrite("POST / HTTP/1.1\r\n"
14893 "Host: www.foo.com\r\n"
14894 "Connection: keep-alive\r\n"
14895 "Transfer-Encoding: chunked\r\n\r\n"),
14896 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14897 };
14898
14899 MockRead data_reads[] = {
14900 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14901 MockRead("hello world"),
14902 MockRead(SYNCHRONOUS, OK),
14903 };
14904 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14905 arraysize(data_writes));
14906 session_deps_.socket_factory->AddSocketDataProvider(&data);
14907
14908 TestCompletionCallback callback;
14909
14910 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14911 EXPECT_EQ(ERR_IO_PENDING, rv);
14912 // Make sure the headers are sent before adding a chunk. This ensures that
14913 // they can't be merged with the body in a single send. Not currently
14914 // necessary since a chunked body is never merged with headers, but this makes
14915 // the test more future proof.
14916 base::RunLoop().RunUntilIdle();
14917
mmenkecbc2b712014-10-09 20:29:0714918 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5414919
14920 rv = callback.WaitForResult();
14921 EXPECT_EQ(OK, rv);
14922
14923 const HttpResponseInfo* response = trans->GetResponseInfo();
14924 ASSERT_TRUE(response != NULL);
14925
14926 EXPECT_TRUE(response->headers.get() != NULL);
14927 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14928
14929 std::string response_data;
14930 rv = ReadTransaction(trans.get(), &response_data);
14931 EXPECT_EQ(OK, rv);
14932 EXPECT_EQ("hello world", response_data);
14933}
14934
14935TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
olli.raula6df48b2a2015-11-26 07:40:2214936 std::vector<scoped_ptr<UploadElementReader>> element_readers;
14937 element_readers.push_back(
14938 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
14939 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5414940
14941 HttpRequestInfo request;
14942 request.method = "POST";
14943 request.url = GURL("http://www.foo.com/");
14944 request.upload_data_stream = &upload_data_stream;
14945 request.load_flags = 0;
14946
mmenkee65e7af2015-10-13 17:16:4214947 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414948 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114949 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414950
14951 MockWrite data_writes[] = {
14952 MockWrite("POST / HTTP/1.1\r\n"
14953 "Host: www.foo.com\r\n"
14954 "Connection: keep-alive\r\n"
14955 "Content-Length: 3\r\n\r\n"),
14956 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14957 };
14958
14959 MockRead data_reads[] = {
14960 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14961 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14962 MockRead("hello world"),
14963 MockRead(SYNCHRONOUS, OK),
14964 };
14965 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14966 arraysize(data_writes));
14967 session_deps_.socket_factory->AddSocketDataProvider(&data);
14968
14969 TestCompletionCallback callback;
14970
14971 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14972 EXPECT_EQ(ERR_IO_PENDING, rv);
14973
14974 rv = callback.WaitForResult();
14975 EXPECT_EQ(OK, rv);
14976
14977 const HttpResponseInfo* response = trans->GetResponseInfo();
14978 ASSERT_TRUE(response != NULL);
14979
14980 EXPECT_TRUE(response->headers.get() != NULL);
14981 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14982
14983 std::string response_data;
14984 rv = ReadTransaction(trans.get(), &response_data);
14985 EXPECT_EQ(OK, rv);
14986 EXPECT_EQ("hello world", response_data);
14987}
14988
14989TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
olli.raula6df48b2a2015-11-26 07:40:2214990 std::vector<scoped_ptr<UploadElementReader>> element_readers;
14991 element_readers.push_back(
14992 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
14993 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5414994
14995 HttpRequestInfo request;
14996 request.method = "POST";
14997 request.url = GURL("http://www.foo.com/");
14998 request.upload_data_stream = &upload_data_stream;
14999 request.load_flags = 0;
15000
mmenkee65e7af2015-10-13 17:16:4215001 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415002 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115003 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415004 // Send headers successfully, but get an error while sending the body.
15005 MockWrite data_writes[] = {
15006 MockWrite("POST / HTTP/1.1\r\n"
15007 "Host: www.foo.com\r\n"
15008 "Connection: keep-alive\r\n"
15009 "Content-Length: 3\r\n\r\n"),
15010 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15011 };
15012
15013 MockRead data_reads[] = {
15014 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15015 MockRead("hello world"),
15016 MockRead(SYNCHRONOUS, OK),
15017 };
15018 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15019 arraysize(data_writes));
15020 session_deps_.socket_factory->AddSocketDataProvider(&data);
15021
15022 TestCompletionCallback callback;
15023
15024 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15025 EXPECT_EQ(ERR_IO_PENDING, rv);
15026
15027 rv = callback.WaitForResult();
15028 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415029}
15030
15031TEST_P(HttpNetworkTransactionTest,
15032 PostIgnoresNonErrorResponseAfterResetAnd100) {
olli.raula6df48b2a2015-11-26 07:40:2215033 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15034 element_readers.push_back(
15035 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15036 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415037
15038 HttpRequestInfo request;
15039 request.method = "POST";
15040 request.url = GURL("http://www.foo.com/");
15041 request.upload_data_stream = &upload_data_stream;
15042 request.load_flags = 0;
15043
mmenkee65e7af2015-10-13 17:16:4215044 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415045 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115046 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415047 // Send headers successfully, but get an error while sending the body.
15048 MockWrite data_writes[] = {
15049 MockWrite("POST / HTTP/1.1\r\n"
15050 "Host: www.foo.com\r\n"
15051 "Connection: keep-alive\r\n"
15052 "Content-Length: 3\r\n\r\n"),
15053 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15054 };
15055
15056 MockRead data_reads[] = {
15057 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15058 MockRead("HTTP/1.0 302 Redirect\r\n"),
15059 MockRead("Location: http://somewhere-else.com/\r\n"),
15060 MockRead("Content-Length: 0\r\n\r\n"),
15061 MockRead(SYNCHRONOUS, OK),
15062 };
15063 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15064 arraysize(data_writes));
15065 session_deps_.socket_factory->AddSocketDataProvider(&data);
15066
15067 TestCompletionCallback callback;
15068
15069 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15070 EXPECT_EQ(ERR_IO_PENDING, rv);
15071
15072 rv = callback.WaitForResult();
15073 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415074}
15075
15076TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
olli.raula6df48b2a2015-11-26 07:40:2215077 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15078 element_readers.push_back(
15079 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15080 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415081
15082 HttpRequestInfo request;
15083 request.method = "POST";
15084 request.url = GURL("http://www.foo.com/");
15085 request.upload_data_stream = &upload_data_stream;
15086 request.load_flags = 0;
15087
mmenkee65e7af2015-10-13 17:16:4215088 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415089 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115090 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415091 // Send headers successfully, but get an error while sending the body.
15092 MockWrite data_writes[] = {
15093 MockWrite("POST / HTTP/1.1\r\n"
15094 "Host: www.foo.com\r\n"
15095 "Connection: keep-alive\r\n"
15096 "Content-Length: 3\r\n\r\n"),
15097 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15098 };
15099
15100 MockRead data_reads[] = {
15101 MockRead("HTTP 0.9 rocks!"),
15102 MockRead(SYNCHRONOUS, OK),
15103 };
15104 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15105 arraysize(data_writes));
15106 session_deps_.socket_factory->AddSocketDataProvider(&data);
15107
15108 TestCompletionCallback callback;
15109
15110 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15111 EXPECT_EQ(ERR_IO_PENDING, rv);
15112
15113 rv = callback.WaitForResult();
15114 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415115}
15116
15117TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
olli.raula6df48b2a2015-11-26 07:40:2215118 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15119 element_readers.push_back(
15120 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15121 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415122
15123 HttpRequestInfo request;
15124 request.method = "POST";
15125 request.url = GURL("http://www.foo.com/");
15126 request.upload_data_stream = &upload_data_stream;
15127 request.load_flags = 0;
15128
mmenkee65e7af2015-10-13 17:16:4215129 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415130 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115131 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415132 // Send headers successfully, but get an error while sending the body.
15133 MockWrite data_writes[] = {
15134 MockWrite("POST / HTTP/1.1\r\n"
15135 "Host: www.foo.com\r\n"
15136 "Connection: keep-alive\r\n"
15137 "Content-Length: 3\r\n\r\n"),
15138 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15139 };
15140
15141 MockRead data_reads[] = {
15142 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15143 MockRead(SYNCHRONOUS, OK),
15144 };
15145 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15146 arraysize(data_writes));
15147 session_deps_.socket_factory->AddSocketDataProvider(&data);
15148
15149 TestCompletionCallback callback;
15150
15151 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15152 EXPECT_EQ(ERR_IO_PENDING, rv);
15153
15154 rv = callback.WaitForResult();
15155 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415156}
15157
Adam Rice425cf122015-01-19 06:18:2415158// Verify that proxy headers are not sent to the destination server when
15159// establishing a tunnel for a secure WebSocket connection.
15160TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
15161 HttpRequestInfo request;
15162 request.method = "GET";
bncce36dca22015-04-21 22:11:2315163 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415164 AddWebSocketHeaders(&request.extra_headers);
15165
15166 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315167 session_deps_.proxy_service =
15168 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415169
mmenkee65e7af2015-10-13 17:16:4215170 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415171
15172 // Since a proxy is configured, try to establish a tunnel.
15173 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1715174 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15175 "Host: www.example.org:443\r\n"
15176 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415177
15178 // After calling trans->RestartWithAuth(), this is the request we should
15179 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1715180 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15181 "Host: www.example.org:443\r\n"
15182 "Proxy-Connection: keep-alive\r\n"
15183 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415184
rsleevidb16bb02015-11-12 23:47:1715185 MockWrite("GET / HTTP/1.1\r\n"
15186 "Host: www.example.org\r\n"
15187 "Connection: Upgrade\r\n"
15188 "Upgrade: websocket\r\n"
15189 "Origin: http://www.example.org\r\n"
15190 "Sec-WebSocket-Version: 13\r\n"
15191 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415192 };
15193
15194 // The proxy responds to the connect with a 407, using a persistent
15195 // connection.
15196 MockRead data_reads[] = {
15197 // No credentials.
15198 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15199 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415200 MockRead("Content-Length: 0\r\n"),
15201 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415202
15203 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15204
15205 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15206 MockRead("Upgrade: websocket\r\n"),
15207 MockRead("Connection: Upgrade\r\n"),
15208 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15209 };
15210
15211 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15212 arraysize(data_writes));
15213 session_deps_.socket_factory->AddSocketDataProvider(&data);
15214 SSLSocketDataProvider ssl(ASYNC, OK);
15215 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15216
15217 scoped_ptr<HttpTransaction> trans(
15218 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15219 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15220 trans->SetWebSocketHandshakeStreamCreateHelper(
15221 &websocket_stream_create_helper);
15222
15223 {
15224 TestCompletionCallback callback;
15225
15226 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15227 EXPECT_EQ(ERR_IO_PENDING, rv);
15228
15229 rv = callback.WaitForResult();
15230 EXPECT_EQ(OK, rv);
15231 }
15232
15233 const HttpResponseInfo* response = trans->GetResponseInfo();
15234 ASSERT_TRUE(response);
15235 ASSERT_TRUE(response->headers.get());
15236 EXPECT_EQ(407, response->headers->response_code());
15237
15238 {
15239 TestCompletionCallback callback;
15240
15241 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15242 callback.callback());
15243 EXPECT_EQ(ERR_IO_PENDING, rv);
15244
15245 rv = callback.WaitForResult();
15246 EXPECT_EQ(OK, rv);
15247 }
15248
15249 response = trans->GetResponseInfo();
15250 ASSERT_TRUE(response);
15251 ASSERT_TRUE(response->headers.get());
15252
15253 EXPECT_EQ(101, response->headers->response_code());
15254
15255 trans.reset();
15256 session->CloseAllConnections();
15257}
15258
15259// Verify that proxy headers are not sent to the destination server when
15260// establishing a tunnel for an insecure WebSocket connection.
15261// This requires the authentication info to be injected into the auth cache
15262// due to crbug.com/395064
15263// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
15264TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
15265 HttpRequestInfo request;
15266 request.method = "GET";
bncce36dca22015-04-21 22:11:2315267 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415268 AddWebSocketHeaders(&request.extra_headers);
15269
15270 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315271 session_deps_.proxy_service =
15272 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415273
mmenkee65e7af2015-10-13 17:16:4215274 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415275
15276 MockWrite data_writes[] = {
15277 // Try to establish a tunnel for the WebSocket connection, with
15278 // credentials. Because WebSockets have a separate set of socket pools,
15279 // they cannot and will not use the same TCP/IP connection as the
15280 // preflight HTTP request.
15281 MockWrite(
bncce36dca22015-04-21 22:11:2315282 "CONNECT www.example.org:80 HTTP/1.1\r\n"
15283 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2415284 "Proxy-Connection: keep-alive\r\n"
15285 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15286
15287 MockWrite(
15288 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315289 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415290 "Connection: Upgrade\r\n"
15291 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315292 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415293 "Sec-WebSocket-Version: 13\r\n"
15294 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
15295 };
15296
15297 MockRead data_reads[] = {
15298 // HTTP CONNECT with credentials.
15299 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15300
15301 // WebSocket connection established inside tunnel.
15302 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15303 MockRead("Upgrade: websocket\r\n"),
15304 MockRead("Connection: Upgrade\r\n"),
15305 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15306 };
15307
15308 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15309 arraysize(data_writes));
15310 session_deps_.socket_factory->AddSocketDataProvider(&data);
15311
15312 session->http_auth_cache()->Add(
15313 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
15314 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
15315
15316 scoped_ptr<HttpTransaction> trans(
15317 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15318 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15319 trans->SetWebSocketHandshakeStreamCreateHelper(
15320 &websocket_stream_create_helper);
15321
15322 TestCompletionCallback callback;
15323
15324 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15325 EXPECT_EQ(ERR_IO_PENDING, rv);
15326
15327 rv = callback.WaitForResult();
15328 EXPECT_EQ(OK, rv);
15329
15330 const HttpResponseInfo* response = trans->GetResponseInfo();
15331 ASSERT_TRUE(response);
15332 ASSERT_TRUE(response->headers.get());
15333
15334 EXPECT_EQ(101, response->headers->response_code());
15335
15336 trans.reset();
15337 session->CloseAllConnections();
15338}
15339
sclittlefb249892015-09-10 21:33:2215340TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
olli.raula6df48b2a2015-11-26 07:40:2215341 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15342 element_readers.push_back(
15343 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15344 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215345
15346 HttpRequestInfo request;
15347 request.method = "POST";
15348 request.url = GURL("http://www.foo.com/");
15349 request.upload_data_stream = &upload_data_stream;
15350
mmenkee65e7af2015-10-13 17:16:4215351 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2215352 scoped_ptr<HttpTransaction> trans(
15353 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15354 MockWrite data_writes[] = {
15355 MockWrite("POST / HTTP/1.1\r\n"
15356 "Host: www.foo.com\r\n"
15357 "Connection: keep-alive\r\n"
15358 "Content-Length: 3\r\n\r\n"),
15359 MockWrite("foo"),
15360 };
15361
15362 MockRead data_reads[] = {
15363 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15364 MockRead(SYNCHRONOUS, OK),
15365 };
15366 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15367 arraysize(data_writes));
15368 session_deps_.socket_factory->AddSocketDataProvider(&data);
15369
15370 TestCompletionCallback callback;
15371
15372 EXPECT_EQ(ERR_IO_PENDING,
15373 trans->Start(&request, callback.callback(), BoundNetLog()));
15374 EXPECT_EQ(OK, callback.WaitForResult());
15375
15376 std::string response_data;
15377 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15378
15379 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15380 trans->GetTotalSentBytes());
15381 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15382 trans->GetTotalReceivedBytes());
15383}
15384
15385TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
olli.raula6df48b2a2015-11-26 07:40:2215386 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15387 element_readers.push_back(
15388 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15389 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215390
15391 HttpRequestInfo request;
15392 request.method = "POST";
15393 request.url = GURL("http://www.foo.com/");
15394 request.upload_data_stream = &upload_data_stream;
15395
mmenkee65e7af2015-10-13 17:16:4215396 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2215397 scoped_ptr<HttpTransaction> trans(
15398 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15399 MockWrite data_writes[] = {
15400 MockWrite("POST / HTTP/1.1\r\n"
15401 "Host: www.foo.com\r\n"
15402 "Connection: keep-alive\r\n"
15403 "Content-Length: 3\r\n\r\n"),
15404 MockWrite("foo"),
15405 };
15406
15407 MockRead data_reads[] = {
15408 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
15409 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15410 MockRead(SYNCHRONOUS, OK),
15411 };
15412 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15413 arraysize(data_writes));
15414 session_deps_.socket_factory->AddSocketDataProvider(&data);
15415
15416 TestCompletionCallback callback;
15417
15418 EXPECT_EQ(ERR_IO_PENDING,
15419 trans->Start(&request, callback.callback(), BoundNetLog()));
15420 EXPECT_EQ(OK, callback.WaitForResult());
15421
15422 std::string response_data;
15423 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15424
15425 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15426 trans->GetTotalSentBytes());
15427 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15428 trans->GetTotalReceivedBytes());
15429}
15430
15431TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2215432 ChunkedUploadDataStream upload_data_stream(0);
15433
15434 HttpRequestInfo request;
15435 request.method = "POST";
15436 request.url = GURL("http://www.foo.com/");
15437 request.upload_data_stream = &upload_data_stream;
15438
mmenkee65e7af2015-10-13 17:16:4215439 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2215440 scoped_ptr<HttpTransaction> trans(
15441 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15442 // Send headers successfully, but get an error while sending the body.
15443 MockWrite data_writes[] = {
15444 MockWrite("POST / HTTP/1.1\r\n"
15445 "Host: www.foo.com\r\n"
15446 "Connection: keep-alive\r\n"
15447 "Transfer-Encoding: chunked\r\n\r\n"),
15448 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
15449 };
15450
15451 MockRead data_reads[] = {
15452 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15453 MockRead(SYNCHRONOUS, OK),
15454 };
15455 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15456 arraysize(data_writes));
15457 session_deps_.socket_factory->AddSocketDataProvider(&data);
15458
15459 TestCompletionCallback callback;
15460
15461 EXPECT_EQ(ERR_IO_PENDING,
15462 trans->Start(&request, callback.callback(), BoundNetLog()));
15463
15464 base::RunLoop().RunUntilIdle();
15465 upload_data_stream.AppendData("f", 1, false);
15466
15467 base::RunLoop().RunUntilIdle();
15468 upload_data_stream.AppendData("oo", 2, true);
15469
15470 EXPECT_EQ(OK, callback.WaitForResult());
15471
15472 std::string response_data;
15473 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15474
15475 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15476 trans->GetTotalSentBytes());
15477 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15478 trans->GetTotalReceivedBytes());
15479}
15480
bncf4588402015-11-24 13:33:1815481TEST_P(HttpNetworkTransactionTest, EnableNPN) {
15482 session_deps_.next_protos = NextProtosDefaults();
15483 session_deps_.enable_npn = true;
15484
15485 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15486 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15487
15488 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
15489 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
15490 EXPECT_THAT(trans.server_ssl_config_.npn_protos,
15491 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
15492}
15493
15494TEST_P(HttpNetworkTransactionTest, DisableNPN) {
15495 session_deps_.next_protos = NextProtosDefaults();
15496 session_deps_.enable_npn = false;
15497
15498 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15499 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15500
15501 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
15502 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
15503 EXPECT_TRUE(trans.server_ssl_config_.npn_protos.empty());
15504}
15505
[email protected]89ceba9a2009-03-21 03:46:0615506} // namespace net