blob: 84b758a4408d91e9df2c8a8395bb89a929273214 [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
sclittlebe1ccf62015-09-02 19:40:369#include <stdint.h>
danakj1fd259a02016-04-16 03:17:0910
avibf0746c2015-12-09 19:53:1411#include <limits>
danakj1fd259a02016-04-16 03:17:0912#include <memory>
rdsmith1d343be52016-10-21 20:37:5013#include <set>
[email protected]5285d972011-10-18 18:56:3414#include <string>
dchengc7eeda422015-12-26 03:56:4815#include <utility>
[email protected]95d88ffe2010-02-04 21:25:3316#include <vector>
[email protected]77848d12008-11-14 00:00:2217
[email protected]68bf9152008-09-25 19:47:3018#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5219#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2920#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5721#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2422#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4623#include "base/macros.h"
danakj1fd259a02016-04-16 03:17:0924#include "base/memory/ptr_util.h"
[email protected]bf828982013-08-14 18:01:4725#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4926#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4727#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0528#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3329#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3530#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3531#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0732#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3333#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0734#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2535#include "net/base/load_timing_info.h"
36#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2437#include "net/base/net_errors.h"
rdsmith1d343be52016-10-21 20:37:5038#include "net/base/network_throttle_manager.h"
tbansal28e68f82016-02-04 02:56:1539#include "net/base/proxy_delegate.h"
[email protected]ac790b42009-12-02 04:31:3140#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5241#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1542#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0643#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2144#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1145#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1646#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5347#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2448#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1249#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0050#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2951#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1952#include "net/http/http_auth_scheme.h"
Adam Rice425cf122015-01-19 06:18:2453#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5754#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5255#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5656#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2457#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1358#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5359#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5760#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3861#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2462#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1963#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0764#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0065#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1966#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5167#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4668#include "net/log/test_net_log_entry.h"
69#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1370#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5371#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0372#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1173#include "net/proxy/proxy_resolver.h"
tbansal28e68f82016-02-04 02:56:1574#include "net/proxy/proxy_server.h"
[email protected]631f1322010-04-30 17:59:1175#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4476#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1577#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0378#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4779#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0280#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0781#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4482#include "net/socket/socket_test_util.h"
83#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5484#include "net/spdy/spdy_framer.h"
85#include "net/spdy/spdy_session.h"
86#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0287#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1488#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5789#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0390#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5791#include "net/ssl/ssl_config_service_defaults.h"
92#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5493#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1194#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0195#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4396#include "net/test/test_data_directory.h"
[email protected]831e4a32013-11-14 02:14:4497#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:1898#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:5299#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15100#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27101#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52102
robpercival214763f2016-07-01 23:27:01103using net::test::IsError;
104using net::test::IsOk;
105
[email protected]ad65a3e2013-12-25 18:18:01106using base::ASCIIToUTF16;
107
initial.commit586acc5fe2008-07-26 22:42:52108//-----------------------------------------------------------------------------
109
ttuttle859dc7a2015-04-23 19:42:29110namespace net {
111
[email protected]13c8a092010-07-29 06:15:44112namespace {
113
rdsmith1d343be52016-10-21 20:37:50114class TestNetworkStreamThrottler : public NetworkThrottleManager {
115 public:
116 TestNetworkStreamThrottler()
117 : throttle_new_requests_(false),
118 num_set_priority_calls_(0),
119 last_priority_set_(IDLE) {}
120
121 ~TestNetworkStreamThrottler() override {
122 EXPECT_TRUE(outstanding_throttles_.empty());
123 }
124
125 // NetworkThrottleManager
126 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
127 RequestPriority priority,
128 bool ignore_limits) override {
129 std::unique_ptr<TestThrottle> test_throttle(
130 new TestThrottle(throttle_new_requests_, delegate, this));
131 outstanding_throttles_.insert(test_throttle.get());
132 return std::move(test_throttle);
133 }
134
135 void UnthrottleAllRequests() {
136 std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
137 for (auto& throttle : outstanding_throttles_copy) {
138 if (throttle->IsThrottled())
139 throttle->Unthrottle();
140 }
141 }
142
143 void set_throttle_new_requests(bool throttle_new_requests) {
144 throttle_new_requests_ = throttle_new_requests;
145 }
146
147 // Includes both throttled and unthrottled throttles.
148 size_t num_outstanding_requests() const {
149 return outstanding_throttles_.size();
150 }
151
152 int num_set_priority_calls() const { return num_set_priority_calls_; }
153 RequestPriority last_priority_set() const { return last_priority_set_; }
154 void set_priority_change_closure(
155 const base::Closure& priority_change_closure) {
156 priority_change_closure_ = priority_change_closure;
157 }
158
159 private:
160 class TestThrottle : public NetworkThrottleManager::Throttle {
161 public:
162 ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
163
164 // Throttle
165 bool IsThrottled() const override { return throttled_; }
166 void SetPriority(RequestPriority priority) override {
167 throttler_->SetPriorityCalled(priority);
168 }
169
170 TestThrottle(bool throttled,
171 ThrottleDelegate* delegate,
172 TestNetworkStreamThrottler* throttler)
173 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
174
175 void Unthrottle() {
176 EXPECT_TRUE(throttled_);
177
178 throttled_ = false;
179 delegate_->OnThrottleStateChanged();
180 }
181
182 bool throttled_;
183 ThrottleDelegate* delegate_;
184 TestNetworkStreamThrottler* throttler_;
185 };
186
187 void OnThrottleDestroyed(TestThrottle* throttle) {
188 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
189 outstanding_throttles_.erase(throttle);
190 }
191
192 void SetPriorityCalled(RequestPriority priority) {
193 ++num_set_priority_calls_;
194 last_priority_set_ = priority;
195 if (!priority_change_closure_.is_null())
196 priority_change_closure_.Run();
197 }
198
199 // Includes both throttled and unthrottled throttles.
200 std::set<TestThrottle*> outstanding_throttles_;
201 bool throttle_new_requests_;
202 int num_set_priority_calls_;
203 RequestPriority last_priority_set_;
204 base::Closure priority_change_closure_;
205
206 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
207};
208
[email protected]42cba2fb2013-03-29 19:58:57209const base::string16 kBar(ASCIIToUTF16("bar"));
210const base::string16 kBar2(ASCIIToUTF16("bar2"));
211const base::string16 kBar3(ASCIIToUTF16("bar3"));
212const base::string16 kBaz(ASCIIToUTF16("baz"));
213const base::string16 kFirst(ASCIIToUTF16("first"));
214const base::string16 kFoo(ASCIIToUTF16("foo"));
215const base::string16 kFoo2(ASCIIToUTF16("foo2"));
216const base::string16 kFoo3(ASCIIToUTF16("foo3"));
217const base::string16 kFou(ASCIIToUTF16("fou"));
218const base::string16 kSecond(ASCIIToUTF16("second"));
219const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
220const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44221
bnc2df4b522016-07-08 18:17:43222const char kAlternativeServiceHttpHeader[] =
223 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
224
ttuttle859dc7a2015-04-23 19:42:29225int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
226 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
227 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02228}
229
ttuttle859dc7a2015-04-23 19:42:29230int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
231 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
232 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02233}
234
ttuttle859dc7a2015-04-23 19:42:29235bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
236 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
237 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52238}
239
[email protected]f3da152d2012-06-02 01:00:57240// Takes in a Value created from a NetLogHttpResponseParameter, and returns
241// a JSONified list of headers as a single string. Uses single quotes instead
242// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27243bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57244 if (!params)
245 return false;
[email protected]ea5ef4c2013-06-13 22:50:27246 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57247 if (!params->GetList("headers", &header_list))
248 return false;
249 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34250 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28251 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57252 return true;
253}
254
[email protected]029c83b62013-01-24 05:28:20255// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
256// used.
ttuttle859dc7a2015-04-23 19:42:29257void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20258 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19259 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25260
[email protected]029c83b62013-01-24 05:28:20261 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
262 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
263
ttuttle859dc7a2015-04-23 19:42:29264 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20265 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25266
267 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25268
[email protected]3b23a222013-05-15 21:33:25269 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25270 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
271 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25272 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25273}
274
[email protected]029c83b62013-01-24 05:28:20275// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
276// used.
ttuttle859dc7a2015-04-23 19:42:29277void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25278 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20279 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19280 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20281
282 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
283 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
284
ttuttle859dc7a2015-04-23 19:42:29285 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
286 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20287 EXPECT_LE(load_timing_info.connect_timing.connect_end,
288 load_timing_info.send_start);
289
290 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20291
[email protected]3b23a222013-05-15 21:33:25292 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20293 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
294 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25295 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20296}
297
298// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
299// used.
ttuttle859dc7a2015-04-23 19:42:29300void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20301 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19302 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20303
ttuttle859dc7a2015-04-23 19:42:29304 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20305
306 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
307 EXPECT_LE(load_timing_info.proxy_resolve_start,
308 load_timing_info.proxy_resolve_end);
309 EXPECT_LE(load_timing_info.proxy_resolve_end,
310 load_timing_info.send_start);
311 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20312
[email protected]3b23a222013-05-15 21:33:25313 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20314 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
315 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25316 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20317}
318
319// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
320// used.
ttuttle859dc7a2015-04-23 19:42:29321void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20322 int connect_timing_flags) {
323 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19324 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20325
326 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
327 EXPECT_LE(load_timing_info.proxy_resolve_start,
328 load_timing_info.proxy_resolve_end);
329 EXPECT_LE(load_timing_info.proxy_resolve_end,
330 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29331 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
332 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20333 EXPECT_LE(load_timing_info.connect_timing.connect_end,
334 load_timing_info.send_start);
335
336 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20337
[email protected]3b23a222013-05-15 21:33:25338 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20339 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
340 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25341 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25342}
343
ttuttle859dc7a2015-04-23 19:42:29344void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24345 headers->SetHeader("Connection", "Upgrade");
346 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23347 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24348 headers->SetHeader("Sec-WebSocket-Version", "13");
349 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
350}
351
danakj1fd259a02016-04-16 03:17:09352std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42353 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34354 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14355}
356
rdsmith1d343be52016-10-21 20:37:50357// Note that the pointer written into |*throttler| will only be valid
358// for the lifetime of the returned HttpNetworkSession.
359std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
360 SpdySessionDependencies* session_deps,
361 TestNetworkStreamThrottler** throttler) {
362 std::unique_ptr<HttpNetworkSession> session(
363 SpdySessionDependencies::SpdyCreateSession(session_deps));
364
365 std::unique_ptr<TestNetworkStreamThrottler> owned_throttler(
366 new TestNetworkStreamThrottler);
367 *throttler = owned_throttler.get();
368
369 HttpNetworkSessionPeer peer(session.get());
370 peer.SetNetworkStreamThrottler(std::move(owned_throttler));
371
372 return session;
373}
374
[email protected]448d4ca52012-03-04 04:12:23375} // namespace
376
bncd16676a2016-07-20 16:23:01377class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03378 public:
bncd16676a2016-07-20 16:23:01379 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03380 // Important to restore the per-pool limit first, since the pool limit must
381 // always be greater than group limit, and the tests reduce both limits.
382 ClientSocketPoolManager::set_max_sockets_per_pool(
383 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
384 ClientSocketPoolManager::set_max_sockets_per_group(
385 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
386 }
387
[email protected]e3ceb682011-06-28 23:55:46388 protected:
[email protected]23e482282013-06-14 16:08:02389 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15390 : ssl_(ASYNC, OK),
391 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03392 HttpNetworkSession::NORMAL_SOCKET_POOL)),
393 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
394 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bncb26024382016-06-29 02:39:45395 session_deps_.enable_http2_alternative_service_with_different_host = true;
[email protected]483fa202013-05-14 01:07:03396 }
[email protected]bb88e1d32013-05-03 23:11:07397
[email protected]e3ceb682011-06-28 23:55:46398 struct SimpleGetHelperResult {
399 int rv;
400 std::string status_line;
401 std::string response_data;
sclittlefb249892015-09-10 21:33:22402 int64_t total_received_bytes;
403 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25404 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47405 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59406 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46407 };
408
dcheng67be2b1f2014-10-27 21:47:29409 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50410 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55411 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54412 }
413
dcheng67be2b1f2014-10-27 21:47:29414 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50415 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55416 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09417 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55418 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09419 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50420 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55421 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09422 }
423
[email protected]202965992011-12-07 23:04:51424 // Either |write_failure| specifies a write failure or |read_failure|
425 // specifies a read failure when using a reused socket. In either case, the
426 // failure should cause the network transaction to resend the request, and the
427 // other argument should be NULL.
428 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
429 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52430
[email protected]a34f61ee2014-03-18 20:59:49431 // Either |write_failure| specifies a write failure or |read_failure|
432 // specifies a read failure when using a reused socket. In either case, the
433 // failure should cause the network transaction to resend the request, and the
434 // other argument should be NULL.
435 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10436 const MockRead* read_failure,
437 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49438
[email protected]5a60c8b2011-10-19 20:14:29439 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
440 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15441 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52442
[email protected]ff007e162009-05-23 09:13:15443 HttpRequestInfo request;
444 request.method = "GET";
bncce36dca22015-04-21 22:11:23445 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:52446
vishal.b62985ca92015-04-17 08:45:51447 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07448 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09449 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16450 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27451
[email protected]5a60c8b2011-10-19 20:14:29452 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07453 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29454 }
initial.commit586acc5fe2008-07-26 22:42:52455
[email protected]49639fa2011-12-20 23:22:41456 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52457
eroman24bc6a12015-05-06 19:55:48458 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16459 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01460 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52461
[email protected]ff007e162009-05-23 09:13:15462 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16463 out.total_received_bytes = trans.GetTotalReceivedBytes();
464 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25465
466 // Even in the failure cases that use this function, connections are always
467 // successfully established before the error.
bnc691fda62016-08-12 00:43:16468 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25469 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
470
[email protected]ff007e162009-05-23 09:13:15471 if (out.rv != OK)
472 return out;
473
bnc691fda62016-08-12 00:43:16474 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50475 // Can't use ASSERT_* inside helper functions like this, so
476 // return an error.
wezca1070932016-05-26 20:30:52477 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50478 out.rv = ERR_UNEXPECTED;
479 return out;
480 }
[email protected]ff007e162009-05-23 09:13:15481 out.status_line = response->headers->GetStatusLine();
482
[email protected]80a09a82012-11-16 17:40:06483 EXPECT_EQ("127.0.0.1", response->socket_address.host());
484 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19485
ttuttled9dbc652015-09-29 20:00:59486 bool got_endpoint =
bnc691fda62016-08-12 00:43:16487 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59488 EXPECT_EQ(got_endpoint,
489 out.remote_endpoint_after_start.address().size() > 0);
490
bnc691fda62016-08-12 00:43:16491 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01492 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40493
mmenke43758e62015-05-04 21:09:46494 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40495 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39496 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00497 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
498 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39499 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00500 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
501 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15502
[email protected]f3da152d2012-06-02 01:00:57503 std::string line;
504 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
505 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
506
[email protected]79e1fd62013-06-20 06:50:04507 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16508 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04509 std::string value;
510 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23511 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04512 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
513 EXPECT_EQ("keep-alive", value);
514
515 std::string response_headers;
516 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23517 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04518 response_headers);
[email protected]3deb9a52010-11-11 00:24:40519
bnc691fda62016-08-12 00:43:16520 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22521 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16522 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22523
bnc691fda62016-08-12 00:43:16524 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47525 return out;
[email protected]ff007e162009-05-23 09:13:15526 }
initial.commit586acc5fe2008-07-26 22:42:52527
[email protected]5a60c8b2011-10-19 20:14:29528 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
529 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22530 MockWrite data_writes[] = {
531 MockWrite("GET / HTTP/1.1\r\n"
532 "Host: www.example.org\r\n"
533 "Connection: keep-alive\r\n\r\n"),
534 };
[email protected]5a60c8b2011-10-19 20:14:29535
sclittlefb249892015-09-10 21:33:22536 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
537 arraysize(data_writes));
538 StaticSocketDataProvider* data[] = {&reads};
539 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
540
541 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
542 out.total_sent_bytes);
543 return out;
[email protected]b8015c42013-12-24 15:18:19544 }
545
bnc032658ba2016-09-26 18:17:15546 void AddSSLSocketData() {
547 ssl_.next_proto = kProtoHTTP2;
548 ssl_.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
549 ASSERT_TRUE(ssl_.cert);
550 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
551 }
552
[email protected]ff007e162009-05-23 09:13:15553 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
554 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52555
[email protected]ff007e162009-05-23 09:13:15556 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07557
558 void BypassHostCacheOnRefreshHelper(int load_flags);
559
560 void CheckErrorIsPassedBack(int error, IoMode mode);
561
[email protected]4bd46222013-05-14 19:32:23562 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07563 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15564 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03565
566 // Original socket limits. Some tests set these. Safest to always restore
567 // them once each test has been run.
568 int old_max_group_sockets_;
569 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15570};
[email protected]231d5a32008-09-13 00:45:27571
[email protected]448d4ca52012-03-04 04:12:23572namespace {
573
ryansturm49a8cb12016-06-15 16:51:09574class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27575 public:
ryansturm49a8cb12016-06-15 16:51:09576 BeforeHeadersSentHandler()
577 : observed_before_headers_sent_with_proxy_(false),
578 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27579
ryansturm49a8cb12016-06-15 16:51:09580 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
581 HttpRequestHeaders* request_headers) {
582 observed_before_headers_sent_ = true;
583 if (!proxy_info.is_http() && !proxy_info.is_https() &&
584 !proxy_info.is_quic()) {
585 return;
586 }
587 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27588 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
589 }
590
ryansturm49a8cb12016-06-15 16:51:09591 bool observed_before_headers_sent_with_proxy() const {
592 return observed_before_headers_sent_with_proxy_;
593 }
594
595 bool observed_before_headers_sent() const {
596 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27597 }
598
599 std::string observed_proxy_server_uri() const {
600 return observed_proxy_server_uri_;
601 }
602
603 private:
ryansturm49a8cb12016-06-15 16:51:09604 bool observed_before_headers_sent_with_proxy_;
605 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27606 std::string observed_proxy_server_uri_;
607
ryansturm49a8cb12016-06-15 16:51:09608 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27609};
610
[email protected]15a5ccf82008-10-23 19:57:43611// Fill |str| with a long header list that consumes >= |size| bytes.
612void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51613 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19614 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
615 const int sizeof_row = strlen(row);
616 const int num_rows = static_cast<int>(
617 ceil(static_cast<float>(size) / sizeof_row));
618 const int sizeof_data = num_rows * sizeof_row;
619 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43620 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51621
[email protected]4ddaf2502008-10-23 18:26:19622 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43623 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19624}
625
thakis84dff942015-07-28 20:47:38626#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29627// Alternative functions that eliminate randomness and dependency on the local
628// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14629void MockGenerateRandom1(uint8_t* output, size_t n) {
630 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
631 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29632 static size_t current_byte = 0;
633 for (size_t i = 0; i < n; ++i) {
634 output[i] = bytes[current_byte++];
635 current_byte %= arraysize(bytes);
636 }
637}
638
avibf0746c2015-12-09 19:53:14639void MockGenerateRandom2(uint8_t* output, size_t n) {
640 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
641 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
642 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29643 static size_t current_byte = 0;
644 for (size_t i = 0; i < n; ++i) {
645 output[i] = bytes[current_byte++];
646 current_byte %= arraysize(bytes);
647 }
648}
649
[email protected]fe2bc6a2009-03-23 16:52:20650std::string MockGetHostName() {
651 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29652}
thakis84dff942015-07-28 20:47:38653#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29654
[email protected]e60e47a2010-07-14 03:37:18655template<typename ParentPool>
656class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31657 public:
[email protected]9e1bdd32011-02-03 21:48:34658 CaptureGroupNameSocketPool(HostResolver* host_resolver,
659 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18660
[email protected]d80a4322009-08-14 07:07:49661 const std::string last_group_name_received() const {
662 return last_group_name_;
663 }
664
dmichaeld6e570d2014-12-18 22:30:57665 int RequestSocket(const std::string& group_name,
666 const void* socket_params,
667 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15668 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57669 ClientSocketHandle* handle,
670 const CompletionCallback& callback,
tfarina428341112016-09-22 13:38:20671 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31672 last_group_name_ = group_name;
673 return ERR_IO_PENDING;
674 }
dmichaeld6e570d2014-12-18 22:30:57675 void CancelRequest(const std::string& group_name,
676 ClientSocketHandle* handle) override {}
677 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09678 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57679 int id) override {}
680 void CloseIdleSockets() override {}
681 int IdleSocketCount() const override { return 0; }
682 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31683 return 0;
684 }
dmichaeld6e570d2014-12-18 22:30:57685 LoadState GetLoadState(const std::string& group_name,
686 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31687 return LOAD_STATE_IDLE;
688 }
dmichaeld6e570d2014-12-18 22:30:57689 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26690 return base::TimeDelta();
691 }
[email protected]d80a4322009-08-14 07:07:49692
693 private:
[email protected]04e5be32009-06-26 20:00:31694 std::string last_group_name_;
695};
696
[email protected]ab739042011-04-07 15:22:28697typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
698CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13699typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
700CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06701typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11702CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18703typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
704CaptureGroupNameSSLSocketPool;
705
rkaplowd90695c2015-03-25 22:12:41706template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18707CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34708 HostResolver* host_resolver,
709 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21710 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18711
hashimoto0d3e4fb2015-01-09 05:02:50712template <>
[email protected]2df19bb2010-08-25 20:13:46713CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21714 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34715 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41716 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50717}
[email protected]2df19bb2010-08-25 20:13:46718
[email protected]007b3f82013-04-09 08:46:45719template <>
[email protected]e60e47a2010-07-14 03:37:18720CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21721 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34722 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45723 : SSLClientSocketPool(0,
724 0,
[email protected]007b3f82013-04-09 08:46:45725 cert_verifier,
726 NULL,
727 NULL,
[email protected]284303b62013-11-28 15:11:54728 NULL,
eranm6571b2b2014-12-03 15:53:23729 NULL,
[email protected]007b3f82013-04-09 08:46:45730 std::string(),
731 NULL,
732 NULL,
733 NULL,
734 NULL,
735 NULL,
[email protected]8e458552014-08-05 00:02:15736 NULL) {
737}
[email protected]2227c692010-05-04 15:36:11738
[email protected]231d5a32008-09-13 00:45:27739//-----------------------------------------------------------------------------
740
[email protected]79cb5c12011-09-12 13:12:04741// Helper functions for validating that AuthChallengeInfo's are correctly
742// configured for common cases.
743bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
744 if (!auth_challenge)
745 return false;
746 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43747 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04748 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19749 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04750 return true;
751}
752
753bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
754 if (!auth_challenge)
755 return false;
756 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43757 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
758 EXPECT_EQ("MyRealm1", auth_challenge->realm);
759 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
760 return true;
761}
762
763bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
764 if (!auth_challenge)
765 return false;
766 EXPECT_TRUE(auth_challenge->is_proxy);
767 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04768 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19769 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04770 return true;
771}
772
773bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
774 if (!auth_challenge)
775 return false;
776 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43777 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04778 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19779 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04780 return true;
781}
782
thakis84dff942015-07-28 20:47:38783#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04784bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
785 if (!auth_challenge)
786 return false;
787 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43788 EXPECT_EQ("http://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04789 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19790 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04791 return true;
792}
thakis84dff942015-07-28 20:47:38793#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04794
[email protected]448d4ca52012-03-04 04:12:23795} // namespace
796
bncd16676a2016-07-20 16:23:01797TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09798 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16799 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27800}
801
bncd16676a2016-07-20 16:23:01802TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27803 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35804 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
805 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06806 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27807 };
[email protected]31a2bfe2010-02-09 08:03:39808 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
809 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01810 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27811 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
812 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22813 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
814 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47815 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59816
817 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27818}
819
820// Response with no status line.
bncd16676a2016-07-20 16:23:01821TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27822 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35823 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06824 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27825 };
[email protected]31a2bfe2010-02-09 08:03:39826 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
827 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41828 EXPECT_THAT(out.rv, IsOk());
829 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
830 EXPECT_EQ("hello world", out.response_data);
831 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
832 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27833}
834
mmenkea7da6da2016-09-01 21:56:52835// Response with no status line, and a weird port. Should fail by default.
836TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
837 MockRead data_reads[] = {
838 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
839 };
840
841 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
842 session_deps_.socket_factory->AddSocketDataProvider(&data);
843
844 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
845
846 std::unique_ptr<HttpTransaction> trans(
847 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
848
849 HttpRequestInfo request;
850 request.method = "GET";
851 request.url = GURL("http://www.example.com:2000/");
852 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:20853 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52854 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
855}
856
857// Response with no status line, and a weird port. Option to allow weird ports
858// enabled.
859TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
860 MockRead data_reads[] = {
861 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
862 };
863
864 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
865 session_deps_.socket_factory->AddSocketDataProvider(&data);
866 session_deps_.http_09_on_non_default_ports_enabled = true;
867 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
868
869 std::unique_ptr<HttpTransaction> trans(
870 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
871
872 HttpRequestInfo request;
873 request.method = "GET";
874 request.url = GURL("http://www.example.com:2000/");
875 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:20876 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52877 EXPECT_THAT(callback.GetResult(rv), IsOk());
878
879 const HttpResponseInfo* info = trans->GetResponseInfo();
880 ASSERT_TRUE(info->headers);
881 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
882
883 // Don't bother to read the body - that's verified elsewhere, important thing
884 // is that the option to allow HTTP/0.9 on non-default ports is respected.
885}
886
[email protected]231d5a32008-09-13 00:45:27887// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01888TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27889 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35890 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06891 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27892 };
[email protected]31a2bfe2010-02-09 08:03:39893 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
894 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01895 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27896 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
897 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22898 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
899 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27900}
901
902// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01903TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27904 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35905 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06906 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27907 };
[email protected]31a2bfe2010-02-09 08:03:39908 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
909 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01910 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27911 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
912 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22913 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
914 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27915}
916
917// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01918TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27919 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35920 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06921 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27922 };
[email protected]31a2bfe2010-02-09 08:03:39923 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
924 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41925 EXPECT_THAT(out.rv, IsOk());
926 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
927 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
928 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
929 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27930}
931
932// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01933TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27934 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35935 MockRead("\n"),
936 MockRead("\n"),
937 MockRead("Q"),
938 MockRead("J"),
939 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06940 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27941 };
[email protected]31a2bfe2010-02-09 08:03:39942 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
943 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01944 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27945 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
946 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22947 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
948 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27949}
950
951// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01952TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27953 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35954 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06955 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27956 };
[email protected]31a2bfe2010-02-09 08:03:39957 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
958 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41959 EXPECT_THAT(out.rv, IsOk());
960 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
961 EXPECT_EQ("HTT", out.response_data);
962 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
963 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52964}
965
[email protected]f9d44aa2008-09-23 23:57:17966// Simulate a 204 response, lacking a Content-Length header, sent over a
967// persistent connection. The response should still terminate since a 204
968// cannot have a response body.
bncd16676a2016-07-20 16:23:01969TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19970 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17971 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35972 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19973 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06974 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17975 };
[email protected]31a2bfe2010-02-09 08:03:39976 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
977 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01978 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17979 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
980 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22981 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
982 int64_t response_size = reads_size - strlen(junk);
983 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17984}
985
[email protected]0877e3d2009-10-17 22:29:57986// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01987TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19988 std::string final_chunk = "0\r\n\r\n";
989 std::string extra_data = "HTTP/1.1 200 OK\r\n";
990 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57991 MockRead data_reads[] = {
992 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
993 MockRead("5\r\nHello\r\n"),
994 MockRead("1\r\n"),
995 MockRead(" \r\n"),
996 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19997 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06998 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57999 };
[email protected]31a2bfe2010-02-09 08:03:391000 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1001 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011002 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571003 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1004 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221005 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1006 int64_t response_size = reads_size - extra_data.size();
1007 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571008}
1009
[email protected]9fe44f52010-09-23 18:36:001010// Next tests deal with http://crbug.com/56344.
1011
bncd16676a2016-07-20 16:23:011012TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001013 MultipleContentLengthHeadersNoTransferEncoding) {
1014 MockRead data_reads[] = {
1015 MockRead("HTTP/1.1 200 OK\r\n"),
1016 MockRead("Content-Length: 10\r\n"),
1017 MockRead("Content-Length: 5\r\n\r\n"),
1018 };
1019 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1020 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011021 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001022}
1023
bncd16676a2016-07-20 16:23:011024TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041025 DuplicateContentLengthHeadersNoTransferEncoding) {
1026 MockRead data_reads[] = {
1027 MockRead("HTTP/1.1 200 OK\r\n"),
1028 MockRead("Content-Length: 5\r\n"),
1029 MockRead("Content-Length: 5\r\n\r\n"),
1030 MockRead("Hello"),
1031 };
1032 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1033 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011034 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041035 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1036 EXPECT_EQ("Hello", out.response_data);
1037}
1038
bncd16676a2016-07-20 16:23:011039TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041040 ComplexContentLengthHeadersNoTransferEncoding) {
1041 // More than 2 dupes.
1042 {
1043 MockRead data_reads[] = {
1044 MockRead("HTTP/1.1 200 OK\r\n"),
1045 MockRead("Content-Length: 5\r\n"),
1046 MockRead("Content-Length: 5\r\n"),
1047 MockRead("Content-Length: 5\r\n\r\n"),
1048 MockRead("Hello"),
1049 };
1050 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1051 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011052 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041053 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1054 EXPECT_EQ("Hello", out.response_data);
1055 }
1056 // HTTP/1.0
1057 {
1058 MockRead data_reads[] = {
1059 MockRead("HTTP/1.0 200 OK\r\n"),
1060 MockRead("Content-Length: 5\r\n"),
1061 MockRead("Content-Length: 5\r\n"),
1062 MockRead("Content-Length: 5\r\n\r\n"),
1063 MockRead("Hello"),
1064 };
1065 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1066 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011067 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041068 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1069 EXPECT_EQ("Hello", out.response_data);
1070 }
1071 // 2 dupes and one mismatched.
1072 {
1073 MockRead data_reads[] = {
1074 MockRead("HTTP/1.1 200 OK\r\n"),
1075 MockRead("Content-Length: 10\r\n"),
1076 MockRead("Content-Length: 10\r\n"),
1077 MockRead("Content-Length: 5\r\n\r\n"),
1078 };
1079 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1080 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011081 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041082 }
1083}
1084
bncd16676a2016-07-20 16:23:011085TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001086 MultipleContentLengthHeadersTransferEncoding) {
1087 MockRead data_reads[] = {
1088 MockRead("HTTP/1.1 200 OK\r\n"),
1089 MockRead("Content-Length: 666\r\n"),
1090 MockRead("Content-Length: 1337\r\n"),
1091 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1092 MockRead("5\r\nHello\r\n"),
1093 MockRead("1\r\n"),
1094 MockRead(" \r\n"),
1095 MockRead("5\r\nworld\r\n"),
1096 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061097 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001098 };
1099 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1100 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011101 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001102 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1103 EXPECT_EQ("Hello world", out.response_data);
1104}
1105
[email protected]1628fe92011-10-04 23:04:551106// Next tests deal with http://crbug.com/98895.
1107
1108// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011109TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551110 MockRead data_reads[] = {
1111 MockRead("HTTP/1.1 200 OK\r\n"),
1112 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1113 MockRead("Content-Length: 5\r\n\r\n"),
1114 MockRead("Hello"),
1115 };
1116 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1117 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011118 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551119 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1120 EXPECT_EQ("Hello", out.response_data);
1121}
1122
[email protected]54a9c6e52012-03-21 20:10:591123// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011124TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551125 MockRead data_reads[] = {
1126 MockRead("HTTP/1.1 200 OK\r\n"),
1127 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1128 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1129 MockRead("Content-Length: 5\r\n\r\n"),
1130 MockRead("Hello"),
1131 };
1132 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1133 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011134 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591135 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1136 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551137}
1138
1139// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011140TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551141 MockRead data_reads[] = {
1142 MockRead("HTTP/1.1 200 OK\r\n"),
1143 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1144 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1145 MockRead("Content-Length: 5\r\n\r\n"),
1146 MockRead("Hello"),
1147 };
1148 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1149 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011150 EXPECT_THAT(out.rv,
1151 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551152}
1153
[email protected]54a9c6e52012-03-21 20:10:591154// Checks that two identical Location headers result in no error.
1155// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011156TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551157 MockRead data_reads[] = {
1158 MockRead("HTTP/1.1 302 Redirect\r\n"),
1159 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591160 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551161 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061162 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551163 };
1164
1165 HttpRequestInfo request;
1166 request.method = "GET";
1167 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551168
danakj1fd259a02016-04-16 03:17:091169 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161170 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551171
1172 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071173 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551174
[email protected]49639fa2011-12-20 23:22:411175 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551176
tfarina428341112016-09-22 13:38:201177 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011178 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551179
robpercival214763f2016-07-01 23:27:011180 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551181
bnc691fda62016-08-12 00:43:161182 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521183 ASSERT_TRUE(response);
1184 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551185 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1186 std::string url;
1187 EXPECT_TRUE(response->headers->IsRedirect(&url));
1188 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471189 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551190}
1191
[email protected]1628fe92011-10-04 23:04:551192// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011193TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551194 MockRead data_reads[] = {
1195 MockRead("HTTP/1.1 302 Redirect\r\n"),
1196 MockRead("Location: http://good.com/\r\n"),
1197 MockRead("Location: http://evil.com/\r\n"),
1198 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061199 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551200 };
1201 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1202 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011203 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551204}
1205
[email protected]ef0faf2e72009-03-05 23:27:231206// Do a request using the HEAD method. Verify that we don't try to read the
1207// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011208TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421209 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231210 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231211 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231212
danakj1fd259a02016-04-16 03:17:091213 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161214 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091215 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161216 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091217 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1218 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271219
[email protected]ef0faf2e72009-03-05 23:27:231220 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131221 MockWrite("HEAD / HTTP/1.1\r\n"
1222 "Host: www.example.org\r\n"
1223 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231224 };
1225 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231226 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1227 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231228
mmenked39192ee2015-12-09 00:57:231229 // No response body because the test stops reading here.
1230 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231231 };
1232
[email protected]31a2bfe2010-02-09 08:03:391233 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1234 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071235 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231236
[email protected]49639fa2011-12-20 23:22:411237 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231238
tfarina428341112016-09-22 13:38:201239 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011240 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231241
1242 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011243 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231244
bnc691fda62016-08-12 00:43:161245 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521246 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231247
1248 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521249 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231250 EXPECT_EQ(1234, response->headers->GetContentLength());
1251 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471252 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091253 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1254 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231255
1256 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101257 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231258 bool has_server_header = response->headers->EnumerateHeader(
1259 &iter, "Server", &server_header);
1260 EXPECT_TRUE(has_server_header);
1261 EXPECT_EQ("Blah", server_header);
1262
1263 // Reading should give EOF right away, since there is no message body
1264 // (despite non-zero content-length).
1265 std::string response_data;
bnc691fda62016-08-12 00:43:161266 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011267 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231268 EXPECT_EQ("", response_data);
1269}
1270
bncd16676a2016-07-20 16:23:011271TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091272 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521273
1274 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351275 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1276 MockRead("hello"),
1277 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1278 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061279 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521280 };
[email protected]31a2bfe2010-02-09 08:03:391281 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071282 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521283
[email protected]0b0bf032010-09-21 18:08:501284 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521285 "hello", "world"
1286 };
1287
1288 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421289 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521290 request.method = "GET";
bncce36dca22015-04-21 22:11:231291 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521292
bnc691fda62016-08-12 00:43:161293 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271294
[email protected]49639fa2011-12-20 23:22:411295 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521296
tfarina428341112016-09-22 13:38:201297 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011298 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521299
1300 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011301 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521302
bnc691fda62016-08-12 00:43:161303 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521304 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521305
wezca1070932016-05-26 20:30:521306 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251307 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471308 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521309
1310 std::string response_data;
bnc691fda62016-08-12 00:43:161311 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011312 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251313 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521314 }
1315}
1316
bncd16676a2016-07-20 16:23:011317TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091318 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221319 element_readers.push_back(
ricea2deef682016-09-09 08:04:071320 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221321 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271322
[email protected]1c773ea12009-04-28 19:58:421323 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521324 request.method = "POST";
1325 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271326 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521327
shivanishab9a143952016-09-19 17:23:411328 // Check the upload progress returned before initialization is correct.
1329 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1330 EXPECT_EQ(0u, progress.size());
1331 EXPECT_EQ(0u, progress.position());
1332
danakj1fd259a02016-04-16 03:17:091333 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271335
initial.commit586acc5fe2008-07-26 22:42:521336 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351337 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1338 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1339 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061340 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521341 };
[email protected]31a2bfe2010-02-09 08:03:391342 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071343 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521344
[email protected]49639fa2011-12-20 23:22:411345 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521346
tfarina428341112016-09-22 13:38:201347 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011348 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521349
1350 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011351 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521352
bnc691fda62016-08-12 00:43:161353 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521354 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521355
wezca1070932016-05-26 20:30:521356 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251357 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521358
1359 std::string response_data;
bnc691fda62016-08-12 00:43:161360 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011361 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251362 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521363}
1364
[email protected]3a2d3662009-03-27 03:49:141365// This test is almost the same as Ignores100 above, but the response contains
1366// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571367// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011368TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421369 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141370 request.method = "GET";
1371 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141372
danakj1fd259a02016-04-16 03:17:091373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161374 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271375
[email protected]3a2d3662009-03-27 03:49:141376 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571377 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1378 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141379 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061380 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141381 };
[email protected]31a2bfe2010-02-09 08:03:391382 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071383 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141384
[email protected]49639fa2011-12-20 23:22:411385 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141386
tfarina428341112016-09-22 13:38:201387 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011388 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141389
1390 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011391 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141392
bnc691fda62016-08-12 00:43:161393 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521394 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141395
wezca1070932016-05-26 20:30:521396 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141397 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1398
1399 std::string response_data;
bnc691fda62016-08-12 00:43:161400 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011401 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141402 EXPECT_EQ("hello world", response_data);
1403}
1404
bncd16676a2016-07-20 16:23:011405TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081406 HttpRequestInfo request;
1407 request.method = "POST";
1408 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081409
danakj1fd259a02016-04-16 03:17:091410 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161411 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081412
1413 MockRead data_reads[] = {
1414 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1415 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381416 };
zmo9528c9f42015-08-04 22:12:081417 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1418 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381419
zmo9528c9f42015-08-04 22:12:081420 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381421
tfarina428341112016-09-22 13:38:201422 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011423 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381424
zmo9528c9f42015-08-04 22:12:081425 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011426 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381427
zmo9528c9f42015-08-04 22:12:081428 std::string response_data;
bnc691fda62016-08-12 00:43:161429 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011430 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081431 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381432}
1433
bncd16676a2016-07-20 16:23:011434TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381435 HttpRequestInfo request;
1436 request.method = "POST";
1437 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381438
danakj1fd259a02016-04-16 03:17:091439 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161440 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271441
[email protected]ee9410e72010-01-07 01:42:381442 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061443 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381444 };
[email protected]31a2bfe2010-02-09 08:03:391445 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071446 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381447
[email protected]49639fa2011-12-20 23:22:411448 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381449
tfarina428341112016-09-22 13:38:201450 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011451 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381452
1453 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011454 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381455}
1456
[email protected]23e482282013-06-14 16:08:021457void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511458 const MockWrite* write_failure,
1459 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421460 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521461 request.method = "GET";
1462 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521463
vishal.b62985ca92015-04-17 08:45:511464 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071465 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091466 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271467
[email protected]202965992011-12-07 23:04:511468 // Written data for successfully sending both requests.
1469 MockWrite data1_writes[] = {
1470 MockWrite("GET / HTTP/1.1\r\n"
1471 "Host: www.foo.com\r\n"
1472 "Connection: keep-alive\r\n\r\n"),
1473 MockWrite("GET / HTTP/1.1\r\n"
1474 "Host: www.foo.com\r\n"
1475 "Connection: keep-alive\r\n\r\n")
1476 };
1477
1478 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521479 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351480 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1481 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061482 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521483 };
[email protected]202965992011-12-07 23:04:511484
1485 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491486 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511487 data1_writes[1] = *write_failure;
1488 } else {
1489 ASSERT_TRUE(read_failure);
1490 data1_reads[2] = *read_failure;
1491 }
1492
1493 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1494 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071495 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521496
1497 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351498 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1499 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061500 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521501 };
[email protected]31a2bfe2010-02-09 08:03:391502 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071503 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521504
thestig9d3bb0c2015-01-24 00:49:511505 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521506 "hello", "world"
1507 };
1508
mikecironef22f9812016-10-04 03:40:191509 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521510 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411511 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521512
bnc691fda62016-08-12 00:43:161513 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521514
tfarina428341112016-09-22 13:38:201515 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521517
1518 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011519 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521520
[email protected]58e32bb2013-01-21 18:23:251521 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161522 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251523 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1524 if (i == 0) {
1525 first_socket_log_id = load_timing_info.socket_log_id;
1526 } else {
1527 // The second request should be using a new socket.
1528 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1529 }
1530
bnc691fda62016-08-12 00:43:161531 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521532 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521533
wezca1070932016-05-26 20:30:521534 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471535 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251536 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521537
1538 std::string response_data;
bnc691fda62016-08-12 00:43:161539 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011540 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251541 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521542 }
1543}
[email protected]3d2a59b2008-09-26 19:44:251544
[email protected]a34f61ee2014-03-18 20:59:491545void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1546 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101547 const MockRead* read_failure,
1548 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491549 HttpRequestInfo request;
1550 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101551 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491552
vishal.b62985ca92015-04-17 08:45:511553 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491554 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091555 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491556
[email protected]09356c652014-03-25 15:36:101557 SSLSocketDataProvider ssl1(ASYNC, OK);
1558 SSLSocketDataProvider ssl2(ASYNC, OK);
1559 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361560 ssl1.next_proto = kProtoHTTP2;
1561 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101562 }
1563 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1564 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491565
[email protected]09356c652014-03-25 15:36:101566 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411567 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491568 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411569 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151570 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411571 SpdySerializedFrame spdy_data(
1572 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491573
[email protected]09356c652014-03-25 15:36:101574 // HTTP/1.1 versions of the request and response.
1575 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1576 "Host: www.foo.com\r\n"
1577 "Connection: keep-alive\r\n\r\n";
1578 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1579 const char kHttpData[] = "hello";
1580
1581 std::vector<MockRead> data1_reads;
1582 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491583 if (write_failure) {
1584 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101585 data1_writes.push_back(*write_failure);
1586 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491587 } else {
1588 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101589 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411590 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101591 } else {
1592 data1_writes.push_back(MockWrite(kHttpRequest));
1593 }
1594 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491595 }
1596
[email protected]09356c652014-03-25 15:36:101597 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1598 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491599 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1600
[email protected]09356c652014-03-25 15:36:101601 std::vector<MockRead> data2_reads;
1602 std::vector<MockWrite> data2_writes;
1603
1604 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411605 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101606
bncdf80d44fd2016-07-15 20:27:411607 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1608 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101609 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1610 } else {
1611 data2_writes.push_back(
1612 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1613
1614 data2_reads.push_back(
1615 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1616 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1617 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1618 }
rch8e6c6c42015-05-01 14:05:131619 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1620 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491621 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1622
1623 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591624 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491625 // Wait for the preconnect to complete.
1626 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1627 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101628 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491629
1630 // Make the request.
1631 TestCompletionCallback callback;
1632
bnc691fda62016-08-12 00:43:161633 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491634
tfarina428341112016-09-22 13:38:201635 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011636 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491637
1638 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011639 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491640
1641 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161642 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101643 TestLoadTimingNotReused(
1644 load_timing_info,
1645 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491646
bnc691fda62016-08-12 00:43:161647 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521648 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491649
wezca1070932016-05-26 20:30:521650 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021651 if (response->was_fetched_via_spdy) {
1652 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1653 } else {
1654 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1655 }
[email protected]a34f61ee2014-03-18 20:59:491656
1657 std::string response_data;
bnc691fda62016-08-12 00:43:161658 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011659 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101660 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491661}
1662
bncd16676a2016-07-20 16:23:011663TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061664 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511665 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1666}
1667
bncd16676a2016-07-20 16:23:011668TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061669 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511670 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251671}
1672
bncd16676a2016-07-20 16:23:011673TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061674 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511675 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251676}
1677
[email protected]d58ceea82014-06-04 10:55:541678// Make sure that on a 408 response (Request Timeout), the request is retried,
1679// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011680TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541681 MockRead read_failure(SYNCHRONOUS,
1682 "HTTP/1.1 408 Request Timeout\r\n"
1683 "Connection: Keep-Alive\r\n"
1684 "Content-Length: 6\r\n\r\n"
1685 "Pickle");
1686 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1687}
1688
bncd16676a2016-07-20 16:23:011689TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491690 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101691 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491692}
1693
bncd16676a2016-07-20 16:23:011694TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491695 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101696 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491697}
1698
bncd16676a2016-07-20 16:23:011699TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491700 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101701 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1702}
1703
bncd16676a2016-07-20 16:23:011704TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101705 MockRead read_failure(ASYNC, OK); // EOF
1706 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1707}
1708
[email protected]d58ceea82014-06-04 10:55:541709// Make sure that on a 408 response (Request Timeout), the request is retried,
1710// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011711TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541712 MockRead read_failure(SYNCHRONOUS,
1713 "HTTP/1.1 408 Request Timeout\r\n"
1714 "Connection: Keep-Alive\r\n"
1715 "Content-Length: 6\r\n\r\n"
1716 "Pickle");
1717 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1718 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1719}
1720
bncd16676a2016-07-20 16:23:011721TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101722 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1723 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1724}
1725
bncd16676a2016-07-20 16:23:011726TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101727 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1728 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1729}
1730
bncd16676a2016-07-20 16:23:011731TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101732 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1733 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1734}
1735
bncd16676a2016-07-20 16:23:011736TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101737 MockRead read_failure(ASYNC, OK); // EOF
1738 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491739}
1740
bncd16676a2016-07-20 16:23:011741TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421742 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251743 request.method = "GET";
bncce36dca22015-04-21 22:11:231744 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251745
danakj1fd259a02016-04-16 03:17:091746 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161747 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271748
[email protected]3d2a59b2008-09-26 19:44:251749 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061750 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351751 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1752 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061753 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251754 };
[email protected]31a2bfe2010-02-09 08:03:391755 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071756 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251757
[email protected]49639fa2011-12-20 23:22:411758 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251759
tfarina428341112016-09-22 13:38:201760 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011761 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251762
1763 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011764 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591765
1766 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161767 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591768 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251769}
1770
1771// What do various browsers do when the server closes a non-keepalive
1772// connection without sending any response header or body?
1773//
1774// IE7: error page
1775// Safari 3.1.2 (Windows): error page
1776// Firefox 3.0.1: blank page
1777// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421778// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1779// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011780TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251781 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061782 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351783 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1784 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061785 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251786 };
[email protected]31a2bfe2010-02-09 08:03:391787 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1788 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011789 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251790}
[email protected]1826a402014-01-08 15:40:481791
[email protected]7a5378b2012-11-04 03:25:171792// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1793// tests. There was a bug causing HttpNetworkTransaction to hang in the
1794// destructor in such situations.
1795// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011796TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171797 HttpRequestInfo request;
1798 request.method = "GET";
bncce36dca22015-04-21 22:11:231799 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171800
danakj1fd259a02016-04-16 03:17:091801 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161802 std::unique_ptr<HttpNetworkTransaction> 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("hello"),
1810 MockRead(SYNCHRONOUS, 0),
1811 };
1812 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071813 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171814
1815 TestCompletionCallback callback;
1816
tfarina428341112016-09-22 13:38:201817 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171819
1820 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011821 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171822
1823 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501824 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171825 if (rv == ERR_IO_PENDING)
1826 rv = callback.WaitForResult();
1827 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501828 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011829 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171830
1831 trans.reset();
fdoray92e35a72016-06-10 15:54:551832 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171833 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1834}
1835
bncd16676a2016-07-20 16:23:011836TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171837 HttpRequestInfo request;
1838 request.method = "GET";
bncce36dca22015-04-21 22:11:231839 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171840
danakj1fd259a02016-04-16 03:17:091841 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161842 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501843 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171844
1845 MockRead data_reads[] = {
1846 MockRead("HTTP/1.0 200 OK\r\n"),
1847 MockRead("Connection: keep-alive\r\n"),
1848 MockRead("Content-Length: 100\r\n\r\n"),
1849 MockRead(SYNCHRONOUS, 0),
1850 };
1851 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071852 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171853
1854 TestCompletionCallback callback;
1855
tfarina428341112016-09-22 13:38:201856 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011857 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171858
1859 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011860 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171861
1862 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501863 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171864 if (rv == ERR_IO_PENDING)
1865 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011866 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171867
1868 trans.reset();
fdoray92e35a72016-06-10 15:54:551869 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171870 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1871}
1872
[email protected]0b0bf032010-09-21 18:08:501873// Test that we correctly reuse a keep-alive connection after not explicitly
1874// reading the body.
bncd16676a2016-07-20 16:23:011875TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131876 HttpRequestInfo request;
1877 request.method = "GET";
1878 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:131879
vishal.b62985ca92015-04-17 08:45:511880 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071881 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091882 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271883
mmenkecc2298e2015-12-07 18:20:181884 const char* request_data =
1885 "GET / HTTP/1.1\r\n"
1886 "Host: www.foo.com\r\n"
1887 "Connection: keep-alive\r\n\r\n";
1888 MockWrite data_writes[] = {
1889 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1890 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1891 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1892 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1893 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1894 };
1895
[email protected]0b0bf032010-09-21 18:08:501896 // Note that because all these reads happen in the same
1897 // StaticSocketDataProvider, it shows that the same socket is being reused for
1898 // all transactions.
mmenkecc2298e2015-12-07 18:20:181899 MockRead data_reads[] = {
1900 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1901 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1902 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1903 MockRead(ASYNC, 7,
1904 "HTTP/1.1 302 Found\r\n"
1905 "Content-Length: 0\r\n\r\n"),
1906 MockRead(ASYNC, 9,
1907 "HTTP/1.1 302 Found\r\n"
1908 "Content-Length: 5\r\n\r\n"
1909 "hello"),
1910 MockRead(ASYNC, 11,
1911 "HTTP/1.1 301 Moved Permanently\r\n"
1912 "Content-Length: 0\r\n\r\n"),
1913 MockRead(ASYNC, 13,
1914 "HTTP/1.1 301 Moved Permanently\r\n"
1915 "Content-Length: 5\r\n\r\n"
1916 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131917
mmenkecc2298e2015-12-07 18:20:181918 // In the next two rounds, IsConnectedAndIdle returns false, due to
1919 // the set_busy_before_sync_reads(true) call, while the
1920 // HttpNetworkTransaction is being shut down, but the socket is still
1921 // reuseable. See http://crbug.com/544255.
1922 MockRead(ASYNC, 15,
1923 "HTTP/1.1 200 Hunky-Dory\r\n"
1924 "Content-Length: 5\r\n\r\n"),
1925 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131926
mmenkecc2298e2015-12-07 18:20:181927 MockRead(ASYNC, 18,
1928 "HTTP/1.1 200 Hunky-Dory\r\n"
1929 "Content-Length: 5\r\n\r\n"
1930 "he"),
1931 MockRead(SYNCHRONOUS, 19, "llo"),
1932
1933 // The body of the final request is actually read.
1934 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1935 MockRead(ASYNC, 22, "hello"),
1936 };
1937 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1938 arraysize(data_writes));
1939 data.set_busy_before_sync_reads(true);
1940 session_deps_.socket_factory->AddSocketDataProvider(&data);
1941
1942 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501943 std::string response_lines[kNumUnreadBodies];
1944
mikecironef22f9812016-10-04 03:40:191945 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181946 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411947 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131948
bnc691fda62016-08-12 00:43:161949 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501950 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131951
tfarina428341112016-09-22 13:38:201952 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011953 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:131954
[email protected]58e32bb2013-01-21 18:23:251955 LoadTimingInfo load_timing_info;
1956 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1957 if (i == 0) {
1958 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1959 first_socket_log_id = load_timing_info.socket_log_id;
1960 } else {
1961 TestLoadTimingReused(load_timing_info);
1962 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1963 }
1964
[email protected]fc31d6a42010-06-24 18:05:131965 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181966 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131967
mmenkecc2298e2015-12-07 18:20:181968 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501969 response_lines[i] = response->headers->GetStatusLine();
1970
mmenkecc2298e2015-12-07 18:20:181971 // Delete the transaction without reading the response bodies. Then spin
1972 // the message loop, so the response bodies are drained.
1973 trans.reset();
1974 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131975 }
[email protected]0b0bf032010-09-21 18:08:501976
1977 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181978 "HTTP/1.1 204 No Content",
1979 "HTTP/1.1 205 Reset Content",
1980 "HTTP/1.1 304 Not Modified",
1981 "HTTP/1.1 302 Found",
1982 "HTTP/1.1 302 Found",
1983 "HTTP/1.1 301 Moved Permanently",
1984 "HTTP/1.1 301 Moved Permanently",
1985 "HTTP/1.1 200 Hunky-Dory",
1986 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:501987 };
1988
mostynb91e0da982015-01-20 19:17:271989 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1990 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501991
1992 for (int i = 0; i < kNumUnreadBodies; ++i)
1993 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1994
[email protected]49639fa2011-12-20 23:22:411995 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161996 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:201997 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011998 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:161999 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182000 ASSERT_TRUE(response);
2001 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502002 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2003 std::string response_data;
bnc691fda62016-08-12 00:43:162004 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012005 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502006 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132007}
2008
mmenke5f94fda2016-06-02 20:54:132009// Sockets that receive extra data after a response is complete should not be
2010// reused.
bncd16676a2016-07-20 16:23:012011TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132012 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2013 MockWrite data_writes1[] = {
2014 MockWrite("HEAD / HTTP/1.1\r\n"
2015 "Host: www.borked.com\r\n"
2016 "Connection: keep-alive\r\n\r\n"),
2017 };
2018
2019 MockRead data_reads1[] = {
2020 MockRead("HTTP/1.1 200 OK\r\n"
2021 "Connection: keep-alive\r\n"
2022 "Content-Length: 22\r\n\r\n"
2023 "This server is borked."),
2024 };
2025
2026 MockWrite data_writes2[] = {
2027 MockWrite("GET /foo HTTP/1.1\r\n"
2028 "Host: www.borked.com\r\n"
2029 "Connection: keep-alive\r\n\r\n"),
2030 };
2031
2032 MockRead data_reads2[] = {
2033 MockRead("HTTP/1.1 200 OK\r\n"
2034 "Content-Length: 3\r\n\r\n"
2035 "foo"),
2036 };
2037 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2038 data_writes1, arraysize(data_writes1));
2039 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2040 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2041 data_writes2, arraysize(data_writes2));
2042 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2043
2044 TestCompletionCallback callback;
2045 HttpRequestInfo request1;
2046 request1.method = "HEAD";
2047 request1.url = GURL("http://www.borked.com/");
2048
bnc691fda62016-08-12 00:43:162049 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132050 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina428341112016-09-22 13:38:202051 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012052 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132053
2054 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2055 ASSERT_TRUE(response1);
2056 ASSERT_TRUE(response1->headers);
2057 EXPECT_EQ(200, response1->headers->response_code());
2058 EXPECT_TRUE(response1->headers->IsKeepAlive());
2059
2060 std::string response_data1;
robpercival214763f2016-07-01 23:27:012061 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132062 EXPECT_EQ("", response_data1);
2063 // Deleting the transaction attempts to release the socket back into the
2064 // socket pool.
2065 trans1.reset();
2066
2067 HttpRequestInfo request2;
2068 request2.method = "GET";
2069 request2.url = GURL("http://www.borked.com/foo");
2070
bnc691fda62016-08-12 00:43:162071 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132072 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina428341112016-09-22 13:38:202073 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012074 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132075
2076 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2077 ASSERT_TRUE(response2);
2078 ASSERT_TRUE(response2->headers);
2079 EXPECT_EQ(200, response2->headers->response_code());
2080
2081 std::string response_data2;
robpercival214763f2016-07-01 23:27:012082 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132083 EXPECT_EQ("foo", response_data2);
2084}
2085
bncd16676a2016-07-20 16:23:012086TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2088 MockWrite data_writes1[] = {
2089 MockWrite("GET / HTTP/1.1\r\n"
2090 "Host: www.borked.com\r\n"
2091 "Connection: keep-alive\r\n\r\n"),
2092 };
2093
2094 MockRead data_reads1[] = {
2095 MockRead("HTTP/1.1 200 OK\r\n"
2096 "Connection: keep-alive\r\n"
2097 "Content-Length: 22\r\n\r\n"
2098 "This server is borked."
2099 "Bonus data!"),
2100 };
2101
2102 MockWrite data_writes2[] = {
2103 MockWrite("GET /foo HTTP/1.1\r\n"
2104 "Host: www.borked.com\r\n"
2105 "Connection: keep-alive\r\n\r\n"),
2106 };
2107
2108 MockRead data_reads2[] = {
2109 MockRead("HTTP/1.1 200 OK\r\n"
2110 "Content-Length: 3\r\n\r\n"
2111 "foo"),
2112 };
2113 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2114 data_writes1, arraysize(data_writes1));
2115 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2116 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2117 data_writes2, arraysize(data_writes2));
2118 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2119
2120 TestCompletionCallback callback;
2121 HttpRequestInfo request1;
2122 request1.method = "GET";
2123 request1.url = GURL("http://www.borked.com/");
2124
bnc691fda62016-08-12 00:43:162125 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132126 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina428341112016-09-22 13:38:202127 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012128 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132129
2130 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2131 ASSERT_TRUE(response1);
2132 ASSERT_TRUE(response1->headers);
2133 EXPECT_EQ(200, response1->headers->response_code());
2134 EXPECT_TRUE(response1->headers->IsKeepAlive());
2135
2136 std::string response_data1;
robpercival214763f2016-07-01 23:27:012137 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132138 EXPECT_EQ("This server is borked.", response_data1);
2139 // Deleting the transaction attempts to release the socket back into the
2140 // socket pool.
2141 trans1.reset();
2142
2143 HttpRequestInfo request2;
2144 request2.method = "GET";
2145 request2.url = GURL("http://www.borked.com/foo");
2146
bnc691fda62016-08-12 00:43:162147 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132148 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina428341112016-09-22 13:38:202149 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012150 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132151
2152 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2153 ASSERT_TRUE(response2);
2154 ASSERT_TRUE(response2->headers);
2155 EXPECT_EQ(200, response2->headers->response_code());
2156
2157 std::string response_data2;
robpercival214763f2016-07-01 23:27:012158 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132159 EXPECT_EQ("foo", response_data2);
2160}
2161
bncd16676a2016-07-20 16:23:012162TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132163 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2164 MockWrite data_writes1[] = {
2165 MockWrite("GET / HTTP/1.1\r\n"
2166 "Host: www.borked.com\r\n"
2167 "Connection: keep-alive\r\n\r\n"),
2168 };
2169
2170 MockRead data_reads1[] = {
2171 MockRead("HTTP/1.1 200 OK\r\n"
2172 "Connection: keep-alive\r\n"
2173 "Transfer-Encoding: chunked\r\n\r\n"),
2174 MockRead("16\r\nThis server is borked.\r\n"),
2175 MockRead("0\r\n\r\nBonus data!"),
2176 };
2177
2178 MockWrite data_writes2[] = {
2179 MockWrite("GET /foo HTTP/1.1\r\n"
2180 "Host: www.borked.com\r\n"
2181 "Connection: keep-alive\r\n\r\n"),
2182 };
2183
2184 MockRead data_reads2[] = {
2185 MockRead("HTTP/1.1 200 OK\r\n"
2186 "Content-Length: 3\r\n\r\n"
2187 "foo"),
2188 };
2189 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2190 data_writes1, arraysize(data_writes1));
2191 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2192 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2193 data_writes2, arraysize(data_writes2));
2194 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2195
2196 TestCompletionCallback callback;
2197 HttpRequestInfo request1;
2198 request1.method = "GET";
2199 request1.url = GURL("http://www.borked.com/");
2200
bnc691fda62016-08-12 00:43:162201 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina428341112016-09-22 13:38:202203 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012204 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132205
2206 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2207 ASSERT_TRUE(response1);
2208 ASSERT_TRUE(response1->headers);
2209 EXPECT_EQ(200, response1->headers->response_code());
2210 EXPECT_TRUE(response1->headers->IsKeepAlive());
2211
2212 std::string response_data1;
robpercival214763f2016-07-01 23:27:012213 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132214 EXPECT_EQ("This server is borked.", response_data1);
2215 // Deleting the transaction attempts to release the socket back into the
2216 // socket pool.
2217 trans1.reset();
2218
2219 HttpRequestInfo request2;
2220 request2.method = "GET";
2221 request2.url = GURL("http://www.borked.com/foo");
2222
bnc691fda62016-08-12 00:43:162223 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132224 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina428341112016-09-22 13:38:202225 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012226 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132227
2228 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2229 ASSERT_TRUE(response2);
2230 ASSERT_TRUE(response2->headers);
2231 EXPECT_EQ(200, response2->headers->response_code());
2232
2233 std::string response_data2;
robpercival214763f2016-07-01 23:27:012234 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132235 EXPECT_EQ("foo", response_data2);
2236}
2237
2238// This is a little different from the others - it tests the case that the
2239// HttpStreamParser doesn't know if there's extra data on a socket or not when
2240// the HttpNetworkTransaction is torn down, because the response body hasn't
2241// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012242TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132243 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2244 MockWrite data_writes1[] = {
2245 MockWrite("GET / HTTP/1.1\r\n"
2246 "Host: www.borked.com\r\n"
2247 "Connection: keep-alive\r\n\r\n"),
2248 };
2249
2250 MockRead data_reads1[] = {
2251 MockRead("HTTP/1.1 200 OK\r\n"
2252 "Connection: keep-alive\r\n"
2253 "Transfer-Encoding: chunked\r\n\r\n"),
2254 MockRead("16\r\nThis server is borked.\r\n"),
2255 MockRead("0\r\n\r\nBonus data!"),
2256 };
2257 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2258 data_writes1, arraysize(data_writes1));
2259 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2260
2261 TestCompletionCallback callback;
2262 HttpRequestInfo request1;
2263 request1.method = "GET";
2264 request1.url = GURL("http://www.borked.com/");
2265
bnc691fda62016-08-12 00:43:162266 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132267 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina428341112016-09-22 13:38:202268 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012269 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132270
2271 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2272 ASSERT_TRUE(response1);
2273 ASSERT_TRUE(response1->headers);
2274 EXPECT_EQ(200, response1->headers->response_code());
2275 EXPECT_TRUE(response1->headers->IsKeepAlive());
2276
2277 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2278 // response body.
2279 trans1.reset();
2280
2281 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2282 // socket can't be reused, rather than returning it to the socket pool.
2283 base::RunLoop().RunUntilIdle();
2284
2285 // There should be no idle sockets in the pool.
2286 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2287}
2288
[email protected]038e9a32008-10-08 22:40:162289// Test the request-challenge-retry sequence for basic auth.
2290// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012291TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422292 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162293 request.method = "GET";
bncce36dca22015-04-21 22:11:232294 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162295
vishal.b62985ca92015-04-17 08:45:512296 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072297 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092298 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162299 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272300
[email protected]f9ee6b52008-11-08 06:46:232301 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232302 MockWrite(
2303 "GET / HTTP/1.1\r\n"
2304 "Host: www.example.org\r\n"
2305 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232306 };
2307
[email protected]038e9a32008-10-08 22:40:162308 MockRead data_reads1[] = {
2309 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2310 // Give a couple authenticate options (only the middle one is actually
2311 // supported).
[email protected]22927ad2009-09-21 19:56:192312 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162313 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2314 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2315 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2316 // Large content-length -- won't matter, as connection will be reset.
2317 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062318 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162319 };
2320
2321 // After calling trans->RestartWithAuth(), this is the request we should
2322 // be issuing -- the final header line contains the credentials.
2323 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232324 MockWrite(
2325 "GET / HTTP/1.1\r\n"
2326 "Host: www.example.org\r\n"
2327 "Connection: keep-alive\r\n"
2328 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162329 };
2330
2331 // Lastly, the server responds with the actual content.
2332 MockRead data_reads2[] = {
2333 MockRead("HTTP/1.0 200 OK\r\n"),
2334 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2335 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062336 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162337 };
2338
[email protected]31a2bfe2010-02-09 08:03:392339 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2340 data_writes1, arraysize(data_writes1));
2341 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2342 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072343 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2344 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162345
[email protected]49639fa2011-12-20 23:22:412346 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162347
tfarina428341112016-09-22 13:38:202348 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012349 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162350
2351 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012352 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162353
[email protected]58e32bb2013-01-21 18:23:252354 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162355 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252356 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2357
sclittlefb249892015-09-10 21:33:222358 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162359 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222360 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162361 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192362
bnc691fda62016-08-12 00:43:162363 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522364 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042365 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162366
[email protected]49639fa2011-12-20 23:22:412367 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162368
bnc691fda62016-08-12 00:43:162369 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012370 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162371
2372 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012373 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162374
[email protected]58e32bb2013-01-21 18:23:252375 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162376 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252377 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2378 // The load timing after restart should have a new socket ID, and times after
2379 // those of the first load timing.
2380 EXPECT_LE(load_timing_info1.receive_headers_end,
2381 load_timing_info2.connect_timing.connect_start);
2382 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2383
sclittlefb249892015-09-10 21:33:222384 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162385 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222386 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162387 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192388
bnc691fda62016-08-12 00:43:162389 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522390 ASSERT_TRUE(response);
2391 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162392 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162393}
2394
ttuttled9dbc652015-09-29 20:00:592395// Test the request-challenge-retry sequence for basic auth.
2396// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012397TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592398 HttpRequestInfo request;
2399 request.method = "GET";
2400 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592401
2402 TestNetLog log;
2403 MockHostResolver* resolver = new MockHostResolver();
2404 session_deps_.net_log = &log;
2405 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092406 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162407 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592408
2409 resolver->rules()->ClearRules();
2410 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2411
2412 MockWrite data_writes1[] = {
2413 MockWrite("GET / HTTP/1.1\r\n"
2414 "Host: www.example.org\r\n"
2415 "Connection: keep-alive\r\n\r\n"),
2416 };
2417
2418 MockRead data_reads1[] = {
2419 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2420 // Give a couple authenticate options (only the middle one is actually
2421 // supported).
2422 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2423 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2424 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2425 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2426 // Large content-length -- won't matter, as connection will be reset.
2427 MockRead("Content-Length: 10000\r\n\r\n"),
2428 MockRead(SYNCHRONOUS, ERR_FAILED),
2429 };
2430
2431 // After calling trans->RestartWithAuth(), this is the request we should
2432 // be issuing -- the final header line contains the credentials.
2433 MockWrite data_writes2[] = {
2434 MockWrite("GET / HTTP/1.1\r\n"
2435 "Host: www.example.org\r\n"
2436 "Connection: keep-alive\r\n"
2437 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2438 };
2439
2440 // Lastly, the server responds with the actual content.
2441 MockRead data_reads2[] = {
2442 MockRead("HTTP/1.0 200 OK\r\n"),
2443 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2444 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2445 };
2446
2447 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2448 data_writes1, arraysize(data_writes1));
2449 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2450 data_writes2, arraysize(data_writes2));
2451 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2452 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2453
2454 TestCompletionCallback callback1;
2455
bnc691fda62016-08-12 00:43:162456 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina428341112016-09-22 13:38:202457 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592458
2459 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162460 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592461 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2462
2463 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162464 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592465 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162466 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592467
bnc691fda62016-08-12 00:43:162468 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592469 ASSERT_TRUE(response);
2470 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2471
2472 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162473 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592474 ASSERT_FALSE(endpoint.address().empty());
2475 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2476
2477 resolver->rules()->ClearRules();
2478 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2479
2480 TestCompletionCallback callback2;
2481
bnc691fda62016-08-12 00:43:162482 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592483 AuthCredentials(kFoo, kBar), callback2.callback())));
2484
2485 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162486 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592487 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2488 // The load timing after restart should have a new socket ID, and times after
2489 // those of the first load timing.
2490 EXPECT_LE(load_timing_info1.receive_headers_end,
2491 load_timing_info2.connect_timing.connect_start);
2492 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2493
2494 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162495 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592496 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162497 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592498
bnc691fda62016-08-12 00:43:162499 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592500 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522501 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592502 EXPECT_EQ(100, response->headers->GetContentLength());
2503
bnc691fda62016-08-12 00:43:162504 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592505 ASSERT_FALSE(endpoint.address().empty());
2506 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2507}
2508
bncd16676a2016-07-20 16:23:012509TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462510 HttpRequestInfo request;
2511 request.method = "GET";
bncce36dca22015-04-21 22:11:232512 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292513 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462514
danakj1fd259a02016-04-16 03:17:092515 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162516 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272517
[email protected]861fcd52009-08-26 02:33:462518 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232519 MockWrite(
2520 "GET / HTTP/1.1\r\n"
2521 "Host: www.example.org\r\n"
2522 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462523 };
2524
2525 MockRead data_reads[] = {
2526 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2527 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2528 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2529 // Large content-length -- won't matter, as connection will be reset.
2530 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062531 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462532 };
2533
[email protected]31a2bfe2010-02-09 08:03:392534 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2535 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072536 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412537 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462538
tfarina428341112016-09-22 13:38:202539 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012540 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462541
2542 rv = callback.WaitForResult();
2543 EXPECT_EQ(0, rv);
2544
sclittlefb249892015-09-10 21:33:222545 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162546 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222547 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162548 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192549
bnc691fda62016-08-12 00:43:162550 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522551 ASSERT_TRUE(response);
2552 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462553}
2554
[email protected]2d2697f92009-02-18 21:00:322555// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2556// connection.
bncd16676a2016-07-20 16:23:012557TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182558 // On the second pass, the body read of the auth challenge is synchronous, so
2559 // IsConnectedAndIdle returns false. The socket should still be drained and
2560 // reused. See http://crbug.com/544255.
2561 for (int i = 0; i < 2; ++i) {
2562 HttpRequestInfo request;
2563 request.method = "GET";
2564 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322565
mmenkecc2298e2015-12-07 18:20:182566 TestNetLog log;
2567 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092568 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272569
mmenkecc2298e2015-12-07 18:20:182570 MockWrite data_writes[] = {
2571 MockWrite(ASYNC, 0,
2572 "GET / HTTP/1.1\r\n"
2573 "Host: www.example.org\r\n"
2574 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322575
bnc691fda62016-08-12 00:43:162576 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182577 // be issuing -- the final header line contains the credentials.
2578 MockWrite(ASYNC, 6,
2579 "GET / HTTP/1.1\r\n"
2580 "Host: www.example.org\r\n"
2581 "Connection: keep-alive\r\n"
2582 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2583 };
[email protected]2d2697f92009-02-18 21:00:322584
mmenkecc2298e2015-12-07 18:20:182585 MockRead data_reads[] = {
2586 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2587 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2588 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2589 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2590 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322591
mmenkecc2298e2015-12-07 18:20:182592 // Lastly, the server responds with the actual content.
2593 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2594 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2595 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2596 MockRead(ASYNC, 10, "Hello"),
2597 };
[email protected]2d2697f92009-02-18 21:00:322598
mmenkecc2298e2015-12-07 18:20:182599 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2600 arraysize(data_writes));
2601 data.set_busy_before_sync_reads(true);
2602 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462603
mmenkecc2298e2015-12-07 18:20:182604 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322605
bnc691fda62016-08-12 00:43:162606 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:202607 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012608 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322609
mmenkecc2298e2015-12-07 18:20:182610 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162611 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182612 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322613
bnc691fda62016-08-12 00:43:162614 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182615 ASSERT_TRUE(response);
2616 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322617
mmenkecc2298e2015-12-07 18:20:182618 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252619
bnc691fda62016-08-12 00:43:162620 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2621 callback2.callback());
robpercival214763f2016-07-01 23:27:012622 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322623
mmenkecc2298e2015-12-07 18:20:182624 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162625 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182626 TestLoadTimingReused(load_timing_info2);
2627 // The load timing after restart should have the same socket ID, and times
2628 // those of the first load timing.
2629 EXPECT_LE(load_timing_info1.receive_headers_end,
2630 load_timing_info2.send_start);
2631 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322632
bnc691fda62016-08-12 00:43:162633 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182634 ASSERT_TRUE(response);
2635 EXPECT_FALSE(response->auth_challenge);
2636 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322637
mmenkecc2298e2015-12-07 18:20:182638 std::string response_data;
bnc691fda62016-08-12 00:43:162639 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322640
mmenkecc2298e2015-12-07 18:20:182641 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162642 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182643 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162644 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182645 }
[email protected]2d2697f92009-02-18 21:00:322646}
2647
2648// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2649// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012650TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422651 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322652 request.method = "GET";
bncce36dca22015-04-21 22:11:232653 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322654
danakj1fd259a02016-04-16 03:17:092655 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272656
[email protected]2d2697f92009-02-18 21:00:322657 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162658 MockWrite("GET / HTTP/1.1\r\n"
2659 "Host: www.example.org\r\n"
2660 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322661
bnc691fda62016-08-12 00:43:162662 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232663 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162664 MockWrite("GET / HTTP/1.1\r\n"
2665 "Host: www.example.org\r\n"
2666 "Connection: keep-alive\r\n"
2667 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322668 };
2669
[email protected]2d2697f92009-02-18 21:00:322670 MockRead data_reads1[] = {
2671 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2672 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312673 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322674
2675 // Lastly, the server responds with the actual content.
2676 MockRead("HTTP/1.1 200 OK\r\n"),
2677 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502678 MockRead("Content-Length: 5\r\n\r\n"),
2679 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322680 };
2681
[email protected]2d0a4f92011-05-05 16:38:462682 // An incorrect reconnect would cause this to be read.
2683 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062684 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462685 };
2686
[email protected]31a2bfe2010-02-09 08:03:392687 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2688 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462689 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2690 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072691 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2692 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322693
[email protected]49639fa2011-12-20 23:22:412694 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322695
bnc691fda62016-08-12 00:43:162696 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:202697 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322699
2700 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012701 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322702
bnc691fda62016-08-12 00:43:162703 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522704 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042705 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322706
[email protected]49639fa2011-12-20 23:22:412707 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322708
bnc691fda62016-08-12 00:43:162709 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012710 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322711
2712 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012713 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322714
bnc691fda62016-08-12 00:43:162715 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522716 ASSERT_TRUE(response);
2717 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502718 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322719}
2720
2721// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2722// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012723TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422724 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322725 request.method = "GET";
bncce36dca22015-04-21 22:11:232726 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322727
danakj1fd259a02016-04-16 03:17:092728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272729
[email protected]2d2697f92009-02-18 21:00:322730 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162731 MockWrite("GET / HTTP/1.1\r\n"
2732 "Host: www.example.org\r\n"
2733 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322734
bnc691fda62016-08-12 00:43:162735 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232736 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162737 MockWrite("GET / HTTP/1.1\r\n"
2738 "Host: www.example.org\r\n"
2739 "Connection: keep-alive\r\n"
2740 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322741 };
2742
2743 // Respond with 5 kb of response body.
2744 std::string large_body_string("Unauthorized");
2745 large_body_string.append(5 * 1024, ' ');
2746 large_body_string.append("\r\n");
2747
2748 MockRead data_reads1[] = {
2749 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2750 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2751 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2752 // 5134 = 12 + 5 * 1024 + 2
2753 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062754 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322755
2756 // Lastly, the server responds with the actual content.
2757 MockRead("HTTP/1.1 200 OK\r\n"),
2758 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502759 MockRead("Content-Length: 5\r\n\r\n"),
2760 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322761 };
2762
[email protected]2d0a4f92011-05-05 16:38:462763 // An incorrect reconnect would cause this to be read.
2764 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062765 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462766 };
2767
[email protected]31a2bfe2010-02-09 08:03:392768 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2769 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462770 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2771 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072772 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2773 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322774
[email protected]49639fa2011-12-20 23:22:412775 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322776
bnc691fda62016-08-12 00:43:162777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:202778 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012779 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322780
2781 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012782 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322783
bnc691fda62016-08-12 00:43:162784 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522785 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042786 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322787
[email protected]49639fa2011-12-20 23:22:412788 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322789
bnc691fda62016-08-12 00:43:162790 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012791 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322792
2793 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012794 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322795
bnc691fda62016-08-12 00:43:162796 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522797 ASSERT_TRUE(response);
2798 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502799 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322800}
2801
2802// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312803// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012804TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312805 HttpRequestInfo request;
2806 request.method = "GET";
bncce36dca22015-04-21 22:11:232807 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312808
danakj1fd259a02016-04-16 03:17:092809 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272810
[email protected]11203f012009-11-12 23:02:312811 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232812 MockWrite(
2813 "GET / HTTP/1.1\r\n"
2814 "Host: www.example.org\r\n"
2815 "Connection: keep-alive\r\n\r\n"),
2816 // This simulates the seemingly successful write to a closed connection
2817 // if the bug is not fixed.
2818 MockWrite(
2819 "GET / HTTP/1.1\r\n"
2820 "Host: www.example.org\r\n"
2821 "Connection: keep-alive\r\n"
2822 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312823 };
2824
2825 MockRead data_reads1[] = {
2826 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2827 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2828 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2829 MockRead("Content-Length: 14\r\n\r\n"),
2830 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062831 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312832 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062833 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312834 };
2835
bnc691fda62016-08-12 00:43:162836 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312837 // be issuing -- the final header line contains the credentials.
2838 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232839 MockWrite(
2840 "GET / HTTP/1.1\r\n"
2841 "Host: www.example.org\r\n"
2842 "Connection: keep-alive\r\n"
2843 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312844 };
2845
2846 // Lastly, the server responds with the actual content.
2847 MockRead data_reads2[] = {
2848 MockRead("HTTP/1.1 200 OK\r\n"),
2849 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502850 MockRead("Content-Length: 5\r\n\r\n"),
2851 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312852 };
2853
[email protected]31a2bfe2010-02-09 08:03:392854 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2855 data_writes1, arraysize(data_writes1));
2856 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2857 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072858 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2859 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312860
[email protected]49639fa2011-12-20 23:22:412861 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312862
bnc691fda62016-08-12 00:43:162863 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:202864 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312866
2867 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012868 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312869
bnc691fda62016-08-12 00:43:162870 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522871 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042872 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312873
[email protected]49639fa2011-12-20 23:22:412874 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312875
bnc691fda62016-08-12 00:43:162876 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012877 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312878
2879 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012880 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312881
bnc691fda62016-08-12 00:43:162882 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522883 ASSERT_TRUE(response);
2884 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502885 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312886}
2887
[email protected]394816e92010-08-03 07:38:592888// Test the request-challenge-retry sequence for basic auth, over a connection
2889// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012890TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:012891 HttpRequestInfo request;
2892 request.method = "GET";
bncce36dca22015-04-21 22:11:232893 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012894 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292895 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012896
2897 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032898 session_deps_.proxy_service =
2899 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512900 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012901 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092902 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012903
2904 // Since we have proxy, should try to establish tunnel.
2905 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542906 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172907 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542908 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012909 };
2910
mmenkee71e15332015-10-07 16:39:542911 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012912 // connection.
2913 MockRead data_reads1[] = {
2914 // No credentials.
2915 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2916 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542917 };
ttuttle34f63b52015-03-05 04:33:012918
mmenkee71e15332015-10-07 16:39:542919 // Since the first connection couldn't be reused, need to establish another
2920 // once given credentials.
2921 MockWrite data_writes2[] = {
2922 // After calling trans->RestartWithAuth(), this is the request we should
2923 // be issuing -- the final header line contains the credentials.
2924 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172925 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542926 "Proxy-Connection: keep-alive\r\n"
2927 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2928
2929 MockWrite("GET / HTTP/1.1\r\n"
2930 "Host: www.example.org\r\n"
2931 "Connection: keep-alive\r\n\r\n"),
2932 };
2933
2934 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012935 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2936
2937 MockRead("HTTP/1.1 200 OK\r\n"),
2938 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2939 MockRead("Content-Length: 5\r\n\r\n"),
2940 MockRead(SYNCHRONOUS, "hello"),
2941 };
2942
2943 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2944 data_writes1, arraysize(data_writes1));
2945 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542946 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2947 data_writes2, arraysize(data_writes2));
2948 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012949 SSLSocketDataProvider ssl(ASYNC, OK);
2950 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2951
2952 TestCompletionCallback callback1;
2953
bnc691fda62016-08-12 00:43:162954 std::unique_ptr<HttpNetworkTransaction> trans(
ttuttle34f63b52015-03-05 04:33:012955 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2956
2957 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:012958 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012959
2960 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012961 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:462962 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012963 log.GetEntries(&entries);
2964 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002965 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2966 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012967 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002968 entries, pos,
2969 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2970 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012971
2972 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522973 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012974 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522975 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:012976 EXPECT_EQ(407, response->headers->response_code());
2977 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2978 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2979
2980 LoadTimingInfo load_timing_info;
2981 // CONNECT requests and responses are handled at the connect job level, so
2982 // the transaction does not yet have a connection.
2983 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2984
2985 TestCompletionCallback callback2;
2986
2987 rv =
2988 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012989 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012990
2991 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012992 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:012993
2994 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522995 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012996
2997 EXPECT_TRUE(response->headers->IsKeepAlive());
2998 EXPECT_EQ(200, response->headers->response_code());
2999 EXPECT_EQ(5, response->headers->GetContentLength());
3000 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3001
3002 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523003 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013004
3005 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3006 TestLoadTimingNotReusedWithPac(load_timing_info,
3007 CONNECT_TIMING_HAS_SSL_TIMES);
3008
3009 trans.reset();
3010 session->CloseAllConnections();
3011}
3012
3013// Test the request-challenge-retry sequence for basic auth, over a connection
3014// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013015TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593016 HttpRequestInfo request;
3017 request.method = "GET";
bncce36dca22015-04-21 22:11:233018 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593019 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293020 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593021
[email protected]cb9bf6ca2011-01-28 13:15:273022 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033023 session_deps_.proxy_service =
3024 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513025 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073026 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093027 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273028
[email protected]394816e92010-08-03 07:38:593029 // Since we have proxy, should try to establish tunnel.
3030 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543031 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173032 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543033 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113034 };
3035
mmenkee71e15332015-10-07 16:39:543036 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083037 // connection.
3038 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543039 // No credentials.
3040 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3041 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3042 MockRead("Proxy-Connection: close\r\n\r\n"),
3043 };
mmenkee0b5c882015-08-26 20:29:113044
mmenkee71e15332015-10-07 16:39:543045 MockWrite data_writes2[] = {
3046 // After calling trans->RestartWithAuth(), this is the request we should
3047 // be issuing -- the final header line contains the credentials.
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"
3051 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083052
mmenkee71e15332015-10-07 16:39:543053 MockWrite("GET / HTTP/1.1\r\n"
3054 "Host: www.example.org\r\n"
3055 "Connection: keep-alive\r\n\r\n"),
3056 };
3057
3058 MockRead data_reads2[] = {
3059 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3060
3061 MockRead("HTTP/1.1 200 OK\r\n"),
3062 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3063 MockRead("Content-Length: 5\r\n\r\n"),
3064 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593065 };
3066
3067 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3068 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073069 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543070 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3071 data_writes2, arraysize(data_writes2));
3072 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063073 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073074 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593075
[email protected]49639fa2011-12-20 23:22:413076 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593077
bnc691fda62016-08-12 00:43:163078 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:503079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503080
[email protected]49639fa2011-12-20 23:22:413081 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013082 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593083
3084 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013085 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463086 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403087 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593088 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003089 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3090 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593091 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403092 entries, pos,
mikecirone8b85c432016-09-08 19:11:003093 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3094 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593095
3096 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523097 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013098 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523099 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593100 EXPECT_EQ(407, response->headers->response_code());
3101 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043102 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593103
[email protected]029c83b62013-01-24 05:28:203104 LoadTimingInfo load_timing_info;
3105 // CONNECT requests and responses are handled at the connect job level, so
3106 // the transaction does not yet have a connection.
3107 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3108
[email protected]49639fa2011-12-20 23:22:413109 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593110
[email protected]49639fa2011-12-20 23:22:413111 rv = trans->RestartWithAuth(
3112 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593114
3115 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013116 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593117
3118 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523119 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593120
3121 EXPECT_TRUE(response->headers->IsKeepAlive());
3122 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503123 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593124 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3125
3126 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523127 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503128
[email protected]029c83b62013-01-24 05:28:203129 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3130 TestLoadTimingNotReusedWithPac(load_timing_info,
3131 CONNECT_TIMING_HAS_SSL_TIMES);
3132
[email protected]0b0bf032010-09-21 18:08:503133 trans.reset();
[email protected]102e27c2011-02-23 01:01:313134 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593135}
3136
[email protected]11203f012009-11-12 23:02:313137// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013138// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013139TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233140 // On the second pass, the body read of the auth challenge is synchronous, so
3141 // IsConnectedAndIdle returns false. The socket should still be drained and
3142 // reused. See http://crbug.com/544255.
3143 for (int i = 0; i < 2; ++i) {
3144 HttpRequestInfo request;
3145 request.method = "GET";
3146 request.url = GURL("https://www.example.org/");
3147 // Ensure that proxy authentication is attempted even
3148 // when the no authentication data flag is set.
3149 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013150
mmenked39192ee2015-12-09 00:57:233151 // Configure against proxy server "myproxy:70".
3152 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3153 BoundTestNetLog log;
3154 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093155 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013156
bnc691fda62016-08-12 00:43:163157 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013158
mmenked39192ee2015-12-09 00:57:233159 // Since we have proxy, should try to establish tunnel.
3160 MockWrite data_writes1[] = {
3161 MockWrite(ASYNC, 0,
3162 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3163 "Host: www.example.org:443\r\n"
3164 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013165
bnc691fda62016-08-12 00:43:163166 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233167 // be issuing -- the final header line contains the credentials.
3168 MockWrite(ASYNC, 3,
3169 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3170 "Host: www.example.org:443\r\n"
3171 "Proxy-Connection: keep-alive\r\n"
3172 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3173 };
ttuttle34f63b52015-03-05 04:33:013174
mmenked39192ee2015-12-09 00:57:233175 // The proxy responds to the connect with a 407, using a persistent
3176 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3177 MockRead data_reads1[] = {
3178 // No credentials.
3179 MockRead(ASYNC, 1,
3180 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3181 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3182 "Proxy-Connection: keep-alive\r\n"
3183 "Content-Length: 10\r\n\r\n"),
3184 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013185
mmenked39192ee2015-12-09 00:57:233186 // Wrong credentials (wrong password).
3187 MockRead(ASYNC, 4,
3188 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3189 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3190 "Proxy-Connection: keep-alive\r\n"
3191 "Content-Length: 10\r\n\r\n"),
3192 // No response body because the test stops reading here.
3193 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3194 };
ttuttle34f63b52015-03-05 04:33:013195
mmenked39192ee2015-12-09 00:57:233196 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3197 arraysize(data_writes1));
3198 data1.set_busy_before_sync_reads(true);
3199 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013200
mmenked39192ee2015-12-09 00:57:233201 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013202
bnc691fda62016-08-12 00:43:163203 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013204 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013205
mmenked39192ee2015-12-09 00:57:233206 TestNetLogEntry::List entries;
3207 log.GetEntries(&entries);
3208 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003209 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3210 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233211 ExpectLogContainsSomewhere(
3212 entries, pos,
mikecirone8b85c432016-09-08 19:11:003213 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3214 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013215
bnc691fda62016-08-12 00:43:163216 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233217 ASSERT_TRUE(response);
3218 ASSERT_TRUE(response->headers);
3219 EXPECT_TRUE(response->headers->IsKeepAlive());
3220 EXPECT_EQ(407, response->headers->response_code());
3221 EXPECT_EQ(10, response->headers->GetContentLength());
3222 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3223 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013224
mmenked39192ee2015-12-09 00:57:233225 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013226
mmenked39192ee2015-12-09 00:57:233227 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163228 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3229 callback2.callback());
robpercival214763f2016-07-01 23:27:013230 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013231
bnc691fda62016-08-12 00:43:163232 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233233 ASSERT_TRUE(response);
3234 ASSERT_TRUE(response->headers);
3235 EXPECT_TRUE(response->headers->IsKeepAlive());
3236 EXPECT_EQ(407, response->headers->response_code());
3237 EXPECT_EQ(10, response->headers->GetContentLength());
3238 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3239 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013240
mmenked39192ee2015-12-09 00:57:233241 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3242 // out of scope.
3243 session->CloseAllConnections();
3244 }
ttuttle34f63b52015-03-05 04:33:013245}
3246
3247// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3248// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013249TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233250 // On the second pass, the body read of the auth challenge is synchronous, so
3251 // IsConnectedAndIdle returns false. The socket should still be drained and
3252 // reused. See http://crbug.com/544255.
3253 for (int i = 0; i < 2; ++i) {
3254 HttpRequestInfo request;
3255 request.method = "GET";
3256 request.url = GURL("https://www.example.org/");
3257 // Ensure that proxy authentication is attempted even
3258 // when the no authentication data flag is set.
3259 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3260
3261 // Configure against proxy server "myproxy:70".
3262 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3263 BoundTestNetLog log;
3264 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093265 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233266
bnc691fda62016-08-12 00:43:163267 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233268
3269 // Since we have proxy, should try to establish tunnel.
3270 MockWrite data_writes1[] = {
3271 MockWrite(ASYNC, 0,
3272 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3273 "Host: www.example.org:443\r\n"
3274 "Proxy-Connection: keep-alive\r\n\r\n"),
3275
bnc691fda62016-08-12 00:43:163276 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233277 // be issuing -- the final header line contains the credentials.
3278 MockWrite(ASYNC, 3,
3279 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3280 "Host: www.example.org:443\r\n"
3281 "Proxy-Connection: keep-alive\r\n"
3282 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3283 };
3284
3285 // The proxy responds to the connect with a 407, using a persistent
3286 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3287 MockRead data_reads1[] = {
3288 // No credentials.
3289 MockRead(ASYNC, 1,
3290 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3291 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3292 "Content-Length: 10\r\n\r\n"),
3293 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3294
3295 // Wrong credentials (wrong password).
3296 MockRead(ASYNC, 4,
3297 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3298 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3299 "Content-Length: 10\r\n\r\n"),
3300 // No response body because the test stops reading here.
3301 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3302 };
3303
3304 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3305 arraysize(data_writes1));
3306 data1.set_busy_before_sync_reads(true);
3307 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3308
3309 TestCompletionCallback callback1;
3310
bnc691fda62016-08-12 00:43:163311 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013312 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233313
3314 TestNetLogEntry::List entries;
3315 log.GetEntries(&entries);
3316 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003317 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3318 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233319 ExpectLogContainsSomewhere(
3320 entries, pos,
mikecirone8b85c432016-09-08 19:11:003321 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3322 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233323
bnc691fda62016-08-12 00:43:163324 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233325 ASSERT_TRUE(response);
3326 ASSERT_TRUE(response->headers);
3327 EXPECT_TRUE(response->headers->IsKeepAlive());
3328 EXPECT_EQ(407, response->headers->response_code());
3329 EXPECT_EQ(10, response->headers->GetContentLength());
3330 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3331 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3332
3333 TestCompletionCallback callback2;
3334
3335 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163336 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3337 callback2.callback());
robpercival214763f2016-07-01 23:27:013338 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233339
bnc691fda62016-08-12 00:43:163340 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233341 ASSERT_TRUE(response);
3342 ASSERT_TRUE(response->headers);
3343 EXPECT_TRUE(response->headers->IsKeepAlive());
3344 EXPECT_EQ(407, response->headers->response_code());
3345 EXPECT_EQ(10, response->headers->GetContentLength());
3346 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3347 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3348
3349 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3350 // out of scope.
3351 session->CloseAllConnections();
3352 }
3353}
3354
3355// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3356// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3357// the case the server sends extra data on the original socket, so it can't be
3358// reused.
bncd16676a2016-07-20 16:23:013359TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273360 HttpRequestInfo request;
3361 request.method = "GET";
bncce36dca22015-04-21 22:11:233362 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273363 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293364 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273365
[email protected]2d2697f92009-02-18 21:00:323366 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233367 session_deps_.proxy_service =
3368 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513369 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073370 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093371 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323372
[email protected]2d2697f92009-02-18 21:00:323373 // Since we have proxy, should try to establish tunnel.
3374 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233375 MockWrite(ASYNC, 0,
3376 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173377 "Host: www.example.org:443\r\n"
3378 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233379 };
[email protected]2d2697f92009-02-18 21:00:323380
mmenked39192ee2015-12-09 00:57:233381 // The proxy responds to the connect with a 407, using a persistent, but sends
3382 // extra data, so the socket cannot be reused.
3383 MockRead data_reads1[] = {
3384 // No credentials.
3385 MockRead(ASYNC, 1,
3386 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3387 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3388 "Content-Length: 10\r\n\r\n"),
3389 MockRead(SYNCHRONOUS, 2, "0123456789"),
3390 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3391 };
3392
3393 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233394 // After calling trans->RestartWithAuth(), this is the request we should
3395 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233396 MockWrite(ASYNC, 0,
3397 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173398 "Host: www.example.org:443\r\n"
3399 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233400 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3401
3402 MockWrite(ASYNC, 2,
3403 "GET / HTTP/1.1\r\n"
3404 "Host: www.example.org\r\n"
3405 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323406 };
3407
mmenked39192ee2015-12-09 00:57:233408 MockRead data_reads2[] = {
3409 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323410
mmenked39192ee2015-12-09 00:57:233411 MockRead(ASYNC, 3,
3412 "HTTP/1.1 200 OK\r\n"
3413 "Content-Type: text/html; charset=iso-8859-1\r\n"
3414 "Content-Length: 5\r\n\r\n"),
3415 // No response body because the test stops reading here.
3416 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323417 };
3418
mmenked39192ee2015-12-09 00:57:233419 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3420 arraysize(data_writes1));
3421 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073422 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233423 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3424 arraysize(data_writes2));
3425 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3426 SSLSocketDataProvider ssl(ASYNC, OK);
3427 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323428
[email protected]49639fa2011-12-20 23:22:413429 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323430
bnc691fda62016-08-12 00:43:163431 std::unique_ptr<HttpNetworkTransaction> trans(
mmenked39192ee2015-12-09 00:57:233432 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:323433
mmenked39192ee2015-12-09 00:57:233434 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013435 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233436
mmenke43758e62015-05-04 21:09:463437 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403438 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393439 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003440 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3441 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393442 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403443 entries, pos,
mikecirone8b85c432016-09-08 19:11:003444 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3445 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323446
[email protected]1c773ea12009-04-28 19:58:423447 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243448 ASSERT_TRUE(response);
3449 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323450 EXPECT_TRUE(response->headers->IsKeepAlive());
3451 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423452 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043453 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323454
mmenked39192ee2015-12-09 00:57:233455 LoadTimingInfo load_timing_info;
3456 // CONNECT requests and responses are handled at the connect job level, so
3457 // the transaction does not yet have a connection.
3458 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3459
[email protected]49639fa2011-12-20 23:22:413460 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323461
mmenked39192ee2015-12-09 00:57:233462 rv =
3463 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013464 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323465
[email protected]2d2697f92009-02-18 21:00:323466 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233467 EXPECT_EQ(200, response->headers->response_code());
3468 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423469 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133470
mmenked39192ee2015-12-09 00:57:233471 // The password prompt info should not be set.
3472 EXPECT_FALSE(response->auth_challenge);
3473
3474 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3475 TestLoadTimingNotReusedWithPac(load_timing_info,
3476 CONNECT_TIMING_HAS_SSL_TIMES);
3477
3478 trans.reset();
[email protected]102e27c2011-02-23 01:01:313479 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323480}
3481
mmenkee71e15332015-10-07 16:39:543482// Test the case a proxy closes a socket while the challenge body is being
3483// drained.
bncd16676a2016-07-20 16:23:013484TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543485 HttpRequestInfo request;
3486 request.method = "GET";
3487 request.url = GURL("https://www.example.org/");
3488 // Ensure that proxy authentication is attempted even
3489 // when the no authentication data flag is set.
3490 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3491
3492 // Configure against proxy server "myproxy:70".
3493 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093494 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543495
bnc691fda62016-08-12 00:43:163496 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543497
3498 // Since we have proxy, should try to establish tunnel.
3499 MockWrite data_writes1[] = {
3500 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173501 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543502 "Proxy-Connection: keep-alive\r\n\r\n"),
3503 };
3504
3505 // The proxy responds to the connect with a 407, using a persistent
3506 // connection.
3507 MockRead data_reads1[] = {
3508 // No credentials.
3509 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3510 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3511 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3512 // Server hands up in the middle of the body.
3513 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3514 };
3515
3516 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163517 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543518 // be issuing -- the final header line contains the credentials.
3519 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173520 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543521 "Proxy-Connection: keep-alive\r\n"
3522 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3523
3524 MockWrite("GET / HTTP/1.1\r\n"
3525 "Host: www.example.org\r\n"
3526 "Connection: keep-alive\r\n\r\n"),
3527 };
3528
3529 MockRead data_reads2[] = {
3530 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3531
3532 MockRead("HTTP/1.1 200 OK\r\n"),
3533 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3534 MockRead("Content-Length: 5\r\n\r\n"),
3535 MockRead(SYNCHRONOUS, "hello"),
3536 };
3537
3538 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3539 data_writes1, arraysize(data_writes1));
3540 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3541 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3542 data_writes2, arraysize(data_writes2));
3543 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3544 SSLSocketDataProvider ssl(ASYNC, OK);
3545 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3546
3547 TestCompletionCallback callback;
3548
tfarina428341112016-09-22 13:38:203549 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013550 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543551
bnc691fda62016-08-12 00:43:163552 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543553 ASSERT_TRUE(response);
3554 ASSERT_TRUE(response->headers);
3555 EXPECT_TRUE(response->headers->IsKeepAlive());
3556 EXPECT_EQ(407, response->headers->response_code());
3557 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3558
bnc691fda62016-08-12 00:43:163559 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013560 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543561
bnc691fda62016-08-12 00:43:163562 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543563 ASSERT_TRUE(response);
3564 ASSERT_TRUE(response->headers);
3565 EXPECT_TRUE(response->headers->IsKeepAlive());
3566 EXPECT_EQ(200, response->headers->response_code());
3567 std::string body;
bnc691fda62016-08-12 00:43:163568 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543569 EXPECT_EQ("hello", body);
3570}
3571
[email protected]a8e9b162009-03-12 00:06:443572// Test that we don't read the response body when we fail to establish a tunnel,
3573// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013574TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273575 HttpRequestInfo request;
3576 request.method = "GET";
bncce36dca22015-04-21 22:11:233577 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273578
[email protected]a8e9b162009-03-12 00:06:443579 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033580 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443581
danakj1fd259a02016-04-16 03:17:093582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443583
bnc691fda62016-08-12 00:43:163584 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443585
[email protected]a8e9b162009-03-12 00:06:443586 // Since we have proxy, should try to establish tunnel.
3587 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173588 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3589 "Host: www.example.org:443\r\n"
3590 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443591 };
3592
3593 // The proxy responds to the connect with a 407.
3594 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243595 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3596 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3597 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233598 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243599 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443600 };
3601
[email protected]31a2bfe2010-02-09 08:03:393602 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3603 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073604 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443605
[email protected]49639fa2011-12-20 23:22:413606 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443607
tfarina428341112016-09-22 13:38:203608 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013609 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443610
3611 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013612 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443613
bnc691fda62016-08-12 00:43:163614 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243615 ASSERT_TRUE(response);
3616 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443617 EXPECT_TRUE(response->headers->IsKeepAlive());
3618 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423619 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443620
3621 std::string response_data;
bnc691fda62016-08-12 00:43:163622 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013623 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183624
3625 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313626 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443627}
3628
ttuttle7933c112015-01-06 00:55:243629// Test that we don't pass extraneous headers from the proxy's response to the
3630// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013631TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243632 HttpRequestInfo request;
3633 request.method = "GET";
bncce36dca22015-04-21 22:11:233634 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243635
3636 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033637 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243638
danakj1fd259a02016-04-16 03:17:093639 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243640
bnc691fda62016-08-12 00:43:163641 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243642
3643 // Since we have proxy, should try to establish tunnel.
3644 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173645 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3646 "Host: www.example.org:443\r\n"
3647 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243648 };
3649
3650 // The proxy responds to the connect with a 407.
3651 MockRead data_reads[] = {
3652 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3653 MockRead("X-Foo: bar\r\n"),
3654 MockRead("Set-Cookie: foo=bar\r\n"),
3655 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3656 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233657 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243658 };
3659
3660 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3661 arraysize(data_writes));
3662 session_deps_.socket_factory->AddSocketDataProvider(&data);
3663
3664 TestCompletionCallback callback;
3665
tfarina428341112016-09-22 13:38:203666 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013667 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243668
3669 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013670 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243671
bnc691fda62016-08-12 00:43:163672 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243673 ASSERT_TRUE(response);
3674 ASSERT_TRUE(response->headers);
3675 EXPECT_TRUE(response->headers->IsKeepAlive());
3676 EXPECT_EQ(407, response->headers->response_code());
3677 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3678 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3679 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3680
3681 std::string response_data;
bnc691fda62016-08-12 00:43:163682 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013683 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243684
3685 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3686 session->CloseAllConnections();
3687}
3688
[email protected]8fdbcd22010-05-05 02:54:523689// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3690// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013691TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523692 HttpRequestInfo request;
3693 request.method = "GET";
bncce36dca22015-04-21 22:11:233694 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523695
[email protected]cb9bf6ca2011-01-28 13:15:273696 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093697 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163698 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273699
[email protected]8fdbcd22010-05-05 02:54:523700 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233701 MockWrite(
3702 "GET / HTTP/1.1\r\n"
3703 "Host: www.example.org\r\n"
3704 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523705 };
3706
3707 MockRead data_reads1[] = {
3708 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3709 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3710 // Large content-length -- won't matter, as connection will be reset.
3711 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063712 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523713 };
3714
3715 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3716 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073717 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523718
[email protected]49639fa2011-12-20 23:22:413719 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523720
tfarina428341112016-09-22 13:38:203721 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013722 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523723
3724 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013725 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523726}
3727
[email protected]7a67a8152010-11-05 18:31:103728// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3729// through a non-authenticating proxy. The request should fail with
3730// ERR_UNEXPECTED_PROXY_AUTH.
3731// Note that it is impossible to detect if an HTTP server returns a 407 through
3732// a non-authenticating proxy - there is nothing to indicate whether the
3733// response came from the proxy or the server, so it is treated as if the proxy
3734// issued the challenge.
bncd16676a2016-07-20 16:23:013735TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273736 HttpRequestInfo request;
3737 request.method = "GET";
bncce36dca22015-04-21 22:11:233738 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273739
rdsmith82957ad2015-09-16 19:42:033740 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513741 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073742 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093743 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103744
[email protected]7a67a8152010-11-05 18:31:103745 // Since we have proxy, should try to establish tunnel.
3746 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173747 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3748 "Host: www.example.org:443\r\n"
3749 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103750
rsleevidb16bb02015-11-12 23:47:173751 MockWrite("GET / HTTP/1.1\r\n"
3752 "Host: www.example.org\r\n"
3753 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103754 };
3755
3756 MockRead data_reads1[] = {
3757 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3758
3759 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3760 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3761 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063762 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103763 };
3764
3765 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3766 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073767 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063768 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073769 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103770
[email protected]49639fa2011-12-20 23:22:413771 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103772
bnc691fda62016-08-12 00:43:163773 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103774
bnc691fda62016-08-12 00:43:163775 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013776 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103777
3778 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013779 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463780 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403781 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103782 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003783 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3784 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103785 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403786 entries, pos,
mikecirone8b85c432016-09-08 19:11:003787 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3788 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103789}
[email protected]2df19bb2010-08-25 20:13:463790
mmenke2a1781d2015-10-07 19:25:333791// Test a proxy auth scheme that allows default credentials and a proxy server
3792// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013793TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333794 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3795 HttpRequestInfo request;
3796 request.method = "GET";
3797 request.url = GURL("https://www.example.org/");
3798
3799 // Configure against proxy server "myproxy:70".
3800 session_deps_.proxy_service =
3801 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3802
danakj1fd259a02016-04-16 03:17:093803 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333804 new HttpAuthHandlerMock::Factory());
3805 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093806 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333807 mock_handler->set_allows_default_credentials(true);
3808 auth_handler_factory->AddMockHandler(mock_handler.release(),
3809 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483810 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333811
3812 // Add NetLog just so can verify load timing information gets a NetLog ID.
3813 NetLog net_log;
3814 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093815 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333816
3817 // Since we have proxy, should try to establish tunnel.
3818 MockWrite data_writes1[] = {
3819 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173820 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333821 "Proxy-Connection: keep-alive\r\n\r\n"),
3822 };
3823
3824 // The proxy responds to the connect with a 407, using a non-persistent
3825 // connection.
3826 MockRead data_reads1[] = {
3827 // No credentials.
3828 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3829 MockRead("Proxy-Authenticate: Mock\r\n"),
3830 MockRead("Proxy-Connection: close\r\n\r\n"),
3831 };
3832
3833 // Since the first connection couldn't be reused, need to establish another
3834 // once given credentials.
3835 MockWrite data_writes2[] = {
3836 // After calling trans->RestartWithAuth(), this is the request we should
3837 // be issuing -- the final header line contains the credentials.
3838 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173839 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333840 "Proxy-Connection: keep-alive\r\n"
3841 "Proxy-Authorization: auth_token\r\n\r\n"),
3842
3843 MockWrite("GET / HTTP/1.1\r\n"
3844 "Host: www.example.org\r\n"
3845 "Connection: keep-alive\r\n\r\n"),
3846 };
3847
3848 MockRead data_reads2[] = {
3849 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3850
3851 MockRead("HTTP/1.1 200 OK\r\n"),
3852 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3853 MockRead("Content-Length: 5\r\n\r\n"),
3854 MockRead(SYNCHRONOUS, "hello"),
3855 };
3856
3857 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3858 data_writes1, arraysize(data_writes1));
3859 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3860 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3861 data_writes2, arraysize(data_writes2));
3862 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3863 SSLSocketDataProvider ssl(ASYNC, OK);
3864 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3865
bnc691fda62016-08-12 00:43:163866 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333867 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3868
3869 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:203870 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013871 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333872
3873 const HttpResponseInfo* response = trans->GetResponseInfo();
3874 ASSERT_TRUE(response);
3875 ASSERT_TRUE(response->headers);
3876 EXPECT_FALSE(response->headers->IsKeepAlive());
3877 EXPECT_EQ(407, response->headers->response_code());
3878 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3879 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523880 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333881
3882 LoadTimingInfo load_timing_info;
3883 // CONNECT requests and responses are handled at the connect job level, so
3884 // the transaction does not yet have a connection.
3885 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3886
3887 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013888 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333889 response = trans->GetResponseInfo();
3890 ASSERT_TRUE(response);
3891 ASSERT_TRUE(response->headers);
3892 EXPECT_TRUE(response->headers->IsKeepAlive());
3893 EXPECT_EQ(200, response->headers->response_code());
3894 EXPECT_EQ(5, response->headers->GetContentLength());
3895 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3896
3897 // The password prompt info should not be set.
3898 EXPECT_FALSE(response->auth_challenge);
3899
3900 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3901 TestLoadTimingNotReusedWithPac(load_timing_info,
3902 CONNECT_TIMING_HAS_SSL_TIMES);
3903
3904 trans.reset();
3905 session->CloseAllConnections();
3906}
3907
3908// Test a proxy auth scheme that allows default credentials and a proxy server
3909// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:013910TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333911 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3912 HttpRequestInfo request;
3913 request.method = "GET";
3914 request.url = GURL("https://www.example.org/");
3915
3916 // Configure against proxy server "myproxy:70".
3917 session_deps_.proxy_service =
3918 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3919
danakj1fd259a02016-04-16 03:17:093920 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333921 new HttpAuthHandlerMock::Factory());
3922 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093923 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333924 mock_handler->set_allows_default_credentials(true);
3925 auth_handler_factory->AddMockHandler(mock_handler.release(),
3926 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483927 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333928
3929 // Add NetLog just so can verify load timing information gets a NetLog ID.
3930 NetLog net_log;
3931 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093932 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333933
3934 // Should try to establish tunnel.
3935 MockWrite data_writes1[] = {
3936 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173937 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333938 "Proxy-Connection: keep-alive\r\n\r\n"),
3939
3940 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173941 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333942 "Proxy-Connection: keep-alive\r\n"
3943 "Proxy-Authorization: auth_token\r\n\r\n"),
3944 };
3945
3946 // The proxy responds to the connect with a 407, using a non-persistent
3947 // connection.
3948 MockRead data_reads1[] = {
3949 // No credentials.
3950 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3951 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3952 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3953 };
3954
3955 // Since the first connection was closed, need to establish another once given
3956 // credentials.
3957 MockWrite data_writes2[] = {
3958 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173959 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333960 "Proxy-Connection: keep-alive\r\n"
3961 "Proxy-Authorization: auth_token\r\n\r\n"),
3962
3963 MockWrite("GET / HTTP/1.1\r\n"
3964 "Host: www.example.org\r\n"
3965 "Connection: keep-alive\r\n\r\n"),
3966 };
3967
3968 MockRead data_reads2[] = {
3969 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3970
3971 MockRead("HTTP/1.1 200 OK\r\n"),
3972 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3973 MockRead("Content-Length: 5\r\n\r\n"),
3974 MockRead(SYNCHRONOUS, "hello"),
3975 };
3976
3977 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3978 data_writes1, arraysize(data_writes1));
3979 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3980 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3981 data_writes2, arraysize(data_writes2));
3982 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3983 SSLSocketDataProvider ssl(ASYNC, OK);
3984 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3985
bnc691fda62016-08-12 00:43:163986 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333987 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3988
3989 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:203990 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013991 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333992
3993 const HttpResponseInfo* response = trans->GetResponseInfo();
3994 ASSERT_TRUE(response);
3995 ASSERT_TRUE(response->headers);
3996 EXPECT_TRUE(response->headers->IsKeepAlive());
3997 EXPECT_EQ(407, response->headers->response_code());
3998 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3999 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4000 EXPECT_FALSE(response->auth_challenge);
4001
4002 LoadTimingInfo load_timing_info;
4003 // CONNECT requests and responses are handled at the connect job level, so
4004 // the transaction does not yet have a connection.
4005 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4006
4007 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014008 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334009
4010 response = trans->GetResponseInfo();
4011 ASSERT_TRUE(response);
4012 ASSERT_TRUE(response->headers);
4013 EXPECT_TRUE(response->headers->IsKeepAlive());
4014 EXPECT_EQ(200, response->headers->response_code());
4015 EXPECT_EQ(5, response->headers->GetContentLength());
4016 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4017
4018 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524019 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334020
4021 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4022 TestLoadTimingNotReusedWithPac(load_timing_info,
4023 CONNECT_TIMING_HAS_SSL_TIMES);
4024
4025 trans.reset();
4026 session->CloseAllConnections();
4027}
4028
4029// Test a proxy auth scheme that allows default credentials and a proxy server
4030// that hangs up when credentials are initially sent, and hangs up again when
4031// they are retried.
bncd16676a2016-07-20 16:23:014032TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334033 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4034 HttpRequestInfo request;
4035 request.method = "GET";
4036 request.url = GURL("https://www.example.org/");
4037
4038 // Configure against proxy server "myproxy:70".
4039 session_deps_.proxy_service =
4040 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4041
danakj1fd259a02016-04-16 03:17:094042 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334043 new HttpAuthHandlerMock::Factory());
4044 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094045 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334046 mock_handler->set_allows_default_credentials(true);
4047 auth_handler_factory->AddMockHandler(mock_handler.release(),
4048 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484049 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334050
4051 // Add NetLog just so can verify load timing information gets a NetLog ID.
4052 NetLog net_log;
4053 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094054 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334055
4056 // Should try to establish tunnel.
4057 MockWrite data_writes1[] = {
4058 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174059 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334060 "Proxy-Connection: keep-alive\r\n\r\n"),
4061
4062 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174063 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334064 "Proxy-Connection: keep-alive\r\n"
4065 "Proxy-Authorization: auth_token\r\n\r\n"),
4066 };
4067
4068 // The proxy responds to the connect with a 407, and then hangs up after the
4069 // second request is sent.
4070 MockRead data_reads1[] = {
4071 // No credentials.
4072 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4073 MockRead("Content-Length: 0\r\n"),
4074 MockRead("Proxy-Connection: keep-alive\r\n"),
4075 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4076 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4077 };
4078
4079 // HttpNetworkTransaction sees a reused connection that was closed with
4080 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4081 // request.
4082 MockWrite data_writes2[] = {
4083 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174084 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334085 "Proxy-Connection: keep-alive\r\n\r\n"),
4086 };
4087
4088 // The proxy, having had more than enough of us, just hangs up.
4089 MockRead data_reads2[] = {
4090 // No credentials.
4091 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4092 };
4093
4094 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4095 data_writes1, arraysize(data_writes1));
4096 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4097 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4098 data_writes2, arraysize(data_writes2));
4099 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4100
bnc691fda62016-08-12 00:43:164101 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334102 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4103
4104 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:204105 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014106 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334107
4108 const HttpResponseInfo* response = trans->GetResponseInfo();
4109 ASSERT_TRUE(response);
4110 ASSERT_TRUE(response->headers);
4111 EXPECT_TRUE(response->headers->IsKeepAlive());
4112 EXPECT_EQ(407, response->headers->response_code());
4113 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4114 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4115 EXPECT_FALSE(response->auth_challenge);
4116
4117 LoadTimingInfo load_timing_info;
4118 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4119
4120 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014121 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334122
4123 trans.reset();
4124 session->CloseAllConnections();
4125}
4126
4127// Test a proxy auth scheme that allows default credentials and a proxy server
4128// that hangs up when credentials are initially sent, and sends a challenge
4129// again they are retried.
bncd16676a2016-07-20 16:23:014130TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334131 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4132 HttpRequestInfo request;
4133 request.method = "GET";
4134 request.url = GURL("https://www.example.org/");
4135
4136 // Configure against proxy server "myproxy:70".
4137 session_deps_.proxy_service =
4138 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4139
danakj1fd259a02016-04-16 03:17:094140 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334141 new HttpAuthHandlerMock::Factory());
4142 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094143 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334144 mock_handler->set_allows_default_credentials(true);
4145 auth_handler_factory->AddMockHandler(mock_handler.release(),
4146 HttpAuth::AUTH_PROXY);
4147 // Add another handler for the second challenge. It supports default
4148 // credentials, but they shouldn't be used, since they were already tried.
4149 mock_handler.reset(new HttpAuthHandlerMock());
4150 mock_handler->set_allows_default_credentials(true);
4151 auth_handler_factory->AddMockHandler(mock_handler.release(),
4152 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484153 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334154
4155 // Add NetLog just so can verify load timing information gets a NetLog ID.
4156 NetLog net_log;
4157 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094158 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334159
4160 // Should try to establish tunnel.
4161 MockWrite data_writes1[] = {
4162 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174163 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334164 "Proxy-Connection: keep-alive\r\n\r\n"),
4165 };
4166
4167 // The proxy responds to the connect with a 407, using a non-persistent
4168 // connection.
4169 MockRead data_reads1[] = {
4170 // No credentials.
4171 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4172 MockRead("Proxy-Authenticate: Mock\r\n"),
4173 MockRead("Proxy-Connection: close\r\n\r\n"),
4174 };
4175
4176 // Since the first connection was closed, need to establish another once given
4177 // credentials.
4178 MockWrite data_writes2[] = {
4179 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174180 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334181 "Proxy-Connection: keep-alive\r\n"
4182 "Proxy-Authorization: auth_token\r\n\r\n"),
4183 };
4184
4185 MockRead data_reads2[] = {
4186 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4187 MockRead("Proxy-Authenticate: Mock\r\n"),
4188 MockRead("Proxy-Connection: close\r\n\r\n"),
4189 };
4190
4191 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4192 data_writes1, arraysize(data_writes1));
4193 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4194 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4195 data_writes2, arraysize(data_writes2));
4196 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4197 SSLSocketDataProvider ssl(ASYNC, OK);
4198 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4199
bnc691fda62016-08-12 00:43:164200 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334201 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4202
4203 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:204204 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014205 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334206
4207 const HttpResponseInfo* response = trans->GetResponseInfo();
4208 ASSERT_TRUE(response);
4209 ASSERT_TRUE(response->headers);
4210 EXPECT_EQ(407, response->headers->response_code());
4211 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4212 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4213 EXPECT_FALSE(response->auth_challenge);
4214
4215 LoadTimingInfo load_timing_info;
4216 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4217
4218 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014219 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334220 response = trans->GetResponseInfo();
4221 ASSERT_TRUE(response);
4222 ASSERT_TRUE(response->headers);
4223 EXPECT_EQ(407, response->headers->response_code());
4224 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4225 EXPECT_TRUE(response->auth_challenge);
4226
4227 trans.reset();
4228 session->CloseAllConnections();
4229}
4230
asankae2257db2016-10-11 22:03:164231// A more nuanced test than GenerateAuthToken test which asserts that
4232// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4233// unnecessarily invalidated, and that if the server co-operates, the
4234// authentication handshake can continue with the same scheme but with a
4235// different identity.
4236TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4237 HttpRequestInfo request;
4238 request.method = "GET";
4239 request.url = GURL("http://www.example.org/");
4240
4241 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
4242 new HttpAuthHandlerMock::Factory());
4243 auth_handler_factory->set_do_init_from_challenge(true);
4244
4245 // First handler. Uses default credentials, but barfs at generate auth token.
4246 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
4247 mock_handler->set_allows_default_credentials(true);
4248 mock_handler->set_allows_explicit_credentials(true);
4249 mock_handler->set_connection_based(true);
4250 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4251 auth_handler_factory->AddMockHandler(mock_handler.release(),
4252 HttpAuth::AUTH_SERVER);
4253
4254 // Add another handler for the second challenge. It supports default
4255 // credentials, but they shouldn't be used, since they were already tried.
4256 mock_handler.reset(new HttpAuthHandlerMock());
4257 mock_handler->set_allows_default_credentials(true);
4258 mock_handler->set_allows_explicit_credentials(true);
4259 mock_handler->set_connection_based(true);
4260 auth_handler_factory->AddMockHandler(mock_handler.release(),
4261 HttpAuth::AUTH_SERVER);
4262 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4263
4264 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4265
4266 MockWrite data_writes1[] = {
4267 MockWrite("GET / HTTP/1.1\r\n"
4268 "Host: www.example.org\r\n"
4269 "Connection: keep-alive\r\n\r\n"),
4270 };
4271
4272 MockRead data_reads1[] = {
4273 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4274 "WWW-Authenticate: Mock\r\n"
4275 "Connection: keep-alive\r\n\r\n"),
4276 };
4277
4278 // Identical to data_writes1[]. The AuthHandler encounters a
4279 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4280 // transaction procceds without an authorization header.
4281 MockWrite data_writes2[] = {
4282 MockWrite("GET / HTTP/1.1\r\n"
4283 "Host: www.example.org\r\n"
4284 "Connection: keep-alive\r\n\r\n"),
4285 };
4286
4287 MockRead data_reads2[] = {
4288 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4289 "WWW-Authenticate: Mock\r\n"
4290 "Connection: keep-alive\r\n\r\n"),
4291 };
4292
4293 MockWrite data_writes3[] = {
4294 MockWrite("GET / HTTP/1.1\r\n"
4295 "Host: www.example.org\r\n"
4296 "Connection: keep-alive\r\n"
4297 "Authorization: auth_token\r\n\r\n"),
4298 };
4299
4300 MockRead data_reads3[] = {
4301 MockRead("HTTP/1.1 200 OK\r\n"
4302 "Content-Length: 5\r\n"
4303 "Content-Type: text/plain\r\n"
4304 "Connection: keep-alive\r\n\r\n"
4305 "Hello"),
4306 };
4307
4308 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4309 data_writes1, arraysize(data_writes1));
4310 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4311
4312 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4313 data_writes2, arraysize(data_writes2));
4314 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4315
4316 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4317 data_writes3, arraysize(data_writes3));
4318 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4319
4320 std::unique_ptr<HttpNetworkTransaction> trans(
4321 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4322
4323 TestCompletionCallback callback;
4324 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4325 EXPECT_THAT(callback.GetResult(rv), IsOk());
4326
4327 const HttpResponseInfo* response = trans->GetResponseInfo();
4328 ASSERT_TRUE(response);
4329 ASSERT_TRUE(response->headers);
4330 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4331
4332 // The following three tests assert that an authentication challenge was
4333 // received and that the stack is ready to respond to the challenge using
4334 // ambient credentials.
4335 EXPECT_EQ(401, response->headers->response_code());
4336 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4337 EXPECT_FALSE(response->auth_challenge);
4338
4339 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4340 EXPECT_THAT(callback.GetResult(rv), IsOk());
4341 response = trans->GetResponseInfo();
4342 ASSERT_TRUE(response);
4343 ASSERT_TRUE(response->headers);
4344
4345 // The following three tests assert that an authentication challenge was
4346 // received and that the stack needs explicit credentials before it is ready
4347 // to respond to the challenge.
4348 EXPECT_EQ(401, response->headers->response_code());
4349 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4350 EXPECT_TRUE(response->auth_challenge);
4351
4352 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4353 EXPECT_THAT(callback.GetResult(rv), IsOk());
4354 response = trans->GetResponseInfo();
4355 ASSERT_TRUE(response);
4356 ASSERT_TRUE(response->headers);
4357 EXPECT_EQ(200, response->headers->response_code());
4358
4359 trans.reset();
4360 session->CloseAllConnections();
4361}
4362
[email protected]029c83b62013-01-24 05:28:204363// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014364TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204365 HttpRequestInfo request1;
4366 request1.method = "GET";
bncce36dca22015-04-21 22:11:234367 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204368
4369 HttpRequestInfo request2;
4370 request2.method = "GET";
bncce36dca22015-04-21 22:11:234371 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204372
4373 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034374 session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514375 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074376 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094377 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204378
4379 // Since we have proxy, should try to establish tunnel.
4380 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174381 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4382 "Host: www.example.org:443\r\n"
4383 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204384
rsleevidb16bb02015-11-12 23:47:174385 MockWrite("GET /1 HTTP/1.1\r\n"
4386 "Host: www.example.org\r\n"
4387 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204388
rsleevidb16bb02015-11-12 23:47:174389 MockWrite("GET /2 HTTP/1.1\r\n"
4390 "Host: www.example.org\r\n"
4391 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204392 };
4393
4394 // The proxy responds to the connect with a 407, using a persistent
4395 // connection.
4396 MockRead data_reads1[] = {
4397 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4398
4399 MockRead("HTTP/1.1 200 OK\r\n"),
4400 MockRead("Content-Length: 1\r\n\r\n"),
4401 MockRead(SYNCHRONOUS, "1"),
4402
4403 MockRead("HTTP/1.1 200 OK\r\n"),
4404 MockRead("Content-Length: 2\r\n\r\n"),
4405 MockRead(SYNCHRONOUS, "22"),
4406 };
4407
4408 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4409 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074410 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204411 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074412 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204413
4414 TestCompletionCallback callback1;
bnc691fda62016-08-12 00:43:164415 std::unique_ptr<HttpNetworkTransaction> trans1(
[email protected]90499482013-06-01 00:39:504416 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204417
4418 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014419 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204420
4421 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014422 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204423
4424 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524425 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474426 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524427 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204428 EXPECT_EQ(1, response1->headers->GetContentLength());
4429
4430 LoadTimingInfo load_timing_info1;
4431 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4432 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4433
4434 trans1.reset();
4435
4436 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:164437 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:504438 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204439
4440 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014441 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204442
4443 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014444 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204445
4446 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524447 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474448 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524449 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204450 EXPECT_EQ(2, response2->headers->GetContentLength());
4451
4452 LoadTimingInfo load_timing_info2;
4453 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4454 TestLoadTimingReused(load_timing_info2);
4455
4456 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4457
4458 trans2.reset();
4459 session->CloseAllConnections();
4460}
4461
4462// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014463TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204464 HttpRequestInfo request1;
4465 request1.method = "GET";
bncce36dca22015-04-21 22:11:234466 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204467
4468 HttpRequestInfo request2;
4469 request2.method = "GET";
bncce36dca22015-04-21 22:11:234470 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204471
4472 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034473 session_deps_.proxy_service =
4474 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514475 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074476 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094477 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204478
4479 // Since we have proxy, should try to establish tunnel.
4480 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174481 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4482 "Host: www.example.org:443\r\n"
4483 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204484
rsleevidb16bb02015-11-12 23:47:174485 MockWrite("GET /1 HTTP/1.1\r\n"
4486 "Host: www.example.org\r\n"
4487 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204488
rsleevidb16bb02015-11-12 23:47:174489 MockWrite("GET /2 HTTP/1.1\r\n"
4490 "Host: www.example.org\r\n"
4491 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204492 };
4493
4494 // The proxy responds to the connect with a 407, using a persistent
4495 // connection.
4496 MockRead data_reads1[] = {
4497 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4498
4499 MockRead("HTTP/1.1 200 OK\r\n"),
4500 MockRead("Content-Length: 1\r\n\r\n"),
4501 MockRead(SYNCHRONOUS, "1"),
4502
4503 MockRead("HTTP/1.1 200 OK\r\n"),
4504 MockRead("Content-Length: 2\r\n\r\n"),
4505 MockRead(SYNCHRONOUS, "22"),
4506 };
4507
4508 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4509 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074510 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204511 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074512 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204513
4514 TestCompletionCallback callback1;
bnc691fda62016-08-12 00:43:164515 std::unique_ptr<HttpNetworkTransaction> trans1(
[email protected]90499482013-06-01 00:39:504516 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204517
4518 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014519 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204520
4521 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014522 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204523
4524 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524525 ASSERT_TRUE(response1);
4526 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204527 EXPECT_EQ(1, response1->headers->GetContentLength());
4528
4529 LoadTimingInfo load_timing_info1;
4530 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4531 TestLoadTimingNotReusedWithPac(load_timing_info1,
4532 CONNECT_TIMING_HAS_SSL_TIMES);
4533
4534 trans1.reset();
4535
4536 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:164537 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:504538 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204539
4540 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014541 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204542
4543 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014544 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204545
4546 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524547 ASSERT_TRUE(response2);
4548 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204549 EXPECT_EQ(2, response2->headers->GetContentLength());
4550
4551 LoadTimingInfo load_timing_info2;
4552 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4553 TestLoadTimingReusedWithPac(load_timing_info2);
4554
4555 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4556
4557 trans2.reset();
4558 session->CloseAllConnections();
4559}
4560
[email protected]2df19bb2010-08-25 20:13:464561// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014562TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274563 HttpRequestInfo request;
4564 request.method = "GET";
bncce36dca22015-04-21 22:11:234565 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274566
[email protected]2df19bb2010-08-25 20:13:464567 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034568 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514569 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074570 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094571 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464572
[email protected]2df19bb2010-08-25 20:13:464573 // Since we have proxy, should use full url
4574 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234575 MockWrite(
4576 "GET http://www.example.org/ HTTP/1.1\r\n"
4577 "Host: www.example.org\r\n"
4578 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464579 };
4580
4581 MockRead data_reads1[] = {
4582 MockRead("HTTP/1.1 200 OK\r\n"),
4583 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4584 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064585 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464586 };
4587
4588 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4589 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074590 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064591 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074592 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464593
[email protected]49639fa2011-12-20 23:22:414594 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464595
bnc691fda62016-08-12 00:43:164596 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504597
bnc691fda62016-08-12 00:43:164598 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014599 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464600
4601 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014602 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464603
[email protected]58e32bb2013-01-21 18:23:254604 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164605 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254606 TestLoadTimingNotReused(load_timing_info,
4607 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4608
bnc691fda62016-08-12 00:43:164609 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524610 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464611
tbansal2ecbbc72016-10-06 17:15:474612 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464613 EXPECT_TRUE(response->headers->IsKeepAlive());
4614 EXPECT_EQ(200, response->headers->response_code());
4615 EXPECT_EQ(100, response->headers->GetContentLength());
4616 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4617
4618 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524619 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464620}
4621
[email protected]7642b5ae2010-09-01 20:55:174622// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014623TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274624 HttpRequestInfo request;
4625 request.method = "GET";
bncce36dca22015-04-21 22:11:234626 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274627
[email protected]7642b5ae2010-09-01 20:55:174628 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034629 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514630 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074631 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094632 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174633
bncce36dca22015-04-21 22:11:234634 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414635 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454636 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414637 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174638
bnc42331402016-07-25 13:36:154639 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414640 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174641 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414642 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174643 };
4644
rch8e6c6c42015-05-01 14:05:134645 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4646 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074647 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174648
[email protected]8ddf8322012-02-23 18:08:064649 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364650 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074651 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174652
[email protected]49639fa2011-12-20 23:22:414653 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174654
bnc691fda62016-08-12 00:43:164655 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504656
bnc691fda62016-08-12 00:43:164657 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014658 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:174659
4660 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014661 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:174662
[email protected]58e32bb2013-01-21 18:23:254663 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164664 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254665 TestLoadTimingNotReused(load_timing_info,
4666 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4667
bnc691fda62016-08-12 00:43:164668 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524669 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:474670 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:524671 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024672 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174673
4674 std::string response_data;
bnc691fda62016-08-12 00:43:164675 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234676 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174677}
4678
[email protected]1c173852014-06-19 12:51:504679// Verifies that a session which races and wins against the owning transaction
4680// (completing prior to host resolution), doesn't fail the transaction.
4681// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:014682TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:504683 HttpRequestInfo request;
4684 request.method = "GET";
bncce36dca22015-04-21 22:11:234685 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504686
4687 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034688 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514689 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504690 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094691 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504692
bncce36dca22015-04-21 22:11:234693 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:414694 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454695 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414696 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:504697
bnc42331402016-07-25 13:36:154698 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414699 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:504700 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414701 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504702 };
4703
rch8e6c6c42015-05-01 14:05:134704 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4705 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504706 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4707
4708 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364709 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:504710 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4711
4712 TestCompletionCallback callback1;
4713
bnc691fda62016-08-12 00:43:164714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:504715
4716 // Stall the hostname resolution begun by the transaction.
4717 session_deps_.host_resolver->set_synchronous_mode(false);
4718 session_deps_.host_resolver->set_ondemand_mode(true);
4719
bnc691fda62016-08-12 00:43:164720 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014721 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:504722
4723 // Race a session to the proxy, which completes first.
4724 session_deps_.host_resolver->set_ondemand_mode(false);
4725 SpdySessionKey key(
4726 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4727 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424728 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504729
4730 // Unstall the resolution begun by the transaction.
4731 session_deps_.host_resolver->set_ondemand_mode(true);
4732 session_deps_.host_resolver->ResolveAllPending();
4733
4734 EXPECT_FALSE(callback1.have_result());
4735 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014736 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:504737
bnc691fda62016-08-12 00:43:164738 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524739 ASSERT_TRUE(response);
4740 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024741 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504742
4743 std::string response_data;
bnc691fda62016-08-12 00:43:164744 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:504745 EXPECT_EQ(kUploadData, response_data);
4746}
4747
[email protected]dc7bd1c52010-11-12 00:01:134748// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014749TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274750 HttpRequestInfo request;
4751 request.method = "GET";
bncce36dca22015-04-21 22:11:234752 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274753
[email protected]79cb5c12011-09-12 13:12:044754 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034755 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514756 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074757 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134759
[email protected]dc7bd1c52010-11-12 00:01:134760 // The first request will be a bare GET, the second request will be a
4761 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:454762 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:414763 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:494764 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384765 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134766 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464767 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134768 };
bncdf80d44fd2016-07-15 20:27:414769 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4770 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
4771 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134772 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414773 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134774 };
4775
4776 // The first response is a 407 proxy authentication challenge, and the second
4777 // response will be a 200 response since the second request includes a valid
4778 // Authorization header.
4779 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464780 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134781 };
bnc42331402016-07-25 13:36:154782 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:414783 "407 Proxy Authentication Required", kExtraAuthenticationHeaders,
4784 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4785 SpdySerializedFrame body_authentication(
4786 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:154787 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:414788 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134789 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414790 CreateMockRead(resp_authentication, 1),
4791 CreateMockRead(body_authentication, 2),
4792 CreateMockRead(resp_data, 4),
4793 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:134794 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134795 };
4796
rch8e6c6c42015-05-01 14:05:134797 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4798 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074799 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134800
[email protected]8ddf8322012-02-23 18:08:064801 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364802 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074803 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134804
[email protected]49639fa2011-12-20 23:22:414805 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134806
bnc691fda62016-08-12 00:43:164807 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:134808
bnc691fda62016-08-12 00:43:164809 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134811
4812 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014813 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134814
bnc691fda62016-08-12 00:43:164815 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134816
wezca1070932016-05-26 20:30:524817 ASSERT_TRUE(response);
4818 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134819 EXPECT_EQ(407, response->headers->response_code());
4820 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434821 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134822
[email protected]49639fa2011-12-20 23:22:414823 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134824
bnc691fda62016-08-12 00:43:164825 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:014826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134827
4828 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014829 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134830
bnc691fda62016-08-12 00:43:164831 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134832
wezca1070932016-05-26 20:30:524833 ASSERT_TRUE(response_restart);
4834 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134835 EXPECT_EQ(200, response_restart->headers->response_code());
4836 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524837 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134838}
4839
[email protected]d9da5fe2010-10-13 22:37:164840// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:014841TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274842 HttpRequestInfo request;
4843 request.method = "GET";
bncce36dca22015-04-21 22:11:234844 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274845
[email protected]d9da5fe2010-10-13 22:37:164846 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034847 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514848 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074849 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164851
bnc691fda62016-08-12 00:43:164852 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164853
bncce36dca22015-04-21 22:11:234854 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414855 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234856 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4857 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164858
bncce36dca22015-04-21 22:11:234859 const char get[] =
4860 "GET / HTTP/1.1\r\n"
4861 "Host: www.example.org\r\n"
4862 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414863 SpdySerializedFrame wrapped_get(
4864 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:154865 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164866 const char resp[] = "HTTP/1.1 200 OK\r\n"
4867 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414868 SpdySerializedFrame wrapped_get_resp(
4869 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
4870 SpdySerializedFrame wrapped_body(
4871 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
4872 SpdySerializedFrame window_update(
4873 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:044874
4875 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414876 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4877 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044878 };
4879
[email protected]d9da5fe2010-10-13 22:37:164880 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414881 CreateMockRead(conn_resp, 1, ASYNC),
4882 CreateMockRead(wrapped_get_resp, 3, ASYNC),
4883 CreateMockRead(wrapped_body, 4, ASYNC),
4884 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134885 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164886 };
4887
rch8e6c6c42015-05-01 14:05:134888 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4889 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074890 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164891
[email protected]8ddf8322012-02-23 18:08:064892 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364893 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074894 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064895 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074896 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164897
[email protected]49639fa2011-12-20 23:22:414898 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164899
bnc691fda62016-08-12 00:43:164900 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164902
4903 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014904 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164905
[email protected]58e32bb2013-01-21 18:23:254906 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164907 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254908 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4909
bnc691fda62016-08-12 00:43:164910 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524911 ASSERT_TRUE(response);
4912 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:164913 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4914
4915 std::string response_data;
bnc691fda62016-08-12 00:43:164916 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:164917 EXPECT_EQ("1234567890", response_data);
4918}
4919
4920// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:014921TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
4922 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:384923
[email protected]cb9bf6ca2011-01-28 13:15:274924 HttpRequestInfo request;
4925 request.method = "GET";
bncce36dca22015-04-21 22:11:234926 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274927
[email protected]d9da5fe2010-10-13 22:37:164928 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034929 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514930 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074931 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094932 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164933
bnc691fda62016-08-12 00:43:164934 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164935
bncce36dca22015-04-21 22:11:234936 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414937 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234938 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4939 // fetch https://www.example.org/ via SPDY
4940 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:414941 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:494942 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414943 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:154944 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414945 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:154946 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414947 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024948 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:414949 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
4950 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:024951 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:414952 SpdySerializedFrame window_update_get_resp(
4953 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
4954 SpdySerializedFrame window_update_body(
4955 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:044956
4957 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414958 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4959 CreateMockWrite(window_update_get_resp, 6),
4960 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:044961 };
4962
[email protected]d9da5fe2010-10-13 22:37:164963 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414964 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:094965 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:414966 CreateMockRead(wrapped_get_resp, 4, ASYNC),
4967 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134968 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164969 };
4970
rch32320842015-05-16 15:57:094971 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4972 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074973 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164974
[email protected]8ddf8322012-02-23 18:08:064975 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364976 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074977 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064978 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364979 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074980 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164981
[email protected]49639fa2011-12-20 23:22:414982 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164983
bnc691fda62016-08-12 00:43:164984 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164986
rch32320842015-05-16 15:57:094987 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:554988 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:094989 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:594990 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:164991 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014992 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164993
[email protected]58e32bb2013-01-21 18:23:254994 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164995 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254996 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4997
bnc691fda62016-08-12 00:43:164998 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524999 ASSERT_TRUE(response);
5000 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025001 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165002
5003 std::string response_data;
bnc691fda62016-08-12 00:43:165004 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235005 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165006}
5007
5008// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015009TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275010 HttpRequestInfo request;
5011 request.method = "GET";
bncce36dca22015-04-21 22:11:235012 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275013
[email protected]d9da5fe2010-10-13 22:37:165014 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035015 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515016 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075017 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095018 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165019
bnc691fda62016-08-12 00:43:165020 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165021
bncce36dca22015-04-21 22:11:235022 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415023 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235024 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415025 SpdySerializedFrame get(
[email protected]c10b20852013-05-15 21:29:205026 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165027
5028 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415029 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165030 };
5031
bnc42331402016-07-25 13:36:155032 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415033 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165034 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415035 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165036 };
5037
rch8e6c6c42015-05-01 14:05:135038 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5039 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075040 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165041
[email protected]8ddf8322012-02-23 18:08:065042 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365043 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075044 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065045 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365046 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075047 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165048
[email protected]49639fa2011-12-20 23:22:415049 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165050
bnc691fda62016-08-12 00:43:165051 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015052 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165053
5054 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015055 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165056
ttuttle960fcbf2016-04-19 13:26:325057 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165058}
5059
[email protected]f6c63db52013-02-02 00:35:225060// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5061// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015062TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225063 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5064 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035065 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515066 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075067 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095068 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505069 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225070
5071 HttpRequestInfo request1;
5072 request1.method = "GET";
bncce36dca22015-04-21 22:11:235073 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225074 request1.load_flags = 0;
5075
5076 HttpRequestInfo request2;
5077 request2.method = "GET";
bncce36dca22015-04-21 22:11:235078 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225079 request2.load_flags = 0;
5080
bncce36dca22015-04-21 22:11:235081 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415082 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235083 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155084 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225085
bncce36dca22015-04-21 22:11:235086 // Fetch https://www.example.org/ via HTTP.
5087 const char get1[] =
5088 "GET / HTTP/1.1\r\n"
5089 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225090 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415091 SpdySerializedFrame wrapped_get1(
5092 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225093 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5094 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415095 SpdySerializedFrame wrapped_get_resp1(
5096 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5097 SpdySerializedFrame wrapped_body1(
5098 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5099 SpdySerializedFrame window_update(
5100 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225101
bncce36dca22015-04-21 22:11:235102 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295103 SpdyHeaderBlock connect2_block;
5104 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnca9b9e222016-07-11 20:10:405105 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155106 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5107 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395108
bnc42331402016-07-25 13:36:155109 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225110
bncce36dca22015-04-21 22:11:235111 // Fetch https://mail.example.org/ via HTTP.
5112 const char get2[] =
5113 "GET / HTTP/1.1\r\n"
5114 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225115 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415116 SpdySerializedFrame wrapped_get2(
5117 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225118 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5119 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415120 SpdySerializedFrame wrapped_get_resp2(
5121 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5122 SpdySerializedFrame wrapped_body2(
5123 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225124
5125 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415126 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5127 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225128 };
5129
5130 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415131 CreateMockRead(conn_resp1, 1, ASYNC),
5132 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5133 CreateMockRead(wrapped_body1, 4, ASYNC),
5134 CreateMockRead(conn_resp2, 6, ASYNC),
5135 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5136 CreateMockRead(wrapped_body2, 9, ASYNC),
5137 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225138 };
5139
mmenke11eb5152015-06-09 14:50:505140 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5141 arraysize(spdy_writes));
5142 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225143
5144 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365145 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505146 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225147 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505148 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225149 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505150 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225151
5152 TestCompletionCallback callback;
5153
bnc691fda62016-08-12 00:43:165154 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:205155 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015156 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225157
5158 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165159 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225160 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5161
bnc691fda62016-08-12 00:43:165162 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525163 ASSERT_TRUE(response);
5164 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225165 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5166
5167 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295168 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165169 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505170 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225171
bnc691fda62016-08-12 00:43:165172 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:205173 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015174 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225175
5176 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165177 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225178 // Even though the SPDY connection is reused, a new tunnelled connection has
5179 // to be created, so the socket's load timing looks like a fresh connection.
5180 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5181
5182 // The requests should have different IDs, since they each are using their own
5183 // separate stream.
5184 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5185
bnc691fda62016-08-12 00:43:165186 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505187 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225188}
5189
5190// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5191// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015192TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225193 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5194 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035195 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515196 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075197 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095198 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505199 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225200
5201 HttpRequestInfo request1;
5202 request1.method = "GET";
bncce36dca22015-04-21 22:11:235203 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225204 request1.load_flags = 0;
5205
5206 HttpRequestInfo request2;
5207 request2.method = "GET";
bncce36dca22015-04-21 22:11:235208 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225209 request2.load_flags = 0;
5210
bncce36dca22015-04-21 22:11:235211 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415212 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235213 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155214 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225215
bncce36dca22015-04-21 22:11:235216 // Fetch https://www.example.org/ via HTTP.
5217 const char get1[] =
5218 "GET / HTTP/1.1\r\n"
5219 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225220 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415221 SpdySerializedFrame wrapped_get1(
5222 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225223 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5224 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415225 SpdySerializedFrame wrapped_get_resp1(
5226 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5227 SpdySerializedFrame wrapped_body1(
5228 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5229 SpdySerializedFrame window_update(
5230 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225231
bncce36dca22015-04-21 22:11:235232 // Fetch https://www.example.org/2 via HTTP.
5233 const char get2[] =
5234 "GET /2 HTTP/1.1\r\n"
5235 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225236 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415237 SpdySerializedFrame wrapped_get2(
5238 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225239 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5240 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415241 SpdySerializedFrame wrapped_get_resp2(
5242 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5243 SpdySerializedFrame wrapped_body2(
5244 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225245
5246 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415247 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5248 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225249 };
5250
5251 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415252 CreateMockRead(conn_resp1, 1, ASYNC),
5253 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5254 CreateMockRead(wrapped_body1, 4, ASYNC),
5255 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
5256 CreateMockRead(wrapped_body2, 7, ASYNC),
5257 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225258 };
5259
mmenke11eb5152015-06-09 14:50:505260 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5261 arraysize(spdy_writes));
5262 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225263
5264 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365265 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505266 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225267 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505268 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225269
5270 TestCompletionCallback callback;
5271
bnc691fda62016-08-12 00:43:165272 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:505273 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina428341112016-09-22 13:38:205274 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015275 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225276
5277 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015278 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225279
5280 LoadTimingInfo load_timing_info;
5281 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5282 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5283
5284 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525285 ASSERT_TRUE(response);
5286 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225287 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5288
5289 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295290 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505291 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225292 trans.reset();
5293
bnc691fda62016-08-12 00:43:165294 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:505295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina428341112016-09-22 13:38:205296 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015297 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225298
[email protected]f6c63db52013-02-02 00:35:225299 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015300 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225301
5302 LoadTimingInfo load_timing_info2;
5303 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5304 TestLoadTimingReused(load_timing_info2);
5305
5306 // The requests should have the same ID.
5307 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5308
[email protected]90499482013-06-01 00:39:505309 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225310}
5311
5312// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5313// Proxy to different servers.
bncd16676a2016-07-20 16:23:015314TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225315 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035316 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515317 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075318 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095319 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505320 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225321
5322 HttpRequestInfo request1;
5323 request1.method = "GET";
bncce36dca22015-04-21 22:11:235324 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225325 request1.load_flags = 0;
5326
5327 HttpRequestInfo request2;
5328 request2.method = "GET";
bncce36dca22015-04-21 22:11:235329 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225330 request2.load_flags = 0;
5331
bncce36dca22015-04-21 22:11:235332 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265333 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235334 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415335 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155336 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5337 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415338 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385339 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225340
bncce36dca22015-04-21 22:11:235341 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265342 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235343 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415344 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155345 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5346 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415347 SpdySerializedFrame body2(
5348 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225349
5350 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415351 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225352 };
5353
5354 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415355 CreateMockRead(get_resp1, 1, ASYNC),
5356 CreateMockRead(body1, 2, ASYNC),
5357 CreateMockRead(get_resp2, 4, ASYNC),
5358 CreateMockRead(body2, 5, ASYNC),
5359 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225360 };
5361
mmenke11eb5152015-06-09 14:50:505362 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5363 arraysize(spdy_writes));
5364 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225365
5366 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365367 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505368 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225369
5370 TestCompletionCallback callback;
5371
bnc691fda62016-08-12 00:43:165372 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:505373 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina428341112016-09-22 13:38:205374 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015375 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225376
5377 LoadTimingInfo load_timing_info;
5378 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5379 TestLoadTimingNotReused(load_timing_info,
5380 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5381
5382 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525383 ASSERT_TRUE(response);
5384 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025385 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225386
5387 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295388 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505389 rv = trans->Read(buf.get(), 256, callback.callback());
5390 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225391 // Delete the first request, so the second one can reuse the socket.
5392 trans.reset();
5393
bnc691fda62016-08-12 00:43:165394 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:205395 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015396 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225397
5398 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165399 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225400 TestLoadTimingReused(load_timing_info2);
5401
5402 // The requests should have the same ID.
5403 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5404
bnc691fda62016-08-12 00:43:165405 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505406 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225407}
5408
[email protected]2df19bb2010-08-25 20:13:465409// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015410TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465411 HttpRequestInfo request;
5412 request.method = "GET";
bncce36dca22015-04-21 22:11:235413 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465414 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295415 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465416
[email protected]79cb5c12011-09-12 13:12:045417 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035418 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515419 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075420 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275422
[email protected]2df19bb2010-08-25 20:13:465423 // Since we have proxy, should use full url
5424 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165425 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5426 "Host: www.example.org\r\n"
5427 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465428
bnc691fda62016-08-12 00:43:165429 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235430 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165431 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5432 "Host: www.example.org\r\n"
5433 "Proxy-Connection: keep-alive\r\n"
5434 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465435 };
5436
5437 // The proxy responds to the GET with a 407, using a persistent
5438 // connection.
5439 MockRead data_reads1[] = {
5440 // No credentials.
5441 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5442 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5443 MockRead("Proxy-Connection: keep-alive\r\n"),
5444 MockRead("Content-Length: 0\r\n\r\n"),
5445
5446 MockRead("HTTP/1.1 200 OK\r\n"),
5447 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5448 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065449 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465450 };
5451
5452 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5453 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075454 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065455 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075456 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465457
[email protected]49639fa2011-12-20 23:22:415458 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465459
bnc691fda62016-08-12 00:43:165460 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505461
bnc691fda62016-08-12 00:43:165462 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465464
5465 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015466 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465467
[email protected]58e32bb2013-01-21 18:23:255468 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165469 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255470 TestLoadTimingNotReused(load_timing_info,
5471 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5472
bnc691fda62016-08-12 00:43:165473 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525474 ASSERT_TRUE(response);
5475 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465476 EXPECT_EQ(407, response->headers->response_code());
5477 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435478 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465479
[email protected]49639fa2011-12-20 23:22:415480 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465481
bnc691fda62016-08-12 00:43:165482 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015483 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465484
5485 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015486 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465487
[email protected]58e32bb2013-01-21 18:23:255488 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165489 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255490 // Retrying with HTTP AUTH is considered to be reusing a socket.
5491 TestLoadTimingReused(load_timing_info);
5492
bnc691fda62016-08-12 00:43:165493 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525494 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465495
5496 EXPECT_TRUE(response->headers->IsKeepAlive());
5497 EXPECT_EQ(200, response->headers->response_code());
5498 EXPECT_EQ(100, response->headers->GetContentLength());
5499 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5500
5501 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525502 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465503}
5504
[email protected]23e482282013-06-14 16:08:025505void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085506 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425507 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085508 request.method = "GET";
bncce36dca22015-04-21 22:11:235509 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085510
[email protected]cb9bf6ca2011-01-28 13:15:275511 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035512 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095513 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275514
[email protected]c744cf22009-02-27 07:28:085515 // Since we have proxy, should try to establish tunnel.
5516 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175517 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5518 "Host: www.example.org:443\r\n"
5519 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085520 };
5521
5522 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235523 status, MockRead("Content-Length: 10\r\n\r\n"),
5524 // No response body because the test stops reading here.
5525 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085526 };
5527
[email protected]31a2bfe2010-02-09 08:03:395528 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5529 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075530 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085531
[email protected]49639fa2011-12-20 23:22:415532 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085533
bnc691fda62016-08-12 00:43:165534 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505535
tfarina428341112016-09-22 13:38:205536 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015537 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085538
5539 rv = callback.WaitForResult();
5540 EXPECT_EQ(expected_status, rv);
5541}
5542
[email protected]23e482282013-06-14 16:08:025543void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235544 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085545 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425546 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085547}
5548
bncd16676a2016-07-20 16:23:015549TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085550 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5551}
5552
bncd16676a2016-07-20 16:23:015553TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085554 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5555}
5556
bncd16676a2016-07-20 16:23:015557TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085558 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5559}
5560
bncd16676a2016-07-20 16:23:015561TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085562 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5563}
5564
bncd16676a2016-07-20 16:23:015565TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085566 ConnectStatusHelper(
5567 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5568}
5569
bncd16676a2016-07-20 16:23:015570TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085571 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5572}
5573
bncd16676a2016-07-20 16:23:015574TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085575 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5576}
5577
bncd16676a2016-07-20 16:23:015578TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085579 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5580}
5581
bncd16676a2016-07-20 16:23:015582TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085583 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5584}
5585
bncd16676a2016-07-20 16:23:015586TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085587 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5588}
5589
bncd16676a2016-07-20 16:23:015590TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085591 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5592}
5593
bncd16676a2016-07-20 16:23:015594TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085595 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5596}
5597
bncd16676a2016-07-20 16:23:015598TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085599 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5600}
5601
bncd16676a2016-07-20 16:23:015602TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085603 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5604}
5605
bncd16676a2016-07-20 16:23:015606TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085607 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5608}
5609
bncd16676a2016-07-20 16:23:015610TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085611 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5612}
5613
bncd16676a2016-07-20 16:23:015614TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375615 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5616}
5617
bncd16676a2016-07-20 16:23:015618TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085619 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5620}
5621
bncd16676a2016-07-20 16:23:015622TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085623 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5624}
5625
bncd16676a2016-07-20 16:23:015626TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085627 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5628}
5629
bncd16676a2016-07-20 16:23:015630TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085631 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5632}
5633
bncd16676a2016-07-20 16:23:015634TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085635 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5636}
5637
bncd16676a2016-07-20 16:23:015638TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085639 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5640}
5641
bncd16676a2016-07-20 16:23:015642TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085643 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5644}
5645
bncd16676a2016-07-20 16:23:015646TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085647 ConnectStatusHelperWithExpectedStatus(
5648 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545649 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085650}
5651
bncd16676a2016-07-20 16:23:015652TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085653 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5654}
5655
bncd16676a2016-07-20 16:23:015656TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085657 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5658}
5659
bncd16676a2016-07-20 16:23:015660TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085661 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5662}
5663
bncd16676a2016-07-20 16:23:015664TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085665 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5666}
5667
bncd16676a2016-07-20 16:23:015668TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085669 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5670}
5671
bncd16676a2016-07-20 16:23:015672TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085673 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5674}
5675
bncd16676a2016-07-20 16:23:015676TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085677 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5678}
5679
bncd16676a2016-07-20 16:23:015680TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085681 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5682}
5683
bncd16676a2016-07-20 16:23:015684TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085685 ConnectStatusHelper(
5686 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5687}
5688
bncd16676a2016-07-20 16:23:015689TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085690 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5691}
5692
bncd16676a2016-07-20 16:23:015693TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085694 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5695}
5696
bncd16676a2016-07-20 16:23:015697TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085698 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5699}
5700
bncd16676a2016-07-20 16:23:015701TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085702 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5703}
5704
bncd16676a2016-07-20 16:23:015705TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085706 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5707}
5708
bncd16676a2016-07-20 16:23:015709TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085710 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5711}
5712
bncd16676a2016-07-20 16:23:015713TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085714 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5715}
5716
[email protected]038e9a32008-10-08 22:40:165717// Test the flow when both the proxy server AND origin server require
5718// authentication. Again, this uses basic auth for both since that is
5719// the simplest to mock.
bncd16676a2016-07-20 16:23:015720TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275721 HttpRequestInfo request;
5722 request.method = "GET";
bncce36dca22015-04-21 22:11:235723 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275724
[email protected]038e9a32008-10-08 22:40:165725 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035726 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095727 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075728
bnc691fda62016-08-12 00:43:165729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:165730
[email protected]f9ee6b52008-11-08 06:46:235731 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235732 MockWrite(
5733 "GET http://www.example.org/ HTTP/1.1\r\n"
5734 "Host: www.example.org\r\n"
5735 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235736 };
5737
[email protected]038e9a32008-10-08 22:40:165738 MockRead data_reads1[] = {
5739 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5740 // Give a couple authenticate options (only the middle one is actually
5741 // supported).
[email protected]22927ad2009-09-21 19:56:195742 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165743 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5744 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5745 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5746 // Large content-length -- won't matter, as connection will be reset.
5747 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065748 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165749 };
5750
bnc691fda62016-08-12 00:43:165751 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:165752 // request we should be issuing -- the final header line contains the
5753 // proxy's credentials.
5754 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235755 MockWrite(
5756 "GET http://www.example.org/ HTTP/1.1\r\n"
5757 "Host: www.example.org\r\n"
5758 "Proxy-Connection: keep-alive\r\n"
5759 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165760 };
5761
5762 // Now the proxy server lets the request pass through to origin server.
5763 // The origin server responds with a 401.
5764 MockRead data_reads2[] = {
5765 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5766 // Note: We are using the same realm-name as the proxy server. This is
5767 // completely valid, as realms are unique across hosts.
5768 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5769 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5770 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065771 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165772 };
5773
bnc691fda62016-08-12 00:43:165774 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:165775 // the credentials for both the proxy and origin server.
5776 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235777 MockWrite(
5778 "GET http://www.example.org/ HTTP/1.1\r\n"
5779 "Host: www.example.org\r\n"
5780 "Proxy-Connection: keep-alive\r\n"
5781 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5782 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165783 };
5784
5785 // Lastly we get the desired content.
5786 MockRead data_reads3[] = {
5787 MockRead("HTTP/1.0 200 OK\r\n"),
5788 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5789 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065790 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165791 };
5792
[email protected]31a2bfe2010-02-09 08:03:395793 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5794 data_writes1, arraysize(data_writes1));
5795 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5796 data_writes2, arraysize(data_writes2));
5797 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5798 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075799 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5800 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5801 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165802
[email protected]49639fa2011-12-20 23:22:415803 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165804
tfarina428341112016-09-22 13:38:205805 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015806 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165807
5808 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015809 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165810
bnc691fda62016-08-12 00:43:165811 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525812 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045813 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165814
[email protected]49639fa2011-12-20 23:22:415815 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165816
bnc691fda62016-08-12 00:43:165817 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165819
5820 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015821 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165822
bnc691fda62016-08-12 00:43:165823 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525824 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045825 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165826
[email protected]49639fa2011-12-20 23:22:415827 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165828
bnc691fda62016-08-12 00:43:165829 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5830 callback3.callback());
robpercival214763f2016-07-01 23:27:015831 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165832
5833 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015834 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165835
bnc691fda62016-08-12 00:43:165836 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525837 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165838 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165839}
[email protected]4ddaf2502008-10-23 18:26:195840
[email protected]ea9dc9a2009-09-05 00:43:325841// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5842// can't hook into its internals to cause it to generate predictable NTLM
5843// authorization headers.
5844#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295845// The NTLM authentication unit tests were generated by capturing the HTTP
5846// requests and responses using Fiddler 2 and inspecting the generated random
5847// bytes in the debugger.
5848
5849// Enter the correct password and authenticate successfully.
bncd16676a2016-07-20 16:23:015850TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425851 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245852 request.method = "GET";
5853 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545854
5855 // Ensure load is not disrupted by flags which suppress behaviour specific
5856 // to other auth schemes.
5857 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245858
[email protected]cb9bf6ca2011-01-28 13:15:275859 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5860 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095861 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275862
[email protected]3f918782009-02-28 01:29:245863 MockWrite data_writes1[] = {
5864 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5865 "Host: 172.22.68.17\r\n"
5866 "Connection: keep-alive\r\n\r\n"),
5867 };
5868
5869 MockRead data_reads1[] = {
5870 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045871 // Negotiate and NTLM are often requested together. However, we only want
5872 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5873 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245874 MockRead("WWW-Authenticate: NTLM\r\n"),
5875 MockRead("Connection: close\r\n"),
5876 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365877 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245878 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065879 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245880 };
5881
5882 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165883 // After restarting with a null identity, this is the
5884 // request we should be issuing -- the final header line contains a Type
5885 // 1 message.
5886 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5887 "Host: 172.22.68.17\r\n"
5888 "Connection: keep-alive\r\n"
5889 "Authorization: NTLM "
5890 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245891
bnc691fda62016-08-12 00:43:165892 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5893 // (the credentials for the origin server). The second request continues
5894 // on the same connection.
5895 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5896 "Host: 172.22.68.17\r\n"
5897 "Connection: keep-alive\r\n"
5898 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5899 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5900 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5901 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5902 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245903 };
5904
5905 MockRead data_reads2[] = {
5906 // The origin server responds with a Type 2 message.
5907 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5908 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295909 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245910 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5911 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5912 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5913 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5914 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5915 "BtAAAAAAA=\r\n"),
5916 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365917 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245918 MockRead("You are not authorized to view this page\r\n"),
5919
5920 // Lastly we get the desired content.
5921 MockRead("HTTP/1.1 200 OK\r\n"),
5922 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5923 MockRead("Content-Length: 13\r\n\r\n"),
5924 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065925 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245926 };
5927
[email protected]31a2bfe2010-02-09 08:03:395928 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5929 data_writes1, arraysize(data_writes1));
5930 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5931 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075932 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5933 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245934
[email protected]49639fa2011-12-20 23:22:415935 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245936
bnc691fda62016-08-12 00:43:165937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505938
tfarina428341112016-09-22 13:38:205939 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245941
5942 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015943 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245944
bnc691fda62016-08-12 00:43:165945 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:225946
bnc691fda62016-08-12 00:43:165947 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525948 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045949 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245950
[email protected]49639fa2011-12-20 23:22:415951 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255952
bnc691fda62016-08-12 00:43:165953 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
5954 callback2.callback());
robpercival214763f2016-07-01 23:27:015955 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:255956
5957 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015958 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:255959
bnc691fda62016-08-12 00:43:165960 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:255961
bnc691fda62016-08-12 00:43:165962 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525963 ASSERT_TRUE(response);
5964 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:255965
[email protected]49639fa2011-12-20 23:22:415966 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245967
bnc691fda62016-08-12 00:43:165968 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:015969 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245970
[email protected]0757e7702009-03-27 04:00:225971 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015972 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245973
bnc691fda62016-08-12 00:43:165974 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525975 ASSERT_TRUE(response);
5976 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:245977 EXPECT_EQ(13, response->headers->GetContentLength());
5978}
5979
[email protected]385a4672009-03-11 22:21:295980// Enter a wrong password, and then the correct one.
bncd16676a2016-07-20 16:23:015981TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425982 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295983 request.method = "GET";
5984 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:295985
[email protected]cb9bf6ca2011-01-28 13:15:275986 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5987 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095988 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275989
[email protected]385a4672009-03-11 22:21:295990 MockWrite data_writes1[] = {
5991 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5992 "Host: 172.22.68.17\r\n"
5993 "Connection: keep-alive\r\n\r\n"),
5994 };
5995
5996 MockRead data_reads1[] = {
5997 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045998 // Negotiate and NTLM are often requested together. However, we only want
5999 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6000 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296001 MockRead("WWW-Authenticate: NTLM\r\n"),
6002 MockRead("Connection: close\r\n"),
6003 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366004 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296005 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066006 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296007 };
6008
6009 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166010 // After restarting with a null identity, this is the
6011 // request we should be issuing -- the final header line contains a Type
6012 // 1 message.
6013 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6014 "Host: 172.22.68.17\r\n"
6015 "Connection: keep-alive\r\n"
6016 "Authorization: NTLM "
6017 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296018
bnc691fda62016-08-12 00:43:166019 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6020 // (the credentials for the origin server). The second request continues
6021 // on the same connection.
6022 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6023 "Host: 172.22.68.17\r\n"
6024 "Connection: keep-alive\r\n"
6025 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6026 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6027 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
6028 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
6029 "4Ww7b7E=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296030 };
6031
6032 MockRead data_reads2[] = {
6033 // The origin server responds with a Type 2 message.
6034 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6035 MockRead("WWW-Authenticate: NTLM "
6036 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
6037 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6038 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6039 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6040 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6041 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6042 "BtAAAAAAA=\r\n"),
6043 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366044 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296045 MockRead("You are not authorized to view this page\r\n"),
6046
6047 // Wrong password.
6048 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:296049 MockRead("WWW-Authenticate: NTLM\r\n"),
6050 MockRead("Connection: close\r\n"),
6051 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366052 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296053 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066054 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296055 };
6056
6057 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166058 // After restarting with a null identity, this is the
6059 // request we should be issuing -- the final header line contains a Type
6060 // 1 message.
6061 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6062 "Host: 172.22.68.17\r\n"
6063 "Connection: keep-alive\r\n"
6064 "Authorization: NTLM "
6065 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296066
bnc691fda62016-08-12 00:43:166067 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6068 // (the credentials for the origin server). The second request continues
6069 // on the same connection.
6070 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6071 "Host: 172.22.68.17\r\n"
6072 "Connection: keep-alive\r\n"
6073 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6074 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6075 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6076 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6077 "+4MUm7c=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296078 };
6079
6080 MockRead data_reads3[] = {
6081 // The origin server responds with a Type 2 message.
6082 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6083 MockRead("WWW-Authenticate: NTLM "
6084 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6085 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6086 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6087 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6088 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6089 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6090 "BtAAAAAAA=\r\n"),
6091 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366092 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296093 MockRead("You are not authorized to view this page\r\n"),
6094
6095 // Lastly we get the desired content.
6096 MockRead("HTTP/1.1 200 OK\r\n"),
6097 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6098 MockRead("Content-Length: 13\r\n\r\n"),
6099 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066100 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296101 };
6102
[email protected]31a2bfe2010-02-09 08:03:396103 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6104 data_writes1, arraysize(data_writes1));
6105 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6106 data_writes2, arraysize(data_writes2));
6107 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6108 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076109 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6110 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6111 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296112
[email protected]49639fa2011-12-20 23:22:416113 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296114
bnc691fda62016-08-12 00:43:166115 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506116
tfarina428341112016-09-22 13:38:206117 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296119
6120 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016121 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296122
bnc691fda62016-08-12 00:43:166123 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296124
bnc691fda62016-08-12 00:43:166125 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526126 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046127 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296128
[email protected]49639fa2011-12-20 23:22:416129 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296130
[email protected]0757e7702009-03-27 04:00:226131 // Enter the wrong password.
bnc691fda62016-08-12 00:43:166132 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
6133 callback2.callback());
robpercival214763f2016-07-01 23:27:016134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296135
[email protected]10af5fe72011-01-31 16:17:256136 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016137 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296138
bnc691fda62016-08-12 00:43:166139 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416140 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166141 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016142 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256143 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016144 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166145 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226146
bnc691fda62016-08-12 00:43:166147 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526148 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046149 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226150
[email protected]49639fa2011-12-20 23:22:416151 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226152
6153 // Now enter the right password.
bnc691fda62016-08-12 00:43:166154 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6155 callback4.callback());
robpercival214763f2016-07-01 23:27:016156 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256157
6158 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016159 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256160
bnc691fda62016-08-12 00:43:166161 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256162
[email protected]49639fa2011-12-20 23:22:416163 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256164
6165 // One more roundtrip
bnc691fda62016-08-12 00:43:166166 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016167 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226168
6169 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016170 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226171
bnc691fda62016-08-12 00:43:166172 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526173 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296174 EXPECT_EQ(13, response->headers->GetContentLength());
6175}
[email protected]ea9dc9a2009-09-05 00:43:326176#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296177
[email protected]4ddaf2502008-10-23 18:26:196178// Test reading a server response which has only headers, and no body.
6179// After some maximum number of bytes is consumed, the transaction should
6180// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016181TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426182 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196183 request.method = "GET";
bncce36dca22015-04-21 22:11:236184 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196185
danakj1fd259a02016-04-16 03:17:096186 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166187 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276188
[email protected]b75b7b2f2009-10-06 00:54:536189 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436190 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536191 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196192
6193 MockRead data_reads[] = {
6194 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066195 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196196 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066197 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196198 };
[email protected]31a2bfe2010-02-09 08:03:396199 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076200 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196201
[email protected]49639fa2011-12-20 23:22:416202 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196203
tfarina428341112016-09-22 13:38:206204 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016205 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196206
6207 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016208 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196209}
[email protected]f4e426b2008-11-05 00:24:496210
6211// Make sure that we don't try to reuse a TCPClientSocket when failing to
6212// establish tunnel.
6213// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016214TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276215 HttpRequestInfo request;
6216 request.method = "GET";
bncce36dca22015-04-21 22:11:236217 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276218
[email protected]f4e426b2008-11-05 00:24:496219 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036220 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016221
danakj1fd259a02016-04-16 03:17:096222 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496223
bnc691fda62016-08-12 00:43:166224 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:506225 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:496226
[email protected]f4e426b2008-11-05 00:24:496227 // Since we have proxy, should try to establish tunnel.
6228 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176229 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6230 "Host: www.example.org:443\r\n"
6231 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496232 };
6233
[email protected]77848d12008-11-14 00:00:226234 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496235 // connection. Usually a proxy would return 501 (not implemented),
6236 // or 200 (tunnel established).
6237 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236238 MockRead("HTTP/1.1 404 Not Found\r\n"),
6239 MockRead("Content-Length: 10\r\n\r\n"),
6240 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496241 };
6242
[email protected]31a2bfe2010-02-09 08:03:396243 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6244 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076245 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496246
[email protected]49639fa2011-12-20 23:22:416247 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496248
tfarina428341112016-09-22 13:38:206249 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496251
6252 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016253 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496254
[email protected]b4404c02009-04-10 16:38:526255 // Empty the current queue. This is necessary because idle sockets are
6256 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556257 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526258
[email protected]f4e426b2008-11-05 00:24:496259 // We now check to make sure the TCPClientSocket was not added back to
6260 // the pool.
[email protected]90499482013-06-01 00:39:506261 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496262 trans.reset();
fdoray92e35a72016-06-10 15:54:556263 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496264 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506265 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496266}
[email protected]372d34a2008-11-05 21:30:516267
[email protected]1b157c02009-04-21 01:55:406268// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016269TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426270 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406271 request.method = "GET";
bncce36dca22015-04-21 22:11:236272 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406273
danakj1fd259a02016-04-16 03:17:096274 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276275
bnc691fda62016-08-12 00:43:166276 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276277
[email protected]1b157c02009-04-21 01:55:406278 MockRead data_reads[] = {
6279 // A part of the response body is received with the response headers.
6280 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6281 // The rest of the response body is received in two parts.
6282 MockRead("lo"),
6283 MockRead(" world"),
6284 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066285 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406286 };
6287
[email protected]31a2bfe2010-02-09 08:03:396288 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076289 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406290
[email protected]49639fa2011-12-20 23:22:416291 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406292
tfarina428341112016-09-22 13:38:206293 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016294 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406295
6296 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016297 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406298
bnc691fda62016-08-12 00:43:166299 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526300 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406301
wezca1070932016-05-26 20:30:526302 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406303 std::string status_line = response->headers->GetStatusLine();
6304 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6305
[email protected]90499482013-06-01 00:39:506306 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406307
6308 std::string response_data;
bnc691fda62016-08-12 00:43:166309 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016310 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406311 EXPECT_EQ("hello world", response_data);
6312
6313 // Empty the current queue. This is necessary because idle sockets are
6314 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556315 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406316
6317 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506318 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406319}
6320
[email protected]76a505b2010-08-25 06:23:006321// Make sure that we recycle a SSL socket after reading all of the response
6322// body.
bncd16676a2016-07-20 16:23:016323TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006324 HttpRequestInfo request;
6325 request.method = "GET";
bncce36dca22015-04-21 22:11:236326 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006327
6328 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236329 MockWrite(
6330 "GET / HTTP/1.1\r\n"
6331 "Host: www.example.org\r\n"
6332 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006333 };
6334
6335 MockRead data_reads[] = {
6336 MockRead("HTTP/1.1 200 OK\r\n"),
6337 MockRead("Content-Length: 11\r\n\r\n"),
6338 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066339 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006340 };
6341
[email protected]8ddf8322012-02-23 18:08:066342 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076343 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006344
6345 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6346 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076347 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006348
[email protected]49639fa2011-12-20 23:22:416349 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006350
danakj1fd259a02016-04-16 03:17:096351 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166352 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006353
tfarina428341112016-09-22 13:38:206354 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006355
robpercival214763f2016-07-01 23:27:016356 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6357 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006358
bnc691fda62016-08-12 00:43:166359 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526360 ASSERT_TRUE(response);
6361 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006362 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6363
[email protected]90499482013-06-01 00:39:506364 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006365
6366 std::string response_data;
bnc691fda62016-08-12 00:43:166367 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016368 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006369 EXPECT_EQ("hello world", response_data);
6370
6371 // Empty the current queue. This is necessary because idle sockets are
6372 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556373 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006374
6375 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506376 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006377}
6378
6379// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6380// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016381TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006382 HttpRequestInfo request;
6383 request.method = "GET";
bncce36dca22015-04-21 22:11:236384 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006385
6386 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236387 MockWrite(
6388 "GET / HTTP/1.1\r\n"
6389 "Host: www.example.org\r\n"
6390 "Connection: keep-alive\r\n\r\n"),
6391 MockWrite(
6392 "GET / HTTP/1.1\r\n"
6393 "Host: www.example.org\r\n"
6394 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006395 };
6396
6397 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426398 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6399 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006400
[email protected]8ddf8322012-02-23 18:08:066401 SSLSocketDataProvider ssl(ASYNC, OK);
6402 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076403 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6404 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006405
6406 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6407 data_writes, arraysize(data_writes));
6408 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6409 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076410 session_deps_.socket_factory->AddSocketDataProvider(&data);
6411 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006412
[email protected]49639fa2011-12-20 23:22:416413 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006414
danakj1fd259a02016-04-16 03:17:096415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166416 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:506417 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006418
tfarina428341112016-09-22 13:38:206419 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006420
robpercival214763f2016-07-01 23:27:016421 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6422 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006423
6424 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526425 ASSERT_TRUE(response);
6426 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006427 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6428
[email protected]90499482013-06-01 00:39:506429 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006430
6431 std::string response_data;
6432 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016433 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006434 EXPECT_EQ("hello world", response_data);
6435
6436 // Empty the current queue. This is necessary because idle sockets are
6437 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556438 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006439
6440 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506441 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006442
6443 // Now start the second transaction, which should reuse the previous socket.
6444
[email protected]90499482013-06-01 00:39:506445 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006446
tfarina428341112016-09-22 13:38:206447 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006448
robpercival214763f2016-07-01 23:27:016449 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6450 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006451
6452 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526453 ASSERT_TRUE(response);
6454 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006455 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6456
[email protected]90499482013-06-01 00:39:506457 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006458
6459 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016460 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006461 EXPECT_EQ("hello world", response_data);
6462
6463 // Empty the current queue. This is necessary because idle sockets are
6464 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556465 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006466
6467 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506468 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006469}
6470
maksim.sisov0adf8592016-07-15 06:25:566471// Grab a socket, use it, and put it back into the pool. Then, make
6472// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016473TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566474 HttpRequestInfo request;
6475 request.method = "GET";
6476 request.url = GURL("http://www.example.org/");
6477 request.load_flags = 0;
6478
6479 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6480
bnc691fda62016-08-12 00:43:166481 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566482
6483 MockRead data_reads[] = {
6484 // A part of the response body is received with the response headers.
6485 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6486 // The rest of the response body is received in two parts.
6487 MockRead("lo"), MockRead(" world"),
6488 MockRead("junk"), // Should not be read!!
6489 MockRead(SYNCHRONOUS, OK),
6490 };
6491
6492 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6493 session_deps_.socket_factory->AddSocketDataProvider(&data);
6494
6495 TestCompletionCallback callback;
6496
tfarina428341112016-09-22 13:38:206497 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566498 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6499
6500 EXPECT_THAT(callback.GetResult(rv), IsOk());
6501
bnc691fda62016-08-12 00:43:166502 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566503 ASSERT_TRUE(response);
6504 EXPECT_TRUE(response->headers);
6505 std::string status_line = response->headers->GetStatusLine();
6506 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6507
6508 // Make memory critical notification and ensure the transaction still has been
6509 // operating right.
6510 base::MemoryPressureListener::NotifyMemoryPressure(
6511 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6512 base::RunLoop().RunUntilIdle();
6513
6514 // Socket should not be flushed as long as it is not idle.
6515 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6516
6517 std::string response_data;
bnc691fda62016-08-12 00:43:166518 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566519 EXPECT_THAT(rv, IsOk());
6520 EXPECT_EQ("hello world", response_data);
6521
6522 // Empty the current queue. This is necessary because idle sockets are
6523 // added to the connection pool asynchronously with a PostTask.
6524 base::RunLoop().RunUntilIdle();
6525
6526 // We now check to make sure the socket was added back to the pool.
6527 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6528
6529 // Idle sockets should be flushed now.
6530 base::MemoryPressureListener::NotifyMemoryPressure(
6531 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6532 base::RunLoop().RunUntilIdle();
6533
6534 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6535}
6536
6537// Grab an SSL socket, use it, and put it back into the pool. Then, make
6538// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016539TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566540 HttpRequestInfo request;
6541 request.method = "GET";
6542 request.url = GURL("https://www.example.org/");
6543 request.load_flags = 0;
6544
6545 MockWrite data_writes[] = {
6546 MockWrite("GET / HTTP/1.1\r\n"
6547 "Host: www.example.org\r\n"
6548 "Connection: keep-alive\r\n\r\n"),
6549 };
6550
6551 MockRead data_reads[] = {
6552 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6553 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6554
6555 SSLSocketDataProvider ssl(ASYNC, OK);
6556 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6557
6558 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6559 arraysize(data_writes));
6560 session_deps_.socket_factory->AddSocketDataProvider(&data);
6561
6562 TestCompletionCallback callback;
6563
6564 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166565 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566566
6567 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina428341112016-09-22 13:38:206568 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566569
6570 EXPECT_THAT(callback.GetResult(rv), IsOk());
6571
bnc691fda62016-08-12 00:43:166572 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566573 ASSERT_TRUE(response);
6574 ASSERT_TRUE(response->headers);
6575 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6576
6577 // Make memory critical notification and ensure the transaction still has been
6578 // operating right.
6579 base::MemoryPressureListener::NotifyMemoryPressure(
6580 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6581 base::RunLoop().RunUntilIdle();
6582
6583 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6584
6585 std::string response_data;
bnc691fda62016-08-12 00:43:166586 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566587 EXPECT_THAT(rv, IsOk());
6588 EXPECT_EQ("hello world", response_data);
6589
6590 // Empty the current queue. This is necessary because idle sockets are
6591 // added to the connection pool asynchronously with a PostTask.
6592 base::RunLoop().RunUntilIdle();
6593
6594 // We now check to make sure the socket was added back to the pool.
6595 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6596
6597 // Make memory notification once again and ensure idle socket is closed.
6598 base::MemoryPressureListener::NotifyMemoryPressure(
6599 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6600 base::RunLoop().RunUntilIdle();
6601
6602 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6603}
6604
[email protected]b4404c02009-04-10 16:38:526605// Make sure that we recycle a socket after a zero-length response.
6606// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016607TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426608 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526609 request.method = "GET";
bncce36dca22015-04-21 22:11:236610 request.url = GURL(
6611 "http://www.example.org/csi?v=3&s=web&action=&"
6612 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6613 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6614 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526615
danakj1fd259a02016-04-16 03:17:096616 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276617
[email protected]b4404c02009-04-10 16:38:526618 MockRead data_reads[] = {
6619 MockRead("HTTP/1.1 204 No Content\r\n"
6620 "Content-Length: 0\r\n"
6621 "Content-Type: text/html\r\n\r\n"),
6622 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066623 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526624 };
6625
[email protected]31a2bfe2010-02-09 08:03:396626 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076627 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526628
mmenkecc2298e2015-12-07 18:20:186629 // Transaction must be created after the MockReads, so it's destroyed before
6630 // them.
bnc691fda62016-08-12 00:43:166631 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186632
[email protected]49639fa2011-12-20 23:22:416633 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526634
tfarina428341112016-09-22 13:38:206635 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016636 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526637
6638 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016639 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526640
bnc691fda62016-08-12 00:43:166641 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526642 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526643
wezca1070932016-05-26 20:30:526644 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526645 std::string status_line = response->headers->GetStatusLine();
6646 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6647
[email protected]90499482013-06-01 00:39:506648 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526649
6650 std::string response_data;
bnc691fda62016-08-12 00:43:166651 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016652 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526653 EXPECT_EQ("", response_data);
6654
6655 // Empty the current queue. This is necessary because idle sockets are
6656 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556657 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526658
6659 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506660 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526661}
6662
bncd16676a2016-07-20 16:23:016663TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096664 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226665 element_readers.push_back(
ricea2deef682016-09-09 08:04:076666 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226667 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276668
[email protected]1c773ea12009-04-28 19:58:426669 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516670 // Transaction 1: a GET request that succeeds. The socket is recycled
6671 // after use.
6672 request[0].method = "GET";
6673 request[0].url = GURL("http://www.google.com/");
6674 request[0].load_flags = 0;
6675 // Transaction 2: a POST request. Reuses the socket kept alive from
6676 // transaction 1. The first attempts fails when writing the POST data.
6677 // This causes the transaction to retry with a new socket. The second
6678 // attempt succeeds.
6679 request[1].method = "POST";
6680 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276681 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516682 request[1].load_flags = 0;
6683
danakj1fd259a02016-04-16 03:17:096684 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516685
6686 // The first socket is used for transaction 1 and the first attempt of
6687 // transaction 2.
6688
6689 // The response of transaction 1.
6690 MockRead data_reads1[] = {
6691 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6692 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066693 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516694 };
6695 // The mock write results of transaction 1 and the first attempt of
6696 // transaction 2.
6697 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066698 MockWrite(SYNCHRONOUS, 64), // GET
6699 MockWrite(SYNCHRONOUS, 93), // POST
6700 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516701 };
[email protected]31a2bfe2010-02-09 08:03:396702 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6703 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516704
6705 // The second socket is used for the second attempt of transaction 2.
6706
6707 // The response of transaction 2.
6708 MockRead data_reads2[] = {
6709 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6710 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066711 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516712 };
6713 // The mock write results of the second attempt of transaction 2.
6714 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066715 MockWrite(SYNCHRONOUS, 93), // POST
6716 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516717 };
[email protected]31a2bfe2010-02-09 08:03:396718 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6719 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516720
[email protected]bb88e1d32013-05-03 23:11:076721 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6722 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516723
thestig9d3bb0c2015-01-24 00:49:516724 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516725 "hello world", "welcome"
6726 };
6727
6728 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:166729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:516730
[email protected]49639fa2011-12-20 23:22:416731 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516732
tfarina428341112016-09-22 13:38:206733 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016734 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:516735
6736 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016737 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516738
bnc691fda62016-08-12 00:43:166739 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526740 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516741
wezca1070932016-05-26 20:30:526742 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516743 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6744
6745 std::string response_data;
bnc691fda62016-08-12 00:43:166746 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016747 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516748 EXPECT_EQ(kExpectedResponseData[i], response_data);
6749 }
6750}
[email protected]f9ee6b52008-11-08 06:46:236751
6752// Test the request-challenge-retry sequence for basic auth when there is
6753// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166754// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:016755TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426756 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236757 request.method = "GET";
bncce36dca22015-04-21 22:11:236758 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416759 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296760
danakj1fd259a02016-04-16 03:17:096761 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166762 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276763
[email protected]a97cca42009-08-14 01:00:296764 // The password contains an escaped character -- for this test to pass it
6765 // will need to be unescaped by HttpNetworkTransaction.
6766 EXPECT_EQ("b%40r", request.url.password());
6767
[email protected]f9ee6b52008-11-08 06:46:236768 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236769 MockWrite(
6770 "GET / HTTP/1.1\r\n"
6771 "Host: www.example.org\r\n"
6772 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236773 };
6774
6775 MockRead data_reads1[] = {
6776 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6777 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6778 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066779 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236780 };
6781
[email protected]2262e3a2012-05-22 16:08:166782 // After the challenge above, the transaction will be restarted using the
6783 // identity from the url (foo, b@r) to answer the challenge.
6784 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236785 MockWrite(
6786 "GET / HTTP/1.1\r\n"
6787 "Host: www.example.org\r\n"
6788 "Connection: keep-alive\r\n"
6789 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166790 };
6791
6792 MockRead data_reads2[] = {
6793 MockRead("HTTP/1.0 200 OK\r\n"),
6794 MockRead("Content-Length: 100\r\n\r\n"),
6795 MockRead(SYNCHRONOUS, OK),
6796 };
6797
[email protected]31a2bfe2010-02-09 08:03:396798 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6799 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166800 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6801 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076802 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6803 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236804
[email protected]49639fa2011-12-20 23:22:416805 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:206806 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236808 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016809 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166810 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166811
6812 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166813 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166815 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016816 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166817 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226818
bnc691fda62016-08-12 00:43:166819 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526820 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166821
6822 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526823 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166824
6825 EXPECT_EQ(100, response->headers->GetContentLength());
6826
6827 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556828 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166829}
6830
6831// Test the request-challenge-retry sequence for basic auth when there is an
6832// incorrect identity in the URL. The identity from the URL should be used only
6833// once.
bncd16676a2016-07-20 16:23:016834TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166835 HttpRequestInfo request;
6836 request.method = "GET";
6837 // Note: the URL has a username:password in it. The password "baz" is
6838 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236839 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166840
6841 request.load_flags = LOAD_NORMAL;
6842
danakj1fd259a02016-04-16 03:17:096843 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166844 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:166845
6846 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236847 MockWrite(
6848 "GET / HTTP/1.1\r\n"
6849 "Host: www.example.org\r\n"
6850 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166851 };
6852
6853 MockRead data_reads1[] = {
6854 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6855 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6856 MockRead("Content-Length: 10\r\n\r\n"),
6857 MockRead(SYNCHRONOUS, ERR_FAILED),
6858 };
6859
6860 // After the challenge above, the transaction will be restarted using the
6861 // identity from the url (foo, baz) to answer the challenge.
6862 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236863 MockWrite(
6864 "GET / HTTP/1.1\r\n"
6865 "Host: www.example.org\r\n"
6866 "Connection: keep-alive\r\n"
6867 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166868 };
6869
6870 MockRead data_reads2[] = {
6871 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6872 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6873 MockRead("Content-Length: 10\r\n\r\n"),
6874 MockRead(SYNCHRONOUS, ERR_FAILED),
6875 };
6876
6877 // After the challenge above, the transaction will be restarted using the
6878 // identity supplied by the user (foo, bar) to answer the challenge.
6879 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236880 MockWrite(
6881 "GET / HTTP/1.1\r\n"
6882 "Host: www.example.org\r\n"
6883 "Connection: keep-alive\r\n"
6884 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166885 };
6886
6887 MockRead data_reads3[] = {
6888 MockRead("HTTP/1.0 200 OK\r\n"),
6889 MockRead("Content-Length: 100\r\n\r\n"),
6890 MockRead(SYNCHRONOUS, OK),
6891 };
6892
6893 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6894 data_writes1, arraysize(data_writes1));
6895 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6896 data_writes2, arraysize(data_writes2));
6897 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6898 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076899 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6900 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6901 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166902
6903 TestCompletionCallback callback1;
6904
tfarina428341112016-09-22 13:38:206905 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166907
6908 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016909 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:166910
bnc691fda62016-08-12 00:43:166911 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166912 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166913 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016914 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166915 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016916 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166917 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166918
bnc691fda62016-08-12 00:43:166919 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526920 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166921 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6922
6923 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166924 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:016925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166926 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016927 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166928 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166929
bnc691fda62016-08-12 00:43:166930 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526931 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166932
6933 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526934 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166935
6936 EXPECT_EQ(100, response->headers->GetContentLength());
6937
[email protected]ea9dc9a2009-09-05 00:43:326938 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556939 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326940}
6941
[email protected]2217aa22013-10-11 03:03:546942
6943// Test the request-challenge-retry sequence for basic auth when there is a
6944// correct identity in the URL, but its use is being suppressed. The identity
6945// from the URL should never be used.
bncd16676a2016-07-20 16:23:016946TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:546947 HttpRequestInfo request;
6948 request.method = "GET";
bncce36dca22015-04-21 22:11:236949 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546950 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6951
danakj1fd259a02016-04-16 03:17:096952 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166953 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:546954
6955 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236956 MockWrite(
6957 "GET / HTTP/1.1\r\n"
6958 "Host: www.example.org\r\n"
6959 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546960 };
6961
6962 MockRead data_reads1[] = {
6963 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6964 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6965 MockRead("Content-Length: 10\r\n\r\n"),
6966 MockRead(SYNCHRONOUS, ERR_FAILED),
6967 };
6968
6969 // After the challenge above, the transaction will be restarted using the
6970 // identity supplied by the user, not the one in the URL, to answer the
6971 // challenge.
6972 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236973 MockWrite(
6974 "GET / HTTP/1.1\r\n"
6975 "Host: www.example.org\r\n"
6976 "Connection: keep-alive\r\n"
6977 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546978 };
6979
6980 MockRead data_reads3[] = {
6981 MockRead("HTTP/1.0 200 OK\r\n"),
6982 MockRead("Content-Length: 100\r\n\r\n"),
6983 MockRead(SYNCHRONOUS, OK),
6984 };
6985
6986 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6987 data_writes1, arraysize(data_writes1));
6988 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6989 data_writes3, arraysize(data_writes3));
6990 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6991 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6992
6993 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:206994 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:546996 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016997 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166998 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:546999
bnc691fda62016-08-12 00:43:167000 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527001 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547002 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7003
7004 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167005 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547007 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017008 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167009 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547010
bnc691fda62016-08-12 00:43:167011 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527012 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547013
7014 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527015 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547016 EXPECT_EQ(100, response->headers->GetContentLength());
7017
7018 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557019 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547020}
7021
[email protected]f9ee6b52008-11-08 06:46:237022// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017023TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097024 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237025
7026 // Transaction 1: authenticate (foo, bar) on MyRealm1
7027 {
[email protected]1c773ea12009-04-28 19:58:427028 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237029 request.method = "GET";
bncce36dca22015-04-21 22:11:237030 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237031
bnc691fda62016-08-12 00:43:167032 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277033
[email protected]f9ee6b52008-11-08 06:46:237034 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237035 MockWrite(
7036 "GET /x/y/z HTTP/1.1\r\n"
7037 "Host: www.example.org\r\n"
7038 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237039 };
7040
7041 MockRead data_reads1[] = {
7042 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7043 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7044 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067045 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237046 };
7047
7048 // Resend with authorization (username=foo, password=bar)
7049 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237050 MockWrite(
7051 "GET /x/y/z HTTP/1.1\r\n"
7052 "Host: www.example.org\r\n"
7053 "Connection: keep-alive\r\n"
7054 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237055 };
7056
7057 // Sever accepts the authorization.
7058 MockRead data_reads2[] = {
7059 MockRead("HTTP/1.0 200 OK\r\n"),
7060 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067061 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237062 };
7063
[email protected]31a2bfe2010-02-09 08:03:397064 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7065 data_writes1, arraysize(data_writes1));
7066 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7067 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077068 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7069 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237070
[email protected]49639fa2011-12-20 23:22:417071 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237072
tfarina428341112016-09-22 13:38:207073 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017074 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237075
7076 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017077 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237078
bnc691fda62016-08-12 00:43:167079 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527080 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047081 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237082
[email protected]49639fa2011-12-20 23:22:417083 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237084
bnc691fda62016-08-12 00:43:167085 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7086 callback2.callback());
robpercival214763f2016-07-01 23:27:017087 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237088
7089 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017090 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237091
bnc691fda62016-08-12 00:43:167092 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527093 ASSERT_TRUE(response);
7094 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237095 EXPECT_EQ(100, response->headers->GetContentLength());
7096 }
7097
7098 // ------------------------------------------------------------------------
7099
7100 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7101 {
[email protected]1c773ea12009-04-28 19:58:427102 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237103 request.method = "GET";
7104 // Note that Transaction 1 was at /x/y/z, so this is in the same
7105 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237106 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237107
bnc691fda62016-08-12 00:43:167108 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277109
[email protected]f9ee6b52008-11-08 06:46:237110 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237111 MockWrite(
7112 "GET /x/y/a/b HTTP/1.1\r\n"
7113 "Host: www.example.org\r\n"
7114 "Connection: keep-alive\r\n"
7115 // Send preemptive authorization for MyRealm1
7116 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237117 };
7118
7119 // The server didn't like the preemptive authorization, and
7120 // challenges us for a different realm (MyRealm2).
7121 MockRead data_reads1[] = {
7122 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7123 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7124 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067125 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237126 };
7127
7128 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7129 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237130 MockWrite(
7131 "GET /x/y/a/b HTTP/1.1\r\n"
7132 "Host: www.example.org\r\n"
7133 "Connection: keep-alive\r\n"
7134 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237135 };
7136
7137 // Sever accepts the authorization.
7138 MockRead data_reads2[] = {
7139 MockRead("HTTP/1.0 200 OK\r\n"),
7140 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067141 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237142 };
7143
[email protected]31a2bfe2010-02-09 08:03:397144 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7145 data_writes1, arraysize(data_writes1));
7146 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7147 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077148 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7149 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237150
[email protected]49639fa2011-12-20 23:22:417151 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237152
tfarina428341112016-09-22 13:38:207153 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017154 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237155
7156 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017157 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237158
bnc691fda62016-08-12 00:43:167159 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527160 ASSERT_TRUE(response);
7161 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047162 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437163 EXPECT_EQ("http://www.example.org",
7164 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047165 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197166 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237167
[email protected]49639fa2011-12-20 23:22:417168 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237169
bnc691fda62016-08-12 00:43:167170 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7171 callback2.callback());
robpercival214763f2016-07-01 23:27:017172 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237173
7174 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017175 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237176
bnc691fda62016-08-12 00:43:167177 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527178 ASSERT_TRUE(response);
7179 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237180 EXPECT_EQ(100, response->headers->GetContentLength());
7181 }
7182
7183 // ------------------------------------------------------------------------
7184
7185 // Transaction 3: Resend a request in MyRealm's protection space --
7186 // succeed with preemptive authorization.
7187 {
[email protected]1c773ea12009-04-28 19:58:427188 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237189 request.method = "GET";
bncce36dca22015-04-21 22:11:237190 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237191
bnc691fda62016-08-12 00:43:167192 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277193
[email protected]f9ee6b52008-11-08 06:46:237194 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237195 MockWrite(
7196 "GET /x/y/z2 HTTP/1.1\r\n"
7197 "Host: www.example.org\r\n"
7198 "Connection: keep-alive\r\n"
7199 // The authorization for MyRealm1 gets sent preemptively
7200 // (since the url is in the same protection space)
7201 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237202 };
7203
7204 // Sever accepts the preemptive authorization
7205 MockRead data_reads1[] = {
7206 MockRead("HTTP/1.0 200 OK\r\n"),
7207 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067208 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237209 };
7210
[email protected]31a2bfe2010-02-09 08:03:397211 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7212 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077213 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237214
[email protected]49639fa2011-12-20 23:22:417215 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237216
tfarina428341112016-09-22 13:38:207217 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017218 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237219
7220 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017221 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237222
bnc691fda62016-08-12 00:43:167223 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527224 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237225
wezca1070932016-05-26 20:30:527226 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237227 EXPECT_EQ(100, response->headers->GetContentLength());
7228 }
7229
7230 // ------------------------------------------------------------------------
7231
7232 // Transaction 4: request another URL in MyRealm (however the
7233 // url is not known to belong to the protection space, so no pre-auth).
7234 {
[email protected]1c773ea12009-04-28 19:58:427235 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237236 request.method = "GET";
bncce36dca22015-04-21 22:11:237237 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237238
bnc691fda62016-08-12 00:43:167239 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277240
[email protected]f9ee6b52008-11-08 06:46:237241 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237242 MockWrite(
7243 "GET /x/1 HTTP/1.1\r\n"
7244 "Host: www.example.org\r\n"
7245 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237246 };
7247
7248 MockRead data_reads1[] = {
7249 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7250 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7251 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067252 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237253 };
7254
7255 // Resend with authorization from MyRealm's cache.
7256 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237257 MockWrite(
7258 "GET /x/1 HTTP/1.1\r\n"
7259 "Host: www.example.org\r\n"
7260 "Connection: keep-alive\r\n"
7261 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237262 };
7263
7264 // Sever accepts the authorization.
7265 MockRead data_reads2[] = {
7266 MockRead("HTTP/1.0 200 OK\r\n"),
7267 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067268 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237269 };
7270
[email protected]31a2bfe2010-02-09 08:03:397271 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7272 data_writes1, arraysize(data_writes1));
7273 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7274 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077275 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7276 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237277
[email protected]49639fa2011-12-20 23:22:417278 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237279
tfarina428341112016-09-22 13:38:207280 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017281 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237282
7283 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017284 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237285
bnc691fda62016-08-12 00:43:167286 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417287 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167288 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017289 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227290 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017291 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167292 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227293
bnc691fda62016-08-12 00:43:167294 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527295 ASSERT_TRUE(response);
7296 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237297 EXPECT_EQ(100, response->headers->GetContentLength());
7298 }
7299
7300 // ------------------------------------------------------------------------
7301
7302 // Transaction 5: request a URL in MyRealm, but the server rejects the
7303 // cached identity. Should invalidate and re-prompt.
7304 {
[email protected]1c773ea12009-04-28 19:58:427305 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237306 request.method = "GET";
bncce36dca22015-04-21 22:11:237307 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237308
bnc691fda62016-08-12 00:43:167309 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277310
[email protected]f9ee6b52008-11-08 06:46:237311 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237312 MockWrite(
7313 "GET /p/q/t HTTP/1.1\r\n"
7314 "Host: www.example.org\r\n"
7315 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237316 };
7317
7318 MockRead data_reads1[] = {
7319 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7320 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7321 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067322 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237323 };
7324
7325 // Resend with authorization from cache for MyRealm.
7326 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237327 MockWrite(
7328 "GET /p/q/t HTTP/1.1\r\n"
7329 "Host: www.example.org\r\n"
7330 "Connection: keep-alive\r\n"
7331 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237332 };
7333
7334 // Sever rejects the authorization.
7335 MockRead data_reads2[] = {
7336 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7337 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7338 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067339 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237340 };
7341
7342 // At this point we should prompt for new credentials for MyRealm.
7343 // Restart with username=foo3, password=foo4.
7344 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237345 MockWrite(
7346 "GET /p/q/t HTTP/1.1\r\n"
7347 "Host: www.example.org\r\n"
7348 "Connection: keep-alive\r\n"
7349 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237350 };
7351
7352 // Sever accepts the authorization.
7353 MockRead data_reads3[] = {
7354 MockRead("HTTP/1.0 200 OK\r\n"),
7355 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067356 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237357 };
7358
[email protected]31a2bfe2010-02-09 08:03:397359 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7360 data_writes1, arraysize(data_writes1));
7361 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7362 data_writes2, arraysize(data_writes2));
7363 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7364 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077365 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7366 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7367 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237368
[email protected]49639fa2011-12-20 23:22:417369 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237370
tfarina428341112016-09-22 13:38:207371 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017372 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237373
7374 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017375 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237376
bnc691fda62016-08-12 00:43:167377 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417378 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167379 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017380 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227381 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017382 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167383 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227384
bnc691fda62016-08-12 00:43:167385 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527386 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047387 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237388
[email protected]49639fa2011-12-20 23:22:417389 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237390
bnc691fda62016-08-12 00:43:167391 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7392 callback3.callback());
robpercival214763f2016-07-01 23:27:017393 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237394
[email protected]0757e7702009-03-27 04:00:227395 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017396 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237397
bnc691fda62016-08-12 00:43:167398 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527399 ASSERT_TRUE(response);
7400 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237401 EXPECT_EQ(100, response->headers->GetContentLength());
7402 }
7403}
[email protected]89ceba9a2009-03-21 03:46:067404
[email protected]3c32c5f2010-05-18 15:18:127405// Tests that nonce count increments when multiple auth attempts
7406// are started with the same nonce.
bncd16676a2016-07-20 16:23:017407TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447408 HttpAuthHandlerDigest::Factory* digest_factory =
7409 new HttpAuthHandlerDigest::Factory();
7410 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7411 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7412 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077413 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097414 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127415
7416 // Transaction 1: authenticate (foo, bar) on MyRealm1
7417 {
[email protected]3c32c5f2010-05-18 15:18:127418 HttpRequestInfo request;
7419 request.method = "GET";
bncce36dca22015-04-21 22:11:237420 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127421
bnc691fda62016-08-12 00:43:167422 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277423
[email protected]3c32c5f2010-05-18 15:18:127424 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237425 MockWrite(
7426 "GET /x/y/z HTTP/1.1\r\n"
7427 "Host: www.example.org\r\n"
7428 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127429 };
7430
7431 MockRead data_reads1[] = {
7432 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7433 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7434 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067435 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127436 };
7437
7438 // Resend with authorization (username=foo, password=bar)
7439 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237440 MockWrite(
7441 "GET /x/y/z HTTP/1.1\r\n"
7442 "Host: www.example.org\r\n"
7443 "Connection: keep-alive\r\n"
7444 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7445 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7446 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7447 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127448 };
7449
7450 // Sever accepts the authorization.
7451 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087452 MockRead("HTTP/1.0 200 OK\r\n"),
7453 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127454 };
7455
7456 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7457 data_writes1, arraysize(data_writes1));
7458 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7459 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077460 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7461 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127462
[email protected]49639fa2011-12-20 23:22:417463 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127464
tfarina428341112016-09-22 13:38:207465 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017466 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127467
7468 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017469 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127470
bnc691fda62016-08-12 00:43:167471 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527472 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047473 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127474
[email protected]49639fa2011-12-20 23:22:417475 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127476
bnc691fda62016-08-12 00:43:167477 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7478 callback2.callback());
robpercival214763f2016-07-01 23:27:017479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127480
7481 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017482 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127483
bnc691fda62016-08-12 00:43:167484 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527485 ASSERT_TRUE(response);
7486 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127487 }
7488
7489 // ------------------------------------------------------------------------
7490
7491 // Transaction 2: Request another resource in digestive's protection space.
7492 // This will preemptively add an Authorization header which should have an
7493 // "nc" value of 2 (as compared to 1 in the first use.
7494 {
[email protected]3c32c5f2010-05-18 15:18:127495 HttpRequestInfo request;
7496 request.method = "GET";
7497 // Note that Transaction 1 was at /x/y/z, so this is in the same
7498 // protection space as digest.
bncce36dca22015-04-21 22:11:237499 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127500
bnc691fda62016-08-12 00:43:167501 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277502
[email protected]3c32c5f2010-05-18 15:18:127503 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237504 MockWrite(
7505 "GET /x/y/a/b HTTP/1.1\r\n"
7506 "Host: www.example.org\r\n"
7507 "Connection: keep-alive\r\n"
7508 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7509 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7510 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7511 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127512 };
7513
7514 // Sever accepts the authorization.
7515 MockRead data_reads1[] = {
7516 MockRead("HTTP/1.0 200 OK\r\n"),
7517 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067518 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127519 };
7520
7521 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7522 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077523 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127524
[email protected]49639fa2011-12-20 23:22:417525 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127526
tfarina428341112016-09-22 13:38:207527 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017528 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127529
7530 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017531 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127532
bnc691fda62016-08-12 00:43:167533 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527534 ASSERT_TRUE(response);
7535 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127536 }
7537}
7538
[email protected]89ceba9a2009-03-21 03:46:067539// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017540TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067541 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097542 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167543 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067544
7545 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167546 trans.read_buf_ = new IOBuffer(15);
7547 trans.read_buf_len_ = 15;
7548 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067549
7550 // Setup state in response_
bnc691fda62016-08-12 00:43:167551 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577552 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087553 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577554 response->response_time = base::Time::Now();
7555 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067556
7557 { // Setup state for response_.vary_data
7558 HttpRequestInfo request;
7559 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7560 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277561 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437562 request.extra_headers.SetHeader("Foo", "1");
7563 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507564 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067565 }
7566
7567 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167568 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067569
7570 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167571 EXPECT_FALSE(trans.read_buf_);
7572 EXPECT_EQ(0, trans.read_buf_len_);
7573 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527574 EXPECT_FALSE(response->auth_challenge);
7575 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047576 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087577 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577578 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067579}
7580
[email protected]bacff652009-03-31 17:50:337581// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017582TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337583 HttpRequestInfo request;
7584 request.method = "GET";
bncce36dca22015-04-21 22:11:237585 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337586
danakj1fd259a02016-04-16 03:17:097587 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167588 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277589
[email protected]bacff652009-03-31 17:50:337590 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237591 MockWrite(
7592 "GET / HTTP/1.1\r\n"
7593 "Host: www.example.org\r\n"
7594 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337595 };
7596
7597 MockRead data_reads[] = {
7598 MockRead("HTTP/1.0 200 OK\r\n"),
7599 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7600 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067601 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337602 };
7603
[email protected]5ecc992a42009-11-11 01:41:597604 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397605 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7606 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067607 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7608 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337609
[email protected]bb88e1d32013-05-03 23:11:077610 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7611 session_deps_.socket_factory->AddSocketDataProvider(&data);
7612 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7613 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337614
[email protected]49639fa2011-12-20 23:22:417615 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337616
tfarina428341112016-09-22 13:38:207617 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017618 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337619
7620 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017621 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337622
bnc691fda62016-08-12 00:43:167623 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337625
7626 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017627 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337628
bnc691fda62016-08-12 00:43:167629 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337630
wezca1070932016-05-26 20:30:527631 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337632 EXPECT_EQ(100, response->headers->GetContentLength());
7633}
7634
7635// Test HTTPS connections to a site with a bad certificate, going through a
7636// proxy
bncd16676a2016-07-20 16:23:017637TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037638 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337639
7640 HttpRequestInfo request;
7641 request.method = "GET";
bncce36dca22015-04-21 22:11:237642 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337643
7644 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177645 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7646 "Host: www.example.org:443\r\n"
7647 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337648 };
7649
7650 MockRead proxy_reads[] = {
7651 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067652 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337653 };
7654
7655 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177656 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7657 "Host: www.example.org:443\r\n"
7658 "Proxy-Connection: keep-alive\r\n\r\n"),
7659 MockWrite("GET / HTTP/1.1\r\n"
7660 "Host: www.example.org\r\n"
7661 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337662 };
7663
7664 MockRead data_reads[] = {
7665 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7666 MockRead("HTTP/1.0 200 OK\r\n"),
7667 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7668 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067669 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337670 };
7671
[email protected]31a2bfe2010-02-09 08:03:397672 StaticSocketDataProvider ssl_bad_certificate(
7673 proxy_reads, arraysize(proxy_reads),
7674 proxy_writes, arraysize(proxy_writes));
7675 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7676 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067677 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7678 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337679
[email protected]bb88e1d32013-05-03 23:11:077680 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7681 session_deps_.socket_factory->AddSocketDataProvider(&data);
7682 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7683 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337684
[email protected]49639fa2011-12-20 23:22:417685 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337686
7687 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077688 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337689
danakj1fd259a02016-04-16 03:17:097690 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167691 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:337692
tfarina428341112016-09-22 13:38:207693 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017694 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337695
7696 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017697 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337698
bnc691fda62016-08-12 00:43:167699 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017700 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337701
7702 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017703 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337704
bnc691fda62016-08-12 00:43:167705 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337706
wezca1070932016-05-26 20:30:527707 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337708 EXPECT_EQ(100, response->headers->GetContentLength());
7709 }
7710}
7711
[email protected]2df19bb2010-08-25 20:13:467712
7713// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:017714TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037715 session_deps_.proxy_service =
7716 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517717 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077718 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467719
7720 HttpRequestInfo request;
7721 request.method = "GET";
bncce36dca22015-04-21 22:11:237722 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467723
7724 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177725 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7726 "Host: www.example.org:443\r\n"
7727 "Proxy-Connection: keep-alive\r\n\r\n"),
7728 MockWrite("GET / HTTP/1.1\r\n"
7729 "Host: www.example.org\r\n"
7730 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467731 };
7732
7733 MockRead data_reads[] = {
7734 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7735 MockRead("HTTP/1.1 200 OK\r\n"),
7736 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7737 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067738 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467739 };
7740
7741 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7742 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067743 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7744 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467745
[email protected]bb88e1d32013-05-03 23:11:077746 session_deps_.socket_factory->AddSocketDataProvider(&data);
7747 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7748 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467749
[email protected]49639fa2011-12-20 23:22:417750 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467751
danakj1fd259a02016-04-16 03:17:097752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167753 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:467754
tfarina428341112016-09-22 13:38:207755 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017756 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:467757
7758 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017759 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167760 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:467761
wezca1070932016-05-26 20:30:527762 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467763
tbansal2ecbbc72016-10-06 17:15:477764 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:467765 EXPECT_TRUE(response->headers->IsKeepAlive());
7766 EXPECT_EQ(200, response->headers->response_code());
7767 EXPECT_EQ(100, response->headers->GetContentLength());
7768 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207769
7770 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167771 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207772 TestLoadTimingNotReusedWithPac(load_timing_info,
7773 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467774}
7775
[email protected]511f6f52010-12-17 03:58:297776// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017777TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037778 session_deps_.proxy_service =
7779 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517780 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077781 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297782
7783 HttpRequestInfo request;
7784 request.method = "GET";
bncce36dca22015-04-21 22:11:237785 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297786
7787 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177788 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7789 "Host: www.example.org:443\r\n"
7790 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297791 };
7792
7793 MockRead data_reads[] = {
7794 MockRead("HTTP/1.1 302 Redirect\r\n"),
7795 MockRead("Location: http://login.example.com/\r\n"),
7796 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067797 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297798 };
7799
7800 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7801 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067802 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297803
[email protected]bb88e1d32013-05-03 23:11:077804 session_deps_.socket_factory->AddSocketDataProvider(&data);
7805 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297806
[email protected]49639fa2011-12-20 23:22:417807 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297808
danakj1fd259a02016-04-16 03:17:097809 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167810 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297811
tfarina428341112016-09-22 13:38:207812 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297814
7815 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017816 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167817 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297818
wezca1070932016-05-26 20:30:527819 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297820
7821 EXPECT_EQ(302, response->headers->response_code());
7822 std::string url;
7823 EXPECT_TRUE(response->headers->IsRedirect(&url));
7824 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207825
7826 // In the case of redirects from proxies, HttpNetworkTransaction returns
7827 // timing for the proxy connection instead of the connection to the host,
7828 // and no send / receive times.
7829 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7830 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167831 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207832
7833 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:197834 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207835
7836 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7837 EXPECT_LE(load_timing_info.proxy_resolve_start,
7838 load_timing_info.proxy_resolve_end);
7839 EXPECT_LE(load_timing_info.proxy_resolve_end,
7840 load_timing_info.connect_timing.connect_start);
7841 ExpectConnectTimingHasTimes(
7842 load_timing_info.connect_timing,
7843 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7844
7845 EXPECT_TRUE(load_timing_info.send_start.is_null());
7846 EXPECT_TRUE(load_timing_info.send_end.is_null());
7847 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297848}
7849
7850// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017851TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037852 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297853
7854 HttpRequestInfo request;
7855 request.method = "GET";
bncce36dca22015-04-21 22:11:237856 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297857
bncdf80d44fd2016-07-15 20:27:417858 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237859 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417860 SpdySerializedFrame goaway(
[email protected]c10b20852013-05-15 21:29:207861 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297862 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417863 CreateMockWrite(conn, 0, SYNCHRONOUS),
7864 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297865 };
7866
7867 static const char* const kExtraHeaders[] = {
7868 "location",
7869 "http://login.example.com/",
7870 };
bnc42331402016-07-25 13:36:157871 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:417872 "302 Redirect", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297873 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417874 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297875 };
7876
rch8e6c6c42015-05-01 14:05:137877 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7878 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067879 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367880 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297881
[email protected]bb88e1d32013-05-03 23:11:077882 session_deps_.socket_factory->AddSocketDataProvider(&data);
7883 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297884
[email protected]49639fa2011-12-20 23:22:417885 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297886
danakj1fd259a02016-04-16 03:17:097887 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167888 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297889
tfarina428341112016-09-22 13:38:207890 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297892
7893 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017894 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167895 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297896
wezca1070932016-05-26 20:30:527897 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297898
7899 EXPECT_EQ(302, response->headers->response_code());
7900 std::string url;
7901 EXPECT_TRUE(response->headers->IsRedirect(&url));
7902 EXPECT_EQ("http://login.example.com/", url);
7903}
7904
[email protected]4eddbc732012-08-09 05:40:177905// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017906TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037907 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297908
7909 HttpRequestInfo request;
7910 request.method = "GET";
bncce36dca22015-04-21 22:11:237911 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297912
7913 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177914 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7915 "Host: www.example.org:443\r\n"
7916 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297917 };
7918
7919 MockRead data_reads[] = {
7920 MockRead("HTTP/1.1 404 Not Found\r\n"),
7921 MockRead("Content-Length: 23\r\n\r\n"),
7922 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067923 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297924 };
7925
7926 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7927 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067928 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297929
[email protected]bb88e1d32013-05-03 23:11:077930 session_deps_.socket_factory->AddSocketDataProvider(&data);
7931 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297932
[email protected]49639fa2011-12-20 23:22:417933 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297934
danakj1fd259a02016-04-16 03:17:097935 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167936 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297937
tfarina428341112016-09-22 13:38:207938 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017939 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297940
7941 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017942 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:297943
ttuttle960fcbf2016-04-19 13:26:327944 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297945}
7946
[email protected]4eddbc732012-08-09 05:40:177947// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017948TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037949 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297950
7951 HttpRequestInfo request;
7952 request.method = "GET";
bncce36dca22015-04-21 22:11:237953 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297954
bncdf80d44fd2016-07-15 20:27:417955 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237956 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417957 SpdySerializedFrame rst(
[email protected]c10b20852013-05-15 21:29:207958 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297959 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417960 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:297961 };
7962
7963 static const char* const kExtraHeaders[] = {
7964 "location",
7965 "http://login.example.com/",
7966 };
bnc42331402016-07-25 13:36:157967 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:417968 "404 Not Found", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
7969 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:557970 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297971 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417972 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:137973 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297974 };
7975
rch8e6c6c42015-05-01 14:05:137976 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7977 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067978 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367979 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297980
[email protected]bb88e1d32013-05-03 23:11:077981 session_deps_.socket_factory->AddSocketDataProvider(&data);
7982 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297983
[email protected]49639fa2011-12-20 23:22:417984 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297985
danakj1fd259a02016-04-16 03:17:097986 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167987 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297988
tfarina428341112016-09-22 13:38:207989 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017990 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297991
7992 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017993 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:297994
ttuttle960fcbf2016-04-19 13:26:327995 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297996}
7997
[email protected]0c5fb722012-02-28 11:50:357998// Test the request-challenge-retry sequence for basic auth, through
7999// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018000TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358001 HttpRequestInfo request;
8002 request.method = "GET";
bncce36dca22015-04-21 22:11:238003 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358004 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298005 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358006
8007 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038008 session_deps_.proxy_service =
8009 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518010 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078011 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098012 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358013
8014 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418015 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238016 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418017 SpdySerializedFrame rst(
[email protected]c10b20852013-05-15 21:29:208018 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388019 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358020
bnc691fda62016-08-12 00:43:168021 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358022 // be issuing -- the final header line contains the credentials.
8023 const char* const kAuthCredentials[] = {
8024 "proxy-authorization", "Basic Zm9vOmJhcg==",
8025 };
bncdf80d44fd2016-07-15 20:27:418026 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348027 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238028 HostPortPair("www.example.org", 443)));
8029 // fetch https://www.example.org/ via HTTP
8030 const char get[] =
8031 "GET / HTTP/1.1\r\n"
8032 "Host: www.example.org\r\n"
8033 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418034 SpdySerializedFrame wrapped_get(
8035 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358036
8037 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418038 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8039 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358040 };
8041
8042 // The proxy responds to the connect with a 407, using a persistent
8043 // connection.
thestig9d3bb0c2015-01-24 00:49:518044 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358045 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358046 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8047 };
bnc42331402016-07-25 13:36:158048 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418049 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358050
bnc42331402016-07-25 13:36:158051 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358052 const char resp[] = "HTTP/1.1 200 OK\r\n"
8053 "Content-Length: 5\r\n\r\n";
8054
bncdf80d44fd2016-07-15 20:27:418055 SpdySerializedFrame wrapped_get_resp(
8056 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8057 SpdySerializedFrame wrapped_body(
8058 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358059 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418060 CreateMockRead(conn_auth_resp, 1, ASYNC),
8061 CreateMockRead(conn_resp, 4, ASYNC),
8062 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8063 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138064 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358065 };
8066
rch8e6c6c42015-05-01 14:05:138067 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8068 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078069 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358070 // Negotiate SPDY to the proxy
8071 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368072 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078073 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358074 // Vanilla SSL to the server
8075 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078076 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358077
8078 TestCompletionCallback callback1;
8079
bnc691fda62016-08-12 00:43:168080 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508081 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:358082
8083 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358085
8086 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018087 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468088 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358089 log.GetEntries(&entries);
8090 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008091 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8092 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358093 ExpectLogContainsSomewhere(
8094 entries, pos,
mikecirone8b85c432016-09-08 19:11:008095 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8096 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358097
8098 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528099 ASSERT_TRUE(response);
8100 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358101 EXPECT_EQ(407, response->headers->response_code());
8102 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528103 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438104 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358105
8106 TestCompletionCallback callback2;
8107
8108 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8109 callback2.callback());
robpercival214763f2016-07-01 23:27:018110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358111
8112 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018113 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358114
8115 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528116 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358117
8118 EXPECT_TRUE(response->headers->IsKeepAlive());
8119 EXPECT_EQ(200, response->headers->response_code());
8120 EXPECT_EQ(5, response->headers->GetContentLength());
8121 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8122
8123 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528124 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358125
[email protected]029c83b62013-01-24 05:28:208126 LoadTimingInfo load_timing_info;
8127 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8128 TestLoadTimingNotReusedWithPac(load_timing_info,
8129 CONNECT_TIMING_HAS_SSL_TIMES);
8130
[email protected]0c5fb722012-02-28 11:50:358131 trans.reset();
8132 session->CloseAllConnections();
8133}
8134
[email protected]7c6f7ba2012-04-03 04:09:298135// Test that an explicitly trusted SPDY proxy can push a resource from an
8136// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018137TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158138 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098139 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158140 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8141 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298142 HttpRequestInfo request;
8143 HttpRequestInfo push_request;
8144
[email protected]7c6f7ba2012-04-03 04:09:298145 request.method = "GET";
bncce36dca22015-04-21 22:11:238146 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298147 push_request.method = "GET";
8148 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8149
tbansal28e68f82016-02-04 02:56:158150 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038151 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158152 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518153 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078154 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508155
tbansal28e68f82016-02-04 02:56:158156 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:508157
danakj1fd259a02016-04-16 03:17:098158 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298159
bncdf80d44fd2016-07-15 20:27:418160 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458161 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]7c6f7ba2012-04-03 04:09:298162
8163 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418164 CreateMockWrite(stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298165 };
8166
bncdf80d44fd2016-07-15 20:27:418167 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158168 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298169
bncdf80d44fd2016-07-15 20:27:418170 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298171
bncdf80d44fd2016-07-15 20:27:418172 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558173 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438174 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418175 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8176 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298177
8178 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418179 CreateMockRead(stream1_reply, 1, ASYNC),
8180 CreateMockRead(stream2_syn, 2, ASYNC),
8181 CreateMockRead(stream1_body, 3, ASYNC),
8182 CreateMockRead(stream2_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598183 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298184 };
8185
rch8e6c6c42015-05-01 14:05:138186 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8187 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078188 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298189 // Negotiate SPDY to the proxy
8190 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368191 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078192 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298193
bnc691fda62016-08-12 00:43:168194 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508195 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:298196 TestCompletionCallback callback;
8197 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018198 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298199
8200 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018201 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298202 const HttpResponseInfo* response = trans->GetResponseInfo();
8203
bnc691fda62016-08-12 00:43:168204 std::unique_ptr<HttpNetworkTransaction> push_trans(
[email protected]90499482013-06-01 00:39:508205 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8206 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018207 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298208
8209 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018210 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298211 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8212
wezca1070932016-05-26 20:30:528213 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298214 EXPECT_TRUE(response->headers->IsKeepAlive());
8215
8216 EXPECT_EQ(200, response->headers->response_code());
8217 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8218
8219 std::string response_data;
8220 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018221 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298222 EXPECT_EQ("hello!", response_data);
8223
[email protected]029c83b62013-01-24 05:28:208224 LoadTimingInfo load_timing_info;
8225 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8226 TestLoadTimingNotReusedWithPac(load_timing_info,
8227 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8228
[email protected]7c6f7ba2012-04-03 04:09:298229 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528230 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298231 EXPECT_EQ(200, push_response->headers->response_code());
8232
8233 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018234 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298235 EXPECT_EQ("pushed", response_data);
8236
[email protected]029c83b62013-01-24 05:28:208237 LoadTimingInfo push_load_timing_info;
8238 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8239 TestLoadTimingReusedWithPac(push_load_timing_info);
8240 // The transactions should share a socket ID, despite being for different
8241 // origins.
8242 EXPECT_EQ(load_timing_info.socket_log_id,
8243 push_load_timing_info.socket_log_id);
8244
[email protected]7c6f7ba2012-04-03 04:09:298245 trans.reset();
8246 push_trans.reset();
8247 session->CloseAllConnections();
8248}
8249
[email protected]8c843192012-04-05 07:15:008250// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018251TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158252 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098253 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158254 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8255 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008256 HttpRequestInfo request;
8257
8258 request.method = "GET";
bncce36dca22015-04-21 22:11:238259 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008260
tbansal28e68f82016-02-04 02:56:158261 session_deps_.proxy_service =
8262 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518263 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078264 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508265
8266 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:158267 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:508268
danakj1fd259a02016-04-16 03:17:098269 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008270
bncdf80d44fd2016-07-15 20:27:418271 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458272 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008273
bncdf80d44fd2016-07-15 20:27:418274 SpdySerializedFrame push_rst(
[email protected]c10b20852013-05-15 21:29:208275 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008276
8277 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418278 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008279 };
8280
bncdf80d44fd2016-07-15 20:27:418281 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158282 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008283
bncdf80d44fd2016-07-15 20:27:418284 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008285
bncdf80d44fd2016-07-15 20:27:418286 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558287 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008288
8289 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418290 CreateMockRead(stream1_reply, 1, ASYNC),
8291 CreateMockRead(stream2_syn, 2, ASYNC),
8292 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598293 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008294 };
8295
rch8e6c6c42015-05-01 14:05:138296 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8297 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078298 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008299 // Negotiate SPDY to the proxy
8300 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368301 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078302 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008303
bnc691fda62016-08-12 00:43:168304 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508305 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:008306 TestCompletionCallback callback;
8307 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018308 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008309
8310 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018311 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008312 const HttpResponseInfo* response = trans->GetResponseInfo();
8313
wezca1070932016-05-26 20:30:528314 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008315 EXPECT_TRUE(response->headers->IsKeepAlive());
8316
8317 EXPECT_EQ(200, response->headers->response_code());
8318 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8319
8320 std::string response_data;
8321 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018322 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008323 EXPECT_EQ("hello!", response_data);
8324
8325 trans.reset();
8326 session->CloseAllConnections();
8327}
8328
tbansal8ef1d3e2016-02-03 04:05:428329// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8330// resources.
bncd16676a2016-07-20 16:23:018331TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158332 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098333 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158334 proxy_delegate->set_trusted_spdy_proxy(
8335 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8336
tbansal8ef1d3e2016-02-03 04:05:428337 HttpRequestInfo request;
8338
8339 request.method = "GET";
8340 request.url = GURL("http://www.example.org/");
8341
8342 // Configure against https proxy server "myproxy:70".
8343 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8344 BoundTestNetLog log;
8345 session_deps_.net_log = log.bound().net_log();
8346
8347 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:158348 session_deps_.proxy_delegate.reset(proxy_delegate.release());
tbansal8ef1d3e2016-02-03 04:05:428349
danakj1fd259a02016-04-16 03:17:098350 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428351
bncdf80d44fd2016-07-15 20:27:418352 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458353 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tbansal8ef1d3e2016-02-03 04:05:428354
8355 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418356 CreateMockWrite(stream1_syn, 0, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428357 };
8358
bncdf80d44fd2016-07-15 20:27:418359 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158360 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428361
bncdf80d44fd2016-07-15 20:27:418362 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:498363 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
8364
bncdf80d44fd2016-07-15 20:27:418365 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428366
bncdf80d44fd2016-07-15 20:27:418367 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158368 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428369
bncdf80d44fd2016-07-15 20:27:418370 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428371
8372 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418373 CreateMockRead(stream1_reply, 1, ASYNC),
8374 CreateMockRead(stream2_syn, 2, ASYNC),
8375 CreateMockRead(stream1_body, 3, ASYNC),
8376 CreateMockRead(stream2_body, 4, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428377 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
8378 };
8379
8380 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8381 arraysize(spdy_writes));
8382 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8383 // Negotiate SPDY to the proxy
8384 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368385 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428386 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8387
bnc691fda62016-08-12 00:43:168388 std::unique_ptr<HttpNetworkTransaction> trans(
tbansal8ef1d3e2016-02-03 04:05:428389 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8390 TestCompletionCallback callback;
8391 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018392 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428393
8394 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018395 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428396 const HttpResponseInfo* response = trans->GetResponseInfo();
8397
wezca1070932016-05-26 20:30:528398 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428399 EXPECT_TRUE(response->headers->IsKeepAlive());
8400
8401 EXPECT_EQ(200, response->headers->response_code());
8402 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8403
8404 std::string response_data;
8405 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018406 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428407 EXPECT_EQ("hello!", response_data);
8408
8409 trans.reset();
8410 session->CloseAllConnections();
8411}
8412
[email protected]2df19bb2010-08-25 20:13:468413// Test HTTPS connections to a site with a bad certificate, going through an
8414// HTTPS proxy
bncd16676a2016-07-20 16:23:018415TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038416 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468417
8418 HttpRequestInfo request;
8419 request.method = "GET";
bncce36dca22015-04-21 22:11:238420 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468421
8422 // Attempt to fetch the URL from a server with a bad cert
8423 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178424 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8425 "Host: www.example.org:443\r\n"
8426 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468427 };
8428
8429 MockRead bad_cert_reads[] = {
8430 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068431 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468432 };
8433
8434 // Attempt to fetch the URL with a good cert
8435 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178436 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8437 "Host: www.example.org:443\r\n"
8438 "Proxy-Connection: keep-alive\r\n\r\n"),
8439 MockWrite("GET / HTTP/1.1\r\n"
8440 "Host: www.example.org\r\n"
8441 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468442 };
8443
8444 MockRead good_cert_reads[] = {
8445 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8446 MockRead("HTTP/1.0 200 OK\r\n"),
8447 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8448 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068449 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468450 };
8451
8452 StaticSocketDataProvider ssl_bad_certificate(
8453 bad_cert_reads, arraysize(bad_cert_reads),
8454 bad_cert_writes, arraysize(bad_cert_writes));
8455 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8456 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068457 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8458 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468459
8460 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078461 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8462 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8463 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468464
8465 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078466 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8467 session_deps_.socket_factory->AddSocketDataProvider(&data);
8468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468469
[email protected]49639fa2011-12-20 23:22:418470 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468471
danakj1fd259a02016-04-16 03:17:098472 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168473 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468474
tfarina428341112016-09-22 13:38:208475 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018476 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468477
8478 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018479 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468480
bnc691fda62016-08-12 00:43:168481 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018482 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468483
8484 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018485 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468486
bnc691fda62016-08-12 00:43:168487 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468488
wezca1070932016-05-26 20:30:528489 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468490 EXPECT_EQ(100, response->headers->GetContentLength());
8491}
8492
bncd16676a2016-07-20 16:23:018493TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428494 HttpRequestInfo request;
8495 request.method = "GET";
bncce36dca22015-04-21 22:11:238496 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438497 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8498 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428499
danakj1fd259a02016-04-16 03:17:098500 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168501 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278502
[email protected]1c773ea12009-04-28 19:58:428503 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238504 MockWrite(
8505 "GET / HTTP/1.1\r\n"
8506 "Host: www.example.org\r\n"
8507 "Connection: keep-alive\r\n"
8508 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428509 };
8510
8511 // Lastly, the server responds with the actual content.
8512 MockRead data_reads[] = {
8513 MockRead("HTTP/1.0 200 OK\r\n"),
8514 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8515 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068516 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428517 };
8518
[email protected]31a2bfe2010-02-09 08:03:398519 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8520 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078521 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428522
[email protected]49639fa2011-12-20 23:22:418523 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428524
tfarina428341112016-09-22 13:38:208525 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018526 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428527
8528 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018529 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428530}
8531
bncd16676a2016-07-20 16:23:018532TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298533 HttpRequestInfo request;
8534 request.method = "GET";
bncce36dca22015-04-21 22:11:238535 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298536 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8537 "Chromium Ultra Awesome X Edition");
8538
rdsmith82957ad2015-09-16 19:42:038539 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098540 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168541 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278542
[email protected]da81f132010-08-18 23:39:298543 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178544 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8545 "Host: www.example.org:443\r\n"
8546 "Proxy-Connection: keep-alive\r\n"
8547 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298548 };
8549 MockRead data_reads[] = {
8550 // Return an error, so the transaction stops here (this test isn't
8551 // interested in the rest).
8552 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8553 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8554 MockRead("Proxy-Connection: close\r\n\r\n"),
8555 };
8556
8557 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8558 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078559 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298560
[email protected]49639fa2011-12-20 23:22:418561 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298562
tfarina428341112016-09-22 13:38:208563 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018564 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298565
8566 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018567 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298568}
8569
bncd16676a2016-07-20 16:23:018570TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428571 HttpRequestInfo request;
8572 request.method = "GET";
bncce36dca22015-04-21 22:11:238573 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168574 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8575 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428576
danakj1fd259a02016-04-16 03:17:098577 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168578 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278579
[email protected]1c773ea12009-04-28 19:58:428580 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238581 MockWrite(
8582 "GET / HTTP/1.1\r\n"
8583 "Host: www.example.org\r\n"
8584 "Connection: keep-alive\r\n"
8585 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428586 };
8587
8588 // Lastly, the server responds with the actual content.
8589 MockRead data_reads[] = {
8590 MockRead("HTTP/1.0 200 OK\r\n"),
8591 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8592 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068593 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428594 };
8595
[email protected]31a2bfe2010-02-09 08:03:398596 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8597 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078598 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428599
[email protected]49639fa2011-12-20 23:22:418600 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428601
tfarina428341112016-09-22 13:38:208602 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018603 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428604
8605 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018606 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428607}
8608
bncd16676a2016-07-20 16:23:018609TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428610 HttpRequestInfo request;
8611 request.method = "POST";
bncce36dca22015-04-21 22:11:238612 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428613
danakj1fd259a02016-04-16 03:17:098614 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168615 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278616
[email protected]1c773ea12009-04-28 19:58:428617 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238618 MockWrite(
8619 "POST / HTTP/1.1\r\n"
8620 "Host: www.example.org\r\n"
8621 "Connection: keep-alive\r\n"
8622 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428623 };
8624
8625 // Lastly, the server responds with the actual content.
8626 MockRead data_reads[] = {
8627 MockRead("HTTP/1.0 200 OK\r\n"),
8628 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8629 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068630 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428631 };
8632
[email protected]31a2bfe2010-02-09 08:03:398633 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8634 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078635 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428636
[email protected]49639fa2011-12-20 23:22:418637 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428638
tfarina428341112016-09-22 13:38:208639 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018640 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428641
8642 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018643 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428644}
8645
bncd16676a2016-07-20 16:23:018646TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428647 HttpRequestInfo request;
8648 request.method = "PUT";
bncce36dca22015-04-21 22:11:238649 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428650
danakj1fd259a02016-04-16 03:17:098651 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168652 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278653
[email protected]1c773ea12009-04-28 19:58:428654 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238655 MockWrite(
8656 "PUT / HTTP/1.1\r\n"
8657 "Host: www.example.org\r\n"
8658 "Connection: keep-alive\r\n"
8659 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428660 };
8661
8662 // Lastly, the server responds with the actual content.
8663 MockRead data_reads[] = {
8664 MockRead("HTTP/1.0 200 OK\r\n"),
8665 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8666 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068667 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428668 };
8669
[email protected]31a2bfe2010-02-09 08:03:398670 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8671 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078672 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428673
[email protected]49639fa2011-12-20 23:22:418674 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428675
tfarina428341112016-09-22 13:38:208676 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018677 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428678
8679 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018680 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428681}
8682
bncd16676a2016-07-20 16:23:018683TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428684 HttpRequestInfo request;
8685 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238686 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428687
danakj1fd259a02016-04-16 03:17:098688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278690
[email protected]1c773ea12009-04-28 19:58:428691 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138692 MockWrite("HEAD / HTTP/1.1\r\n"
8693 "Host: www.example.org\r\n"
8694 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428695 };
8696
8697 // Lastly, the server responds with the actual content.
8698 MockRead data_reads[] = {
8699 MockRead("HTTP/1.0 200 OK\r\n"),
8700 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8701 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068702 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428703 };
8704
[email protected]31a2bfe2010-02-09 08:03:398705 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8706 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078707 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428708
[email protected]49639fa2011-12-20 23:22:418709 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428710
tfarina428341112016-09-22 13:38:208711 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018712 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428713
8714 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018715 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428716}
8717
bncd16676a2016-07-20 16:23:018718TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428719 HttpRequestInfo request;
8720 request.method = "GET";
bncce36dca22015-04-21 22:11:238721 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428722 request.load_flags = LOAD_BYPASS_CACHE;
8723
danakj1fd259a02016-04-16 03:17:098724 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168725 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278726
[email protected]1c773ea12009-04-28 19:58:428727 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238728 MockWrite(
8729 "GET / HTTP/1.1\r\n"
8730 "Host: www.example.org\r\n"
8731 "Connection: keep-alive\r\n"
8732 "Pragma: no-cache\r\n"
8733 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428734 };
8735
8736 // Lastly, the server responds with the actual content.
8737 MockRead data_reads[] = {
8738 MockRead("HTTP/1.0 200 OK\r\n"),
8739 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8740 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068741 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428742 };
8743
[email protected]31a2bfe2010-02-09 08:03:398744 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8745 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078746 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428747
[email protected]49639fa2011-12-20 23:22:418748 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428749
tfarina428341112016-09-22 13:38:208750 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018751 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428752
8753 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018754 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428755}
8756
bncd16676a2016-07-20 16:23:018757TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428758 HttpRequestInfo request;
8759 request.method = "GET";
bncce36dca22015-04-21 22:11:238760 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428761 request.load_flags = LOAD_VALIDATE_CACHE;
8762
danakj1fd259a02016-04-16 03:17:098763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168764 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278765
[email protected]1c773ea12009-04-28 19:58:428766 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238767 MockWrite(
8768 "GET / HTTP/1.1\r\n"
8769 "Host: www.example.org\r\n"
8770 "Connection: keep-alive\r\n"
8771 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428772 };
8773
8774 // Lastly, the server responds with the actual content.
8775 MockRead data_reads[] = {
8776 MockRead("HTTP/1.0 200 OK\r\n"),
8777 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8778 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068779 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428780 };
8781
[email protected]31a2bfe2010-02-09 08:03:398782 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8783 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078784 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428785
[email protected]49639fa2011-12-20 23:22:418786 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428787
tfarina428341112016-09-22 13:38:208788 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018789 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428790
8791 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018792 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428793}
8794
bncd16676a2016-07-20 16:23:018795TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428796 HttpRequestInfo request;
8797 request.method = "GET";
bncce36dca22015-04-21 22:11:238798 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438799 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428800
danakj1fd259a02016-04-16 03:17:098801 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168802 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278803
[email protected]1c773ea12009-04-28 19:58:428804 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238805 MockWrite(
8806 "GET / HTTP/1.1\r\n"
8807 "Host: www.example.org\r\n"
8808 "Connection: keep-alive\r\n"
8809 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428810 };
8811
8812 // Lastly, the server responds with the actual content.
8813 MockRead data_reads[] = {
8814 MockRead("HTTP/1.0 200 OK\r\n"),
8815 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8816 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068817 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428818 };
8819
[email protected]31a2bfe2010-02-09 08:03:398820 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8821 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078822 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428823
[email protected]49639fa2011-12-20 23:22:418824 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428825
tfarina428341112016-09-22 13:38:208826 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018827 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428828
8829 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018830 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428831}
8832
bncd16676a2016-07-20 16:23:018833TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478834 HttpRequestInfo request;
8835 request.method = "GET";
bncce36dca22015-04-21 22:11:238836 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438837 request.extra_headers.SetHeader("referer", "www.foo.com");
8838 request.extra_headers.SetHeader("hEllo", "Kitty");
8839 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478840
danakj1fd259a02016-04-16 03:17:098841 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168842 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278843
[email protected]270c6412010-03-29 22:02:478844 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238845 MockWrite(
8846 "GET / HTTP/1.1\r\n"
8847 "Host: www.example.org\r\n"
8848 "Connection: keep-alive\r\n"
8849 "referer: www.foo.com\r\n"
8850 "hEllo: Kitty\r\n"
8851 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478852 };
8853
8854 // Lastly, the server responds with the actual content.
8855 MockRead data_reads[] = {
8856 MockRead("HTTP/1.0 200 OK\r\n"),
8857 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8858 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068859 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478860 };
8861
8862 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8863 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078864 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478865
[email protected]49639fa2011-12-20 23:22:418866 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478867
tfarina428341112016-09-22 13:38:208868 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018869 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:478870
8871 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018872 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:478873}
8874
bncd16676a2016-07-20 16:23:018875TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278876 HttpRequestInfo request;
8877 request.method = "GET";
bncce36dca22015-04-21 22:11:238878 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278879
rdsmith82957ad2015-09-16 19:42:038880 session_deps_.proxy_service =
8881 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518882 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078883 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028884
danakj1fd259a02016-04-16 03:17:098885 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168886 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028887
[email protected]3cd17242009-06-23 02:59:028888 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8889 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8890
8891 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238892 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8893 MockWrite(
8894 "GET / HTTP/1.1\r\n"
8895 "Host: www.example.org\r\n"
8896 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028897
8898 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068899 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028900 MockRead("HTTP/1.0 200 OK\r\n"),
8901 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8902 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068903 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028904 };
8905
[email protected]31a2bfe2010-02-09 08:03:398906 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8907 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078908 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028909
[email protected]49639fa2011-12-20 23:22:418910 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028911
tfarina428341112016-09-22 13:38:208912 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:028914
8915 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018916 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028917
bnc691fda62016-08-12 00:43:168918 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528919 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028920
tbansal2ecbbc72016-10-06 17:15:478921 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:208922 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168923 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208924 TestLoadTimingNotReusedWithPac(load_timing_info,
8925 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8926
[email protected]3cd17242009-06-23 02:59:028927 std::string response_text;
bnc691fda62016-08-12 00:43:168928 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018929 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028930 EXPECT_EQ("Payload", response_text);
8931}
8932
bncd16676a2016-07-20 16:23:018933TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278934 HttpRequestInfo request;
8935 request.method = "GET";
bncce36dca22015-04-21 22:11:238936 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278937
rdsmith82957ad2015-09-16 19:42:038938 session_deps_.proxy_service =
8939 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518940 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078941 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028942
danakj1fd259a02016-04-16 03:17:098943 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168944 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028945
[email protected]3cd17242009-06-23 02:59:028946 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8947 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8948
8949 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238950 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8951 arraysize(write_buffer)),
8952 MockWrite(
8953 "GET / HTTP/1.1\r\n"
8954 "Host: www.example.org\r\n"
8955 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028956
8957 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018958 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8959 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358960 MockRead("HTTP/1.0 200 OK\r\n"),
8961 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8962 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068963 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358964 };
8965
[email protected]31a2bfe2010-02-09 08:03:398966 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8967 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078968 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358969
[email protected]8ddf8322012-02-23 18:08:068970 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078971 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358972
[email protected]49639fa2011-12-20 23:22:418973 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358974
tfarina428341112016-09-22 13:38:208975 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:358977
8978 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018979 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:358980
[email protected]029c83b62013-01-24 05:28:208981 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168982 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208983 TestLoadTimingNotReusedWithPac(load_timing_info,
8984 CONNECT_TIMING_HAS_SSL_TIMES);
8985
bnc691fda62016-08-12 00:43:168986 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528987 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:478988 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:358989
8990 std::string response_text;
bnc691fda62016-08-12 00:43:168991 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018992 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:358993 EXPECT_EQ("Payload", response_text);
8994}
8995
bncd16676a2016-07-20 16:23:018996TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:208997 HttpRequestInfo request;
8998 request.method = "GET";
bncce36dca22015-04-21 22:11:238999 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209000
rdsmith82957ad2015-09-16 19:42:039001 session_deps_.proxy_service =
9002 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519003 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079004 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209005
danakj1fd259a02016-04-16 03:17:099006 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169007 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209008
9009 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9010 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9011
9012 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239013 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9014 MockWrite(
9015 "GET / HTTP/1.1\r\n"
9016 "Host: www.example.org\r\n"
9017 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209018
9019 MockRead data_reads[] = {
9020 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9021 MockRead("HTTP/1.0 200 OK\r\n"),
9022 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9023 MockRead("Payload"),
9024 MockRead(SYNCHRONOUS, OK)
9025 };
9026
9027 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9028 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079029 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209030
9031 TestCompletionCallback callback;
9032
tfarina428341112016-09-22 13:38:209033 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209035
9036 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019037 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209038
bnc691fda62016-08-12 00:43:169039 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529040 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209041
9042 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169043 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209044 TestLoadTimingNotReused(load_timing_info,
9045 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9046
9047 std::string response_text;
bnc691fda62016-08-12 00:43:169048 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019049 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209050 EXPECT_EQ("Payload", response_text);
9051}
9052
bncd16676a2016-07-20 16:23:019053TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279054 HttpRequestInfo request;
9055 request.method = "GET";
bncce36dca22015-04-21 22:11:239056 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279057
rdsmith82957ad2015-09-16 19:42:039058 session_deps_.proxy_service =
9059 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519060 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079061 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359062
danakj1fd259a02016-04-16 03:17:099063 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169064 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359065
[email protected]e0c27be2009-07-15 13:09:359066 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9067 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379068 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239069 0x05, // Version
9070 0x01, // Command (CONNECT)
9071 0x00, // Reserved.
9072 0x03, // Address type (DOMAINNAME).
9073 0x0F, // Length of domain (15)
9074 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9075 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379076 };
[email protected]e0c27be2009-07-15 13:09:359077 const char kSOCKS5OkResponse[] =
9078 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9079
9080 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239081 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9082 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9083 MockWrite(
9084 "GET / HTTP/1.1\r\n"
9085 "Host: www.example.org\r\n"
9086 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359087
9088 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019089 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9090 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359091 MockRead("HTTP/1.0 200 OK\r\n"),
9092 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9093 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069094 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359095 };
9096
[email protected]31a2bfe2010-02-09 08:03:399097 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9098 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079099 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359100
[email protected]49639fa2011-12-20 23:22:419101 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359102
tfarina428341112016-09-22 13:38:209103 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019104 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359105
9106 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019107 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359108
bnc691fda62016-08-12 00:43:169109 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529110 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479111 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359112
[email protected]029c83b62013-01-24 05:28:209113 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169114 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209115 TestLoadTimingNotReusedWithPac(load_timing_info,
9116 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9117
[email protected]e0c27be2009-07-15 13:09:359118 std::string response_text;
bnc691fda62016-08-12 00:43:169119 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019120 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359121 EXPECT_EQ("Payload", response_text);
9122}
9123
bncd16676a2016-07-20 16:23:019124TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279125 HttpRequestInfo request;
9126 request.method = "GET";
bncce36dca22015-04-21 22:11:239127 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279128
rdsmith82957ad2015-09-16 19:42:039129 session_deps_.proxy_service =
9130 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519131 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079132 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359133
danakj1fd259a02016-04-16 03:17:099134 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169135 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359136
[email protected]e0c27be2009-07-15 13:09:359137 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9138 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379139 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239140 0x05, // Version
9141 0x01, // Command (CONNECT)
9142 0x00, // Reserved.
9143 0x03, // Address type (DOMAINNAME).
9144 0x0F, // Length of domain (15)
9145 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9146 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379147 };
9148
[email protected]e0c27be2009-07-15 13:09:359149 const char kSOCKS5OkResponse[] =
9150 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9151
9152 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239153 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9154 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9155 arraysize(kSOCKS5OkRequest)),
9156 MockWrite(
9157 "GET / HTTP/1.1\r\n"
9158 "Host: www.example.org\r\n"
9159 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359160
9161 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019162 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9163 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029164 MockRead("HTTP/1.0 200 OK\r\n"),
9165 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9166 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069167 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029168 };
9169
[email protected]31a2bfe2010-02-09 08:03:399170 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9171 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079172 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029173
[email protected]8ddf8322012-02-23 18:08:069174 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079175 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029176
[email protected]49639fa2011-12-20 23:22:419177 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029178
tfarina428341112016-09-22 13:38:209179 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019180 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029181
9182 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019183 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029184
bnc691fda62016-08-12 00:43:169185 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529186 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479187 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029188
[email protected]029c83b62013-01-24 05:28:209189 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169190 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209191 TestLoadTimingNotReusedWithPac(load_timing_info,
9192 CONNECT_TIMING_HAS_SSL_TIMES);
9193
[email protected]3cd17242009-06-23 02:59:029194 std::string response_text;
bnc691fda62016-08-12 00:43:169195 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019196 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029197 EXPECT_EQ("Payload", response_text);
9198}
9199
[email protected]448d4ca52012-03-04 04:12:239200namespace {
9201
[email protected]04e5be32009-06-26 20:00:319202// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069203
9204struct GroupNameTest {
9205 std::string proxy_server;
9206 std::string url;
9207 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189208 bool ssl;
[email protected]2d731a32010-04-29 01:04:069209};
9210
danakj1fd259a02016-04-16 03:17:099211std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079212 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099213 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069214
bnc525e175a2016-06-20 12:36:409215 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539216 session->http_server_properties();
bnccacc0992015-03-20 20:22:229217 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:409218 AlternateProtocolFromNextProto(kProtoHTTP2), "", 444);
bnc7dc7e1b42015-07-28 14:43:129219 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229220 http_server_properties->SetAlternativeService(
bncaa60ff402016-06-22 19:12:429221 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469222 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069223
9224 return session;
9225}
9226
mmenkee65e7af2015-10-13 17:16:429227int GroupNameTransactionHelper(const std::string& url,
9228 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069229 HttpRequestInfo request;
9230 request.method = "GET";
9231 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069232
bnc691fda62016-08-12 00:43:169233 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279234
[email protected]49639fa2011-12-20 23:22:419235 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069236
9237 // We do not complete this request, the dtor will clean the transaction up.
tfarina428341112016-09-22 13:38:209238 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069239}
9240
[email protected]448d4ca52012-03-04 04:12:239241} // namespace
9242
bncd16676a2016-07-20 16:23:019243TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069244 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239245 {
9246 "", // unused
9247 "http://www.example.org/direct",
9248 "www.example.org:80",
9249 false,
9250 },
9251 {
9252 "", // unused
9253 "http://[2001:1418:13:1::25]/direct",
9254 "[2001:1418:13:1::25]:80",
9255 false,
9256 },
[email protected]04e5be32009-06-26 20:00:319257
bncce36dca22015-04-21 22:11:239258 // SSL Tests
9259 {
9260 "", // unused
9261 "https://www.example.org/direct_ssl",
9262 "ssl/www.example.org:443",
9263 true,
9264 },
9265 {
9266 "", // unused
9267 "https://[2001:1418:13:1::25]/direct",
9268 "ssl/[2001:1418:13:1::25]:443",
9269 true,
9270 },
9271 {
9272 "", // unused
bncaa60ff402016-06-22 19:12:429273 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239274 "ssl/host.with.alternate:443",
9275 true,
9276 },
[email protected]2d731a32010-04-29 01:04:069277 };
[email protected]2ff8b312010-04-26 22:20:549278
viettrungluue4a8b882014-10-16 06:17:389279 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039280 session_deps_.proxy_service =
9281 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099282 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409283 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069284
mmenkee65e7af2015-10-13 17:16:429285 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289286 CaptureGroupNameTransportSocketPool* transport_conn_pool =
9287 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139288 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349289 new CaptureGroupNameSSLSocketPool(NULL, NULL);
danakj1fd259a02016-04-16 03:17:099290 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449291 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029292 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9293 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489294 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069295
9296 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429297 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189298 if (tests[i].ssl)
9299 EXPECT_EQ(tests[i].expected_group_name,
9300 ssl_conn_pool->last_group_name_received());
9301 else
9302 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289303 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069304 }
[email protected]2d731a32010-04-29 01:04:069305}
9306
bncd16676a2016-07-20 16:23:019307TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069308 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239309 {
9310 "http_proxy",
9311 "http://www.example.org/http_proxy_normal",
9312 "www.example.org:80",
9313 false,
9314 },
[email protected]2d731a32010-04-29 01:04:069315
bncce36dca22015-04-21 22:11:239316 // SSL Tests
9317 {
9318 "http_proxy",
9319 "https://www.example.org/http_connect_ssl",
9320 "ssl/www.example.org:443",
9321 true,
9322 },
[email protected]af3490e2010-10-16 21:02:299323
bncce36dca22015-04-21 22:11:239324 {
9325 "http_proxy",
bncaa60ff402016-06-22 19:12:429326 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239327 "ssl/host.with.alternate:443",
9328 true,
9329 },
[email protected]45499252013-01-23 17:12:569330
bncce36dca22015-04-21 22:11:239331 {
9332 "http_proxy",
9333 "ftp://ftp.google.com/http_proxy_normal",
9334 "ftp/ftp.google.com:21",
9335 false,
9336 },
[email protected]2d731a32010-04-29 01:04:069337 };
9338
viettrungluue4a8b882014-10-16 06:17:389339 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039340 session_deps_.proxy_service =
9341 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099342 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409343 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069344
mmenkee65e7af2015-10-13 17:16:429345 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069346
[email protected]e60e47a2010-07-14 03:37:189347 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139348 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349349 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139350 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349351 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029352
danakj1fd259a02016-04-16 03:17:099353 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449354 new MockClientSocketPoolManager);
aviadef3442016-10-03 18:50:399355 mock_pool_manager->SetSocketPoolForHTTPProxy(
9356 proxy_host, base::WrapUnique(http_proxy_pool));
9357 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9358 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489359 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069360
9361 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429362 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189363 if (tests[i].ssl)
9364 EXPECT_EQ(tests[i].expected_group_name,
9365 ssl_conn_pool->last_group_name_received());
9366 else
9367 EXPECT_EQ(tests[i].expected_group_name,
9368 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069369 }
[email protected]2d731a32010-04-29 01:04:069370}
9371
bncd16676a2016-07-20 16:23:019372TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069373 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239374 {
9375 "socks4://socks_proxy:1080",
9376 "http://www.example.org/socks4_direct",
9377 "socks4/www.example.org:80",
9378 false,
9379 },
9380 {
9381 "socks5://socks_proxy:1080",
9382 "http://www.example.org/socks5_direct",
9383 "socks5/www.example.org:80",
9384 false,
9385 },
[email protected]2d731a32010-04-29 01:04:069386
bncce36dca22015-04-21 22:11:239387 // SSL Tests
9388 {
9389 "socks4://socks_proxy:1080",
9390 "https://www.example.org/socks4_ssl",
9391 "socks4/ssl/www.example.org:443",
9392 true,
9393 },
9394 {
9395 "socks5://socks_proxy:1080",
9396 "https://www.example.org/socks5_ssl",
9397 "socks5/ssl/www.example.org:443",
9398 true,
9399 },
[email protected]af3490e2010-10-16 21:02:299400
bncce36dca22015-04-21 22:11:239401 {
9402 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429403 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239404 "socks4/ssl/host.with.alternate:443",
9405 true,
9406 },
[email protected]04e5be32009-06-26 20:00:319407 };
9408
viettrungluue4a8b882014-10-16 06:17:389409 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039410 session_deps_.proxy_service =
9411 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099412 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409413 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029414
mmenkee65e7af2015-10-13 17:16:429415 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319416
[email protected]e60e47a2010-07-14 03:37:189417 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139418 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349419 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139420 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349421 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029422
danakj1fd259a02016-04-16 03:17:099423 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449424 new MockClientSocketPoolManager);
aviadef3442016-10-03 18:50:399425 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9426 proxy_host, base::WrapUnique(socks_conn_pool));
9427 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9428 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489429 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319430
bnc691fda62016-08-12 00:43:169431 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319432
[email protected]2d731a32010-04-29 01:04:069433 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429434 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189435 if (tests[i].ssl)
9436 EXPECT_EQ(tests[i].expected_group_name,
9437 ssl_conn_pool->last_group_name_received());
9438 else
9439 EXPECT_EQ(tests[i].expected_group_name,
9440 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319441 }
9442}
9443
bncd16676a2016-07-20 16:23:019444TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279445 HttpRequestInfo request;
9446 request.method = "GET";
bncce36dca22015-04-21 22:11:239447 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279448
rdsmith82957ad2015-09-16 19:42:039449 session_deps_.proxy_service =
9450 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329451
[email protected]69719062010-01-05 20:09:219452 // This simulates failure resolving all hostnames; that means we will fail
9453 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079454 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329455
danakj1fd259a02016-04-16 03:17:099456 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169457 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259458
[email protected]49639fa2011-12-20 23:22:419459 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259460
tfarina428341112016-09-22 13:38:209461 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019462 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259463
[email protected]9172a982009-06-06 00:30:259464 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019465 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259466}
9467
[email protected]685af592010-05-11 19:31:249468// Base test to make sure that when the load flags for a request specify to
9469// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029470void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079471 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279472 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109473 HttpRequestInfo request_info;
9474 request_info.method = "GET";
9475 request_info.load_flags = load_flags;
9476 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279477
[email protected]a2c2fb92009-07-18 07:31:049478 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:079479 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:329480
danakj1fd259a02016-04-16 03:17:099481 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169482 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289483
bncce36dca22015-04-21 22:11:239484 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289485 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299486 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109487 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079488 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239489 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109490 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina428341112016-09-22 13:38:209491 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019492 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479493 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019494 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289495
9496 // Verify that it was added to host cache, by doing a subsequent async lookup
9497 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109498 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079499 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239500 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109501 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina428341112016-09-22 13:38:209502 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019503 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289504
bncce36dca22015-04-21 22:11:239505 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289506 // we can tell if the next lookup hit the cache, or the "network".
9507 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239508 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289509
9510 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9511 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069512 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399513 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079514 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289515
[email protected]3b9cca42009-06-16 01:08:289516 // Run the request.
tfarina428341112016-09-22 13:38:209517 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019518 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419519 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289520
9521 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239522 // "www.example.org".
robpercival214763f2016-07-01 23:27:019523 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289524}
9525
[email protected]685af592010-05-11 19:31:249526// There are multiple load flags that should trigger the host cache bypass.
9527// Test each in isolation:
bncd16676a2016-07-20 16:23:019528TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249529 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9530}
9531
bncd16676a2016-07-20 16:23:019532TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249533 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9534}
9535
bncd16676a2016-07-20 16:23:019536TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249537 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9538}
9539
[email protected]0877e3d2009-10-17 22:29:579540// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019541TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579542 HttpRequestInfo request;
9543 request.method = "GET";
9544 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579545
9546 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069547 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579548 };
[email protected]31a2bfe2010-02-09 08:03:399549 StaticSocketDataProvider data(NULL, 0,
9550 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079551 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099552 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579553
[email protected]49639fa2011-12-20 23:22:419554 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579555
bnc691fda62016-08-12 00:43:169556 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579557
tfarina428341112016-09-22 13:38:209558 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019559 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579560
9561 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019562 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599563
9564 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169565 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599566 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579567}
9568
zmo9528c9f42015-08-04 22:12:089569// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019570TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579571 HttpRequestInfo request;
9572 request.method = "GET";
9573 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579574
9575 MockRead data_reads[] = {
9576 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069577 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579578 };
9579
[email protected]31a2bfe2010-02-09 08:03:399580 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079581 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579583
[email protected]49639fa2011-12-20 23:22:419584 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579585
bnc691fda62016-08-12 00:43:169586 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579587
tfarina428341112016-09-22 13:38:209588 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019589 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579590
9591 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019592 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089593
bnc691fda62016-08-12 00:43:169594 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529595 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089596
wezca1070932016-05-26 20:30:529597 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089598 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9599
9600 std::string response_data;
bnc691fda62016-08-12 00:43:169601 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019602 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089603 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599604
9605 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169606 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599607 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579608}
9609
9610// Make sure that a dropped connection while draining the body for auth
9611// restart does the right thing.
bncd16676a2016-07-20 16:23:019612TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579613 HttpRequestInfo request;
9614 request.method = "GET";
bncce36dca22015-04-21 22:11:239615 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579616
9617 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239618 MockWrite(
9619 "GET / HTTP/1.1\r\n"
9620 "Host: www.example.org\r\n"
9621 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579622 };
9623
9624 MockRead data_reads1[] = {
9625 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9626 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9627 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9628 MockRead("Content-Length: 14\r\n\r\n"),
9629 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069630 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579631 };
9632
[email protected]31a2bfe2010-02-09 08:03:399633 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9634 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079635 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579636
bnc691fda62016-08-12 00:43:169637 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579638 // be issuing -- the final header line contains the credentials.
9639 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239640 MockWrite(
9641 "GET / HTTP/1.1\r\n"
9642 "Host: www.example.org\r\n"
9643 "Connection: keep-alive\r\n"
9644 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579645 };
9646
9647 // Lastly, the server responds with the actual content.
9648 MockRead data_reads2[] = {
9649 MockRead("HTTP/1.1 200 OK\r\n"),
9650 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9651 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069652 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579653 };
9654
[email protected]31a2bfe2010-02-09 08:03:399655 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9656 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079657 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099658 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579659
[email protected]49639fa2011-12-20 23:22:419660 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579661
bnc691fda62016-08-12 00:43:169662 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509663
tfarina428341112016-09-22 13:38:209664 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579666
9667 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019668 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579669
bnc691fda62016-08-12 00:43:169670 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529671 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049672 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579673
[email protected]49639fa2011-12-20 23:22:419674 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579675
bnc691fda62016-08-12 00:43:169676 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019677 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579678
9679 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019680 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579681
bnc691fda62016-08-12 00:43:169682 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529683 ASSERT_TRUE(response);
9684 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579685 EXPECT_EQ(100, response->headers->GetContentLength());
9686}
9687
9688// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019689TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039690 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579691
9692 HttpRequestInfo request;
9693 request.method = "GET";
bncce36dca22015-04-21 22:11:239694 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579695
9696 MockRead proxy_reads[] = {
9697 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069698 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579699 };
9700
[email protected]31a2bfe2010-02-09 08:03:399701 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069702 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579703
[email protected]bb88e1d32013-05-03 23:11:079704 session_deps_.socket_factory->AddSocketDataProvider(&data);
9705 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579706
[email protected]49639fa2011-12-20 23:22:419707 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579708
[email protected]bb88e1d32013-05-03 23:11:079709 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579710
danakj1fd259a02016-04-16 03:17:099711 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169712 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579713
tfarina428341112016-09-22 13:38:209714 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579716
9717 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019718 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:579719}
9720
bncd16676a2016-07-20 16:23:019721TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469722 HttpRequestInfo request;
9723 request.method = "GET";
bncce36dca22015-04-21 22:11:239724 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469725
danakj1fd259a02016-04-16 03:17:099726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169727 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279728
[email protected]e22e1362009-11-23 21:31:129729 MockRead data_reads[] = {
9730 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069731 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129732 };
[email protected]9492e4a2010-02-24 00:58:469733
9734 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079735 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469736
[email protected]49639fa2011-12-20 23:22:419737 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469738
tfarina428341112016-09-22 13:38:209739 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:469741
robpercival214763f2016-07-01 23:27:019742 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:469743
bnc691fda62016-08-12 00:43:169744 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529745 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469746
wezca1070932016-05-26 20:30:529747 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469748 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9749
9750 std::string response_data;
bnc691fda62016-08-12 00:43:169751 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019752 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:129753}
9754
bncd16676a2016-07-20 16:23:019755TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159756 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529757 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149758 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219759 UploadFileElementReader::ScopedOverridingContentLengthForTests
9760 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339761
danakj1fd259a02016-04-16 03:17:099762 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079763 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149764 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:079765 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229766 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279767
9768 HttpRequestInfo request;
9769 request.method = "POST";
bncce36dca22015-04-21 22:11:239770 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279771 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279772
danakj1fd259a02016-04-16 03:17:099773 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169774 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:339775
9776 MockRead data_reads[] = {
9777 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9778 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069779 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339780 };
[email protected]31a2bfe2010-02-09 08:03:399781 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079782 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339783
[email protected]49639fa2011-12-20 23:22:419784 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339785
tfarina428341112016-09-22 13:38:209786 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019787 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:339788
9789 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019790 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:339791
bnc691fda62016-08-12 00:43:169792 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529793 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339794
maksim.sisove869bf52016-06-23 17:11:529795 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339796
[email protected]dd3aa792013-07-16 19:10:239797 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339798}
9799
bncd16676a2016-07-20 16:23:019800TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159801 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529802 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369803 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:309804 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:369805 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119806 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369807
danakj1fd259a02016-04-16 03:17:099808 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079809 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149810 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:079811 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229812 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279813
9814 HttpRequestInfo request;
9815 request.method = "POST";
bncce36dca22015-04-21 22:11:239816 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279817 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279818
[email protected]999dd8c2013-11-12 06:45:549819 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099820 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169821 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:369822
[email protected]999dd8c2013-11-12 06:45:549823 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079824 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369825
[email protected]49639fa2011-12-20 23:22:419826 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369827
tfarina428341112016-09-22 13:38:209828 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019829 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:369830
9831 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019832 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:369833
[email protected]dd3aa792013-07-16 19:10:239834 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369835}
9836
bncd16676a2016-07-20 16:23:019837TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:039838 class FakeUploadElementReader : public UploadElementReader {
9839 public:
9840 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209841 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039842
9843 const CompletionCallback& callback() const { return callback_; }
9844
9845 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209846 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039847 callback_ = callback;
9848 return ERR_IO_PENDING;
9849 }
avibf0746c2015-12-09 19:53:149850 uint64_t GetContentLength() const override { return 0; }
9851 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209852 int Read(IOBuffer* buf,
9853 int buf_length,
9854 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039855 return ERR_FAILED;
9856 }
9857
9858 private:
9859 CompletionCallback callback_;
9860 };
9861
9862 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099863 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9864 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229865 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039866
9867 HttpRequestInfo request;
9868 request.method = "POST";
bncce36dca22015-04-21 22:11:239869 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039870 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:039871
danakj1fd259a02016-04-16 03:17:099872 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169873 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:419874 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039875
9876 StaticSocketDataProvider data;
9877 session_deps_.socket_factory->AddSocketDataProvider(&data);
9878
9879 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:209880 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:559882 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039883
9884 // Transaction is pending on request body initialization.
9885 ASSERT_FALSE(fake_reader->callback().is_null());
9886
9887 // Return Init()'s result after the transaction gets destroyed.
9888 trans.reset();
9889 fake_reader->callback().Run(OK); // Should not crash.
9890}
9891
[email protected]aeefc9e82010-02-19 16:18:279892// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:019893TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279894 HttpRequestInfo request;
9895 request.method = "GET";
bncce36dca22015-04-21 22:11:239896 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279897
9898 // First transaction will request a resource and receive a Basic challenge
9899 // with realm="first_realm".
9900 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239901 MockWrite(
9902 "GET / HTTP/1.1\r\n"
9903 "Host: www.example.org\r\n"
9904 "Connection: keep-alive\r\n"
9905 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279906 };
9907 MockRead data_reads1[] = {
9908 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9909 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9910 "\r\n"),
9911 };
9912
bnc691fda62016-08-12 00:43:169913 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:279914 // for first_realm. The server will reject and provide a challenge with
9915 // second_realm.
9916 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239917 MockWrite(
9918 "GET / HTTP/1.1\r\n"
9919 "Host: www.example.org\r\n"
9920 "Connection: keep-alive\r\n"
9921 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9922 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279923 };
9924 MockRead data_reads2[] = {
9925 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9926 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9927 "\r\n"),
9928 };
9929
9930 // This again fails, and goes back to first_realm. Make sure that the
9931 // entry is removed from cache.
9932 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239933 MockWrite(
9934 "GET / HTTP/1.1\r\n"
9935 "Host: www.example.org\r\n"
9936 "Connection: keep-alive\r\n"
9937 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9938 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279939 };
9940 MockRead data_reads3[] = {
9941 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9942 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9943 "\r\n"),
9944 };
9945
9946 // Try one last time (with the correct password) and get the resource.
9947 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239948 MockWrite(
9949 "GET / HTTP/1.1\r\n"
9950 "Host: www.example.org\r\n"
9951 "Connection: keep-alive\r\n"
9952 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9953 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279954 };
9955 MockRead data_reads4[] = {
9956 MockRead("HTTP/1.1 200 OK\r\n"
9957 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509958 "Content-Length: 5\r\n"
9959 "\r\n"
9960 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279961 };
9962
9963 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9964 data_writes1, arraysize(data_writes1));
9965 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9966 data_writes2, arraysize(data_writes2));
9967 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9968 data_writes3, arraysize(data_writes3));
9969 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9970 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079971 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9972 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9973 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9974 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279975
[email protected]49639fa2011-12-20 23:22:419976 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279977
danakj1fd259a02016-04-16 03:17:099978 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169979 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509980
[email protected]aeefc9e82010-02-19 16:18:279981 // Issue the first request with Authorize headers. There should be a
9982 // password prompt for first_realm waiting to be filled in after the
9983 // transaction completes.
tfarina428341112016-09-22 13:38:209984 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:279986 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019987 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169988 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529989 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049990 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529991 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049992 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:439993 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:049994 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199995 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279996
9997 // Issue the second request with an incorrect password. There should be a
9998 // password prompt for second_realm waiting to be filled in after the
9999 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110000 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610001 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10002 callback2.callback());
robpercival214763f2016-07-01 23:27:0110003 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710004 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110005 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610006 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210007 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410008 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210009 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410010 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310011 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410012 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910013 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710014
10015 // Issue the third request with another incorrect password. There should be
10016 // a password prompt for first_realm waiting to be filled in. If the password
10017 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10018 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110019 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610020 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10021 callback3.callback());
robpercival214763f2016-07-01 23:27:0110022 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710023 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110024 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610025 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210026 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410027 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210028 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410029 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310030 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410031 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910032 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710033
10034 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110035 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610036 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10037 callback4.callback());
robpercival214763f2016-07-01 23:27:0110038 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710039 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110040 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610041 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210042 ASSERT_TRUE(response);
10043 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710044}
10045
bncd16676a2016-07-20 16:23:0110046TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210047 MockRead data_reads[] = {
10048 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310049 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210050 MockRead("\r\n"),
10051 MockRead("hello world"),
10052 MockRead(SYNCHRONOUS, OK),
10053 };
10054
10055 HttpRequestInfo request;
10056 request.method = "GET";
bncb26024382016-06-29 02:39:4510057 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210058
10059 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210060 session_deps_.socket_factory->AddSocketDataProvider(&data);
10061
bncb26024382016-06-29 02:39:4510062 SSLSocketDataProvider ssl(ASYNC, OK);
10063 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10064
bncc958faa2015-07-31 18:14:5210065 TestCompletionCallback callback;
10066
danakj1fd259a02016-04-16 03:17:0910067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610068 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210069
tfarina428341112016-09-22 13:38:2010070 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210072
bncb26024382016-06-29 02:39:4510073 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010074 HttpServerProperties* http_server_properties =
10075 session->http_server_properties();
bncc958faa2015-07-31 18:14:5210076 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010077 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210078 EXPECT_TRUE(alternative_service_vector.empty());
10079
robpercival214763f2016-07-01 23:27:0110080 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210081
bnc691fda62016-08-12 00:43:1610082 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210083 ASSERT_TRUE(response);
10084 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210085 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10086 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210087 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210088
10089 std::string response_data;
bnc691fda62016-08-12 00:43:1610090 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210091 EXPECT_EQ("hello world", response_data);
10092
10093 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010094 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210095 ASSERT_EQ(1u, alternative_service_vector.size());
bnca9b9e222016-07-11 20:10:4010096 EXPECT_EQ(AlternateProtocolFromNextProto(kProtoHTTP2),
bncc958faa2015-07-31 18:14:5210097 alternative_service_vector[0].protocol);
bncb26024382016-06-29 02:39:4510098 EXPECT_EQ("mail.example.org", alternative_service_vector[0].host);
bncc958faa2015-07-31 18:14:5210099 EXPECT_EQ(443, alternative_service_vector[0].port);
10100}
10101
bnce3dd56f2016-06-01 10:37:1110102// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110103TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110104 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110105 MockRead data_reads[] = {
10106 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310107 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110108 MockRead("\r\n"),
10109 MockRead("hello world"),
10110 MockRead(SYNCHRONOUS, OK),
10111 };
10112
10113 HttpRequestInfo request;
10114 request.method = "GET";
10115 request.url = GURL("http://www.example.org/");
10116 request.load_flags = 0;
10117
10118 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10119 session_deps_.socket_factory->AddSocketDataProvider(&data);
10120
10121 TestCompletionCallback callback;
10122
10123 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610124 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110125
10126 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010127 HttpServerProperties* http_server_properties =
10128 session->http_server_properties();
bnce3dd56f2016-06-01 10:37:1110129 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010130 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:1110131 EXPECT_TRUE(alternative_service_vector.empty());
10132
tfarina428341112016-09-22 13:38:2010133 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10135 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110136
bnc691fda62016-08-12 00:43:1610137 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110138 ASSERT_TRUE(response);
10139 ASSERT_TRUE(response->headers);
10140 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10141 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210142 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110143
10144 std::string response_data;
bnc691fda62016-08-12 00:43:1610145 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110146 EXPECT_EQ("hello world", response_data);
10147
10148 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010149 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:1110150 EXPECT_TRUE(alternative_service_vector.empty());
10151}
10152
bnc8bef8da22016-05-30 01:28:2510153// HTTP/2 Alternative Services should be disabled if alternative service
10154// hostname is different from that of origin.
10155// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110156TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510157 DisableHTTP2AlternativeServicesWithDifferentHost) {
bncb26024382016-06-29 02:39:4510158 session_deps_.enable_http2_alternative_service_with_different_host = false;
10159
bnc8bef8da22016-05-30 01:28:2510160 HttpRequestInfo request;
10161 request.method = "GET";
bncb26024382016-06-29 02:39:4510162 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510163 request.load_flags = 0;
10164
10165 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10166 StaticSocketDataProvider first_data;
10167 first_data.set_connect_data(mock_connect);
10168 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510169 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610170 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510171 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510172
10173 MockRead data_reads[] = {
10174 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10175 MockRead(ASYNC, OK),
10176 };
10177 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10178 0);
10179 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10180
10181 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10182
bnc525e175a2016-06-20 12:36:4010183 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510184 session->http_server_properties();
10185 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010186 AlternateProtocolFromNextProto(kProtoHTTP2), "different.example.org",
bnc8bef8da22016-05-30 01:28:2510187 444);
10188 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10189 http_server_properties->SetAlternativeService(
10190 url::SchemeHostPort(request.url), alternative_service, expiration);
10191
bnc691fda62016-08-12 00:43:1610192 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510193 TestCompletionCallback callback;
10194
tfarina428341112016-09-22 13:38:2010195 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510196 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110197 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510198}
10199
bnce3dd56f2016-06-01 10:37:1110200// Regression test for https://crbug.com/615497:
10201// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110202TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110203 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110204 HttpRequestInfo request;
10205 request.method = "GET";
10206 request.url = GURL("http://www.example.org/");
10207 request.load_flags = 0;
10208
10209 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10210 StaticSocketDataProvider first_data;
10211 first_data.set_connect_data(mock_connect);
10212 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10213
10214 MockRead data_reads[] = {
10215 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10216 MockRead(ASYNC, OK),
10217 };
10218 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10219 0);
10220 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10221
10222 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10223
bnc525e175a2016-06-20 12:36:4010224 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110225 session->http_server_properties();
10226 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010227 AlternateProtocolFromNextProto(kProtoHTTP2), "", 444);
bnce3dd56f2016-06-01 10:37:1110228 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10229 http_server_properties->SetAlternativeService(
10230 url::SchemeHostPort(request.url), alternative_service, expiration);
10231
bnc691fda62016-08-12 00:43:1610232 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110233 TestCompletionCallback callback;
10234
tfarina428341112016-09-22 13:38:2010235 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110236 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110237 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110238}
10239
bncd16676a2016-07-20 16:23:0110240TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810241 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910242 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010243 HttpServerProperties* http_server_properties =
10244 session->http_server_properties();
bncb26024382016-06-29 02:39:4510245 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc4f575852015-10-14 18:35:0810246 AlternativeService alternative_service(QUIC, "", 80);
10247 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc525e175a2016-06-20 12:36:4010248 http_server_properties->SetAlternativeService(
10249 test_server, alternative_service, expiration);
bnc4f575852015-10-14 18:35:0810250 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010251 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810252 EXPECT_EQ(1u, alternative_service_vector.size());
10253
10254 // Send a clear header.
10255 MockRead data_reads[] = {
10256 MockRead("HTTP/1.1 200 OK\r\n"),
10257 MockRead("Alt-Svc: clear\r\n"),
10258 MockRead("\r\n"),
10259 MockRead("hello world"),
10260 MockRead(SYNCHRONOUS, OK),
10261 };
10262 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10263 session_deps_.socket_factory->AddSocketDataProvider(&data);
10264
bncb26024382016-06-29 02:39:4510265 SSLSocketDataProvider ssl(ASYNC, OK);
10266 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10267
bnc4f575852015-10-14 18:35:0810268 HttpRequestInfo request;
10269 request.method = "GET";
bncb26024382016-06-29 02:39:4510270 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810271
10272 TestCompletionCallback callback;
10273
bnc691fda62016-08-12 00:43:1610274 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810275
tfarina428341112016-09-22 13:38:2010276 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110277 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810278
bnc691fda62016-08-12 00:43:1610279 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210280 ASSERT_TRUE(response);
10281 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810282 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10283 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210284 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810285
10286 std::string response_data;
bnc691fda62016-08-12 00:43:1610287 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810288 EXPECT_EQ("hello world", response_data);
10289
10290 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010291 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810292 EXPECT_TRUE(alternative_service_vector.empty());
10293}
10294
bncd16676a2016-07-20 16:23:0110295TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210296 MockRead data_reads[] = {
10297 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310298 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10299 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210300 MockRead("hello world"),
10301 MockRead(SYNCHRONOUS, OK),
10302 };
10303
10304 HttpRequestInfo request;
10305 request.method = "GET";
bncb26024382016-06-29 02:39:4510306 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210307
10308 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210309 session_deps_.socket_factory->AddSocketDataProvider(&data);
10310
bncb26024382016-06-29 02:39:4510311 SSLSocketDataProvider ssl(ASYNC, OK);
10312 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10313
bncc958faa2015-07-31 18:14:5210314 TestCompletionCallback callback;
10315
danakj1fd259a02016-04-16 03:17:0910316 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610317 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210318
tfarina428341112016-09-22 13:38:2010319 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110320 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210321
bncb26024382016-06-29 02:39:4510322 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010323 HttpServerProperties* http_server_properties =
10324 session->http_server_properties();
bncc958faa2015-07-31 18:14:5210325 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010326 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210327 EXPECT_TRUE(alternative_service_vector.empty());
10328
robpercival214763f2016-07-01 23:27:0110329 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210330
bnc691fda62016-08-12 00:43:1610331 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210332 ASSERT_TRUE(response);
10333 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210334 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10335 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210336 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210337
10338 std::string response_data;
bnc691fda62016-08-12 00:43:1610339 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210340 EXPECT_EQ("hello world", response_data);
10341
10342 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010343 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210344 ASSERT_EQ(2u, alternative_service_vector.size());
bnca9b9e222016-07-11 20:10:4010345 EXPECT_EQ(AlternateProtocolFromNextProto(kProtoHTTP2),
bncc958faa2015-07-31 18:14:5210346 alternative_service_vector[0].protocol);
10347 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
10348 EXPECT_EQ(443, alternative_service_vector[0].port);
bnca9b9e222016-07-11 20:10:4010349 EXPECT_EQ(AlternateProtocolFromNextProto(kProtoHTTP2),
bnc3f0118e2016-02-02 15:42:2210350 alternative_service_vector[1].protocol);
bncc958faa2015-07-31 18:14:5210351 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
10352 EXPECT_EQ(1234, alternative_service_vector[1].port);
10353}
10354
bncd16676a2016-07-20 16:23:0110355TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610356 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210357 HostPortPair alternative("alternative.example.org", 443);
10358 std::string origin_url = "https://origin.example.org:443";
10359 std::string alternative_url = "https://alternative.example.org:443";
10360
10361 // Negotiate HTTP/1.1 with alternative.example.org.
10362 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610363 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210364 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10365
10366 // HTTP/1.1 data for request.
10367 MockWrite http_writes[] = {
10368 MockWrite("GET / HTTP/1.1\r\n"
10369 "Host: alternative.example.org\r\n"
10370 "Connection: keep-alive\r\n\r\n"),
10371 };
10372
10373 MockRead http_reads[] = {
10374 MockRead("HTTP/1.1 200 OK\r\n"
10375 "Content-Type: text/html; charset=iso-8859-1\r\n"
10376 "Content-Length: 40\r\n\r\n"
10377 "first HTTP/1.1 response from alternative"),
10378 };
10379 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10380 http_writes, arraysize(http_writes));
10381 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10382
10383 StaticSocketDataProvider data_refused;
10384 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10385 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10386
zhongyi3d4a55e72016-04-22 20:36:4610387 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910388 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010389 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210390 session->http_server_properties();
10391 AlternativeService alternative_service(QUIC, alternative);
10392 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610393 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5010394 expiration);
zhongyi48704c182015-12-07 07:52:0210395 // Mark the QUIC alternative service as broken.
10396 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10397
bnc691fda62016-08-12 00:43:1610398 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210399 HttpRequestInfo request;
10400 request.method = "GET";
10401 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210402 TestCompletionCallback callback;
10403 NetErrorDetails details;
10404 EXPECT_FALSE(details.quic_broken);
10405
tfarina428341112016-09-22 13:38:2010406 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610407 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210408 EXPECT_TRUE(details.quic_broken);
10409}
10410
bncd16676a2016-07-20 16:23:0110411TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610412 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210413 HostPortPair alternative1("alternative1.example.org", 443);
10414 HostPortPair alternative2("alternative2.example.org", 443);
10415 std::string origin_url = "https://origin.example.org:443";
10416 std::string alternative_url1 = "https://alternative1.example.org:443";
10417 std::string alternative_url2 = "https://alternative2.example.org:443";
10418
10419 // Negotiate HTTP/1.1 with alternative1.example.org.
10420 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610421 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210422 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10423
10424 // HTTP/1.1 data for request.
10425 MockWrite http_writes[] = {
10426 MockWrite("GET / HTTP/1.1\r\n"
10427 "Host: alternative1.example.org\r\n"
10428 "Connection: keep-alive\r\n\r\n"),
10429 };
10430
10431 MockRead http_reads[] = {
10432 MockRead("HTTP/1.1 200 OK\r\n"
10433 "Content-Type: text/html; charset=iso-8859-1\r\n"
10434 "Content-Length: 40\r\n\r\n"
10435 "first HTTP/1.1 response from alternative1"),
10436 };
10437 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10438 http_writes, arraysize(http_writes));
10439 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10440
10441 StaticSocketDataProvider data_refused;
10442 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10443 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10444
danakj1fd259a02016-04-16 03:17:0910445 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010446 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210447 session->http_server_properties();
10448
zhongyi3d4a55e72016-04-22 20:36:4610449 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210450 AlternativeServiceInfoVector alternative_service_info_vector;
10451 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10452
10453 AlternativeService alternative_service1(QUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010454 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210455 expiration);
10456 alternative_service_info_vector.push_back(alternative_service_info1);
10457 AlternativeService alternative_service2(QUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010458 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210459 expiration);
10460 alternative_service_info_vector.push_back(alternative_service_info2);
10461
10462 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610463 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210464
10465 // Mark one of the QUIC alternative service as broken.
10466 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
10467
10468 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610469 http_server_properties->GetAlternativeServices(server);
zhongyi48704c182015-12-07 07:52:0210470
bnc691fda62016-08-12 00:43:1610471 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210472 HttpRequestInfo request;
10473 request.method = "GET";
10474 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210475 TestCompletionCallback callback;
10476 NetErrorDetails details;
10477 EXPECT_FALSE(details.quic_broken);
10478
tfarina428341112016-09-22 13:38:2010479 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610480 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210481 EXPECT_FALSE(details.quic_broken);
10482}
10483
bncd16676a2016-07-20 16:23:0110484TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210485 HttpRequestInfo request;
10486 request.method = "GET";
bncb26024382016-06-29 02:39:4510487 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210488
[email protected]d973e99a2012-02-17 21:02:3610489 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210490 StaticSocketDataProvider first_data;
10491 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710492 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510493 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610494 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510495 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210496
10497 MockRead data_reads[] = {
10498 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10499 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610500 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210501 };
10502 StaticSocketDataProvider second_data(
10503 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710504 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210505
danakj1fd259a02016-04-16 03:17:0910506 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210507
bnc525e175a2016-06-20 12:36:4010508 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310509 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610510 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110511 // Port must be < 1024, or the header will be ignored (since initial port was
10512 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010513 const AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010514 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bncd9b132e2015-07-08 05:16:1010515 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210516 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610517 http_server_properties->SetAlternativeService(server, alternative_service,
10518 expiration);
[email protected]564b4912010-03-09 16:30:4210519
bnc691fda62016-08-12 00:43:1610520 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110521 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210522
tfarina428341112016-09-22 13:38:2010523 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110524 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10525 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210526
bnc691fda62016-08-12 00:43:1610527 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210528 ASSERT_TRUE(response);
10529 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210530 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10531
10532 std::string response_data;
bnc691fda62016-08-12 00:43:1610533 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210534 EXPECT_EQ("hello world", response_data);
10535
bncd9b132e2015-07-08 05:16:1010536 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610537 http_server_properties->GetAlternativeServices(server);
bncd9b132e2015-07-08 05:16:1010538 ASSERT_EQ(1u, alternative_service_vector.size());
10539 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
10540 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
10541 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:4210542}
10543
bnc55ff9da2015-08-19 18:42:3510544// Ensure that we are not allowed to redirect traffic via an alternate protocol
10545// to an unrestricted (port >= 1024) when the original traffic was on a
10546// restricted port (port < 1024). Ensure that we can redirect in all other
10547// cases.
bncd16676a2016-07-20 16:23:0110548TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110549 HttpRequestInfo restricted_port_request;
10550 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510551 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110552 restricted_port_request.load_flags = 0;
10553
[email protected]d973e99a2012-02-17 21:02:3610554 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110555 StaticSocketDataProvider first_data;
10556 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710557 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110558
10559 MockRead data_reads[] = {
10560 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10561 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610562 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110563 };
10564 StaticSocketDataProvider second_data(
10565 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710566 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510567 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610568 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510569 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110570
danakj1fd259a02016-04-16 03:17:0910571 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110572
bnc525e175a2016-06-20 12:36:4010573 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310574 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110575 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210576 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010577 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bnccacc0992015-03-20 20:22:2210578 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210579 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210580 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610581 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010582 expiration);
[email protected]3912662a32011-10-04 00:51:1110583
bnc691fda62016-08-12 00:43:1610584 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110585 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110586
tfarina428341112016-09-22 13:38:2010587 int rv = trans.Start(&restricted_port_request, callback.callback(),
10588 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110589 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110590 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110591 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910592}
[email protected]3912662a32011-10-04 00:51:1110593
bnc55ff9da2015-08-19 18:42:3510594// Ensure that we are allowed to redirect traffic via an alternate protocol to
10595// an unrestricted (port >= 1024) when the original traffic was on a restricted
10596// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110597TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710598 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910599
10600 HttpRequestInfo restricted_port_request;
10601 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510602 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910603 restricted_port_request.load_flags = 0;
10604
10605 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10606 StaticSocketDataProvider first_data;
10607 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710608 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910609
10610 MockRead data_reads[] = {
10611 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10612 MockRead("hello world"),
10613 MockRead(ASYNC, OK),
10614 };
10615 StaticSocketDataProvider second_data(
10616 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710617 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510618 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610619 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510620 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910621
danakj1fd259a02016-04-16 03:17:0910622 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910623
bnc525e175a2016-06-20 12:36:4010624 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910625 session->http_server_properties();
10626 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210627 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010628 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bnccacc0992015-03-20 20:22:2210629 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210630 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210631 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610632 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010633 expiration);
[email protected]c54c6962013-02-01 04:53:1910634
bnc691fda62016-08-12 00:43:1610635 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910636 TestCompletionCallback callback;
10637
tfarina428341112016-09-22 13:38:2010638 EXPECT_EQ(ERR_IO_PENDING,
10639 trans.Start(&restricted_port_request, callback.callback(),
10640 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910641 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110642 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110643}
10644
bnc55ff9da2015-08-19 18:42:3510645// Ensure that we are not allowed to redirect traffic via an alternate protocol
10646// to an unrestricted (port >= 1024) when the original traffic was on a
10647// restricted port (port < 1024). Ensure that we can redirect in all other
10648// cases.
bncd16676a2016-07-20 16:23:0110649TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110650 HttpRequestInfo restricted_port_request;
10651 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510652 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110653 restricted_port_request.load_flags = 0;
10654
[email protected]d973e99a2012-02-17 21:02:3610655 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110656 StaticSocketDataProvider first_data;
10657 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710658 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110659
10660 MockRead data_reads[] = {
10661 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10662 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610663 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110664 };
10665 StaticSocketDataProvider second_data(
10666 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710667 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110668
bncb26024382016-06-29 02:39:4510669 SSLSocketDataProvider ssl(ASYNC, OK);
10670 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10671
danakj1fd259a02016-04-16 03:17:0910672 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110673
bnc525e175a2016-06-20 12:36:4010674 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310675 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110676 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210677 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010678 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bnccacc0992015-03-20 20:22:2210679 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210680 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210681 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610682 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010683 expiration);
[email protected]3912662a32011-10-04 00:51:1110684
bnc691fda62016-08-12 00:43:1610685 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110686 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110687
tfarina428341112016-09-22 13:38:2010688 int rv = trans.Start(&restricted_port_request, callback.callback(),
10689 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110690 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110691 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110692 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110693}
10694
bnc55ff9da2015-08-19 18:42:3510695// Ensure that we are not allowed to redirect traffic via an alternate protocol
10696// to an unrestricted (port >= 1024) when the original traffic was on a
10697// restricted port (port < 1024). Ensure that we can redirect in all other
10698// cases.
bncd16676a2016-07-20 16:23:0110699TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1110700 HttpRequestInfo unrestricted_port_request;
10701 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510702 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110703 unrestricted_port_request.load_flags = 0;
10704
[email protected]d973e99a2012-02-17 21:02:3610705 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110706 StaticSocketDataProvider first_data;
10707 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710708 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110709
10710 MockRead data_reads[] = {
10711 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10712 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610713 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110714 };
10715 StaticSocketDataProvider second_data(
10716 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710717 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510718 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610719 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510720 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110721
danakj1fd259a02016-04-16 03:17:0910722 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110723
bnc525e175a2016-06-20 12:36:4010724 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310725 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110726 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210727 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010728 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bnccacc0992015-03-20 20:22:2210729 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210730 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210731 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610732 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010733 expiration);
[email protected]3912662a32011-10-04 00:51:1110734
bnc691fda62016-08-12 00:43:1610735 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110736 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110737
bnc691fda62016-08-12 00:43:1610738 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina428341112016-09-22 13:38:2010739 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110741 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110742 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110743}
10744
bnc55ff9da2015-08-19 18:42:3510745// Ensure that we are not allowed to redirect traffic via an alternate protocol
10746// to an unrestricted (port >= 1024) when the original traffic was on a
10747// restricted port (port < 1024). Ensure that we can redirect in all other
10748// cases.
bncd16676a2016-07-20 16:23:0110749TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1110750 HttpRequestInfo unrestricted_port_request;
10751 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510752 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110753 unrestricted_port_request.load_flags = 0;
10754
[email protected]d973e99a2012-02-17 21:02:3610755 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110756 StaticSocketDataProvider first_data;
10757 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710758 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110759
10760 MockRead data_reads[] = {
10761 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10762 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610763 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110764 };
10765 StaticSocketDataProvider second_data(
10766 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710767 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110768
bncb26024382016-06-29 02:39:4510769 SSLSocketDataProvider ssl(ASYNC, OK);
10770 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10771
danakj1fd259a02016-04-16 03:17:0910772 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110773
bnc525e175a2016-06-20 12:36:4010774 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310775 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210776 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:2210777 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010778 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bnccacc0992015-03-20 20:22:2210779 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210780 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210781 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610782 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010783 expiration);
[email protected]3912662a32011-10-04 00:51:1110784
bnc691fda62016-08-12 00:43:1610785 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110786 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110787
bnc691fda62016-08-12 00:43:1610788 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina428341112016-09-22 13:38:2010789 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110790 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110791 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0110792 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110793}
10794
bnc55ff9da2015-08-19 18:42:3510795// Ensure that we are not allowed to redirect traffic via an alternate protocol
10796// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10797// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0110798TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0210799 HttpRequestInfo request;
10800 request.method = "GET";
bncce36dca22015-04-21 22:11:2310801 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210802
10803 // The alternate protocol request will error out before we attempt to connect,
10804 // so only the standard HTTP request will try to connect.
10805 MockRead data_reads[] = {
10806 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10807 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610808 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210809 };
10810 StaticSocketDataProvider data(
10811 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710812 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210813
danakj1fd259a02016-04-16 03:17:0910814 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210815
bnc525e175a2016-06-20 12:36:4010816 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210817 session->http_server_properties();
10818 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:2210819 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4010820 AlternateProtocolFromNextProto(kProtoHTTP2), "www.example.org",
bnccacc0992015-03-20 20:22:2210821 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210822 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210823 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610824 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210825
bnc691fda62016-08-12 00:43:1610826 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0210827 TestCompletionCallback callback;
10828
tfarina428341112016-09-22 13:38:2010829 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0210831 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0110832 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210833
bnc691fda62016-08-12 00:43:1610834 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210835 ASSERT_TRUE(response);
10836 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210837 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10838
10839 std::string response_data;
bnc691fda62016-08-12 00:43:1610840 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210841 EXPECT_EQ("hello world", response_data);
10842}
10843
bncd16676a2016-07-20 16:23:0110844TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5410845 HttpRequestInfo request;
10846 request.method = "GET";
bncb26024382016-06-29 02:39:4510847 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410848
10849 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210850 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310851 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210852 MockRead("\r\n"),
10853 MockRead("hello world"),
10854 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10855 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410856
10857 StaticSocketDataProvider first_transaction(
10858 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710859 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4510860 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610861 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510862 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5410863
bnc032658ba2016-09-26 18:17:1510864 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5410865
bncdf80d44fd2016-07-15 20:27:4110866 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4510867 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110868 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410869
bnc42331402016-07-25 13:36:1510870 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110871 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410872 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110873 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410874 };
10875
rch8e6c6c42015-05-01 14:05:1310876 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10877 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710878 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410879
[email protected]d973e99a2012-02-17 21:02:3610880 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510881 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10882 NULL, 0, NULL, 0);
10883 hanging_non_alternate_protocol_socket.set_connect_data(
10884 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710885 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510886 &hanging_non_alternate_protocol_socket);
10887
[email protected]49639fa2011-12-20 23:22:4110888 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410889
danakj1fd259a02016-04-16 03:17:0910890 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610891 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010892 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410893
tfarina428341112016-09-22 13:38:2010894 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10896 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410897
10898 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210899 ASSERT_TRUE(response);
10900 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410901 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10902
10903 std::string response_data;
robpercival214763f2016-07-01 23:27:0110904 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410905 EXPECT_EQ("hello world", response_data);
10906
[email protected]90499482013-06-01 00:39:5010907 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410908
tfarina428341112016-09-22 13:38:2010909 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110910 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10911 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410912
10913 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210914 ASSERT_TRUE(response);
10915 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210916 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310917 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210918 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410919
robpercival214763f2016-07-01 23:27:0110920 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410921 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410922}
10923
bncd16676a2016-07-20 16:23:0110924TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5510925 HttpRequestInfo request;
10926 request.method = "GET";
bncb26024382016-06-29 02:39:4510927 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510928
bncb26024382016-06-29 02:39:4510929 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5510930 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210931 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310932 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210933 MockRead("\r\n"),
10934 MockRead("hello world"),
10935 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10936 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510937 };
10938
bncb26024382016-06-29 02:39:4510939 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
10940 0);
10941 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5510942
bncb26024382016-06-29 02:39:4510943 SSLSocketDataProvider ssl_http11(ASYNC, OK);
10944 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
10945
10946 // Second transaction starts an alternative and a non-alternative Job.
10947 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3610948 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810949 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10950 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1810951 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10952
10953 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10954 hanging_socket2.set_connect_data(never_finishing_connect);
10955 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510956
bncb26024382016-06-29 02:39:4510957 // Third transaction starts an alternative and a non-alternative job.
10958 // The non-alternative job hangs, but the alternative one succeeds.
10959 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4110960 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4510961 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110962 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4510963 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5510964 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110965 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5510966 };
bnc42331402016-07-25 13:36:1510967 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110968 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1510969 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4110970 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510971 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110972 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
10973 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1310974 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510975 };
10976
rch8e6c6c42015-05-01 14:05:1310977 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10978 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710979 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510980
bnc032658ba2016-09-26 18:17:1510981 AddSSLSocketData();
bncb26024382016-06-29 02:39:4510982
mmenkecc2298e2015-12-07 18:20:1810983 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10984 hanging_socket3.set_connect_data(never_finishing_connect);
10985 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510986
danakj1fd259a02016-04-16 03:17:0910987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110988 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010989 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510990
tfarina428341112016-09-22 13:38:2010991 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10993 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5510994
10995 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5210996 ASSERT_TRUE(response);
10997 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510998 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10999
11000 std::string response_data;
robpercival214763f2016-07-01 23:27:0111001 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511002 EXPECT_EQ("hello world", response_data);
11003
[email protected]49639fa2011-12-20 23:22:4111004 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011005 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:2011006 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511008
[email protected]49639fa2011-12-20 23:22:4111009 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011010 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:2011011 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511013
robpercival214763f2016-07-01 23:27:0111014 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11015 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511016
11017 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211018 ASSERT_TRUE(response);
11019 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211020 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511021 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211022 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111023 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511024 EXPECT_EQ("hello!", response_data);
11025
11026 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211027 ASSERT_TRUE(response);
11028 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211029 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511030 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211031 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111032 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511033 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511034}
11035
bncd16676a2016-07-20 16:23:0111036TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511037 HttpRequestInfo request;
11038 request.method = "GET";
bncb26024382016-06-29 02:39:4511039 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511040
11041 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211042 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311043 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211044 MockRead("\r\n"),
11045 MockRead("hello world"),
11046 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11047 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511048 };
11049
11050 StaticSocketDataProvider first_transaction(
11051 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711052 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511053
[email protected]8ddf8322012-02-23 18:08:0611054 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711055 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511056
[email protected]d973e99a2012-02-17 21:02:3611057 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511058 StaticSocketDataProvider hanging_alternate_protocol_socket(
11059 NULL, 0, NULL, 0);
11060 hanging_alternate_protocol_socket.set_connect_data(
11061 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711062 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511063 &hanging_alternate_protocol_socket);
11064
bncb26024382016-06-29 02:39:4511065 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811066 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11067 NULL, 0);
11068 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511070
[email protected]49639fa2011-12-20 23:22:4111071 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511072
danakj1fd259a02016-04-16 03:17:0911073 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611074 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011075 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511076
tfarina428341112016-09-22 13:38:2011077 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111078 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11079 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511080
11081 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211082 ASSERT_TRUE(response);
11083 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511084 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11085
11086 std::string response_data;
robpercival214763f2016-07-01 23:27:0111087 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511088 EXPECT_EQ("hello world", response_data);
11089
[email protected]90499482013-06-01 00:39:5011090 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511091
tfarina428341112016-09-22 13:38:2011092 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111093 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11094 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511095
11096 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211097 ASSERT_TRUE(response);
11098 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511099 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11100 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211101 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511102
robpercival214763f2016-07-01 23:27:0111103 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511104 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511105}
11106
[email protected]631f1322010-04-30 17:59:1111107class CapturingProxyResolver : public ProxyResolver {
11108 public:
sammce90c9212015-05-27 23:43:3511109 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011110 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111111
dchengb03027d2014-10-21 12:00:2011112 int GetProxyForURL(const GURL& url,
11113 ProxyInfo* results,
11114 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511115 std::unique_ptr<Request>* request,
tfarina428341112016-09-22 13:38:2011116 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011117 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11118 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211119 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111120 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211121 return OK;
[email protected]631f1322010-04-30 17:59:1111122 }
11123
[email protected]24476402010-07-20 20:55:1711124 const std::vector<GURL>& resolved() const { return resolved_; }
11125
11126 private:
[email protected]631f1322010-04-30 17:59:1111127 std::vector<GURL> resolved_;
11128
11129 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11130};
11131
sammce64b2362015-04-29 03:50:2311132class CapturingProxyResolverFactory : public ProxyResolverFactory {
11133 public:
11134 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11135 : ProxyResolverFactory(false), resolver_(resolver) {}
11136
11137 int CreateProxyResolver(
11138 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911139 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311140 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911141 std::unique_ptr<Request>* request) override {
sammce64b2362015-04-29 03:50:2311142 resolver->reset(new ForwardingProxyResolver(resolver_));
11143 return OK;
11144 }
11145
11146 private:
11147 ProxyResolver* resolver_;
11148};
11149
bnc2e884782016-08-11 19:45:1911150// Test that proxy is resolved using the origin url,
11151// regardless of the alternative server.
11152TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11153 // Configure proxy to bypass www.example.org, which is the origin URL.
11154 ProxyConfig proxy_config;
11155 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11156 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11157 auto proxy_config_service =
11158 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config);
11159
11160 CapturingProxyResolver capturing_proxy_resolver;
11161 auto proxy_resolver_factory = base::MakeUnique<CapturingProxyResolverFactory>(
11162 &capturing_proxy_resolver);
11163
11164 TestNetLog net_log;
11165
11166 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11167 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11168 &net_log);
11169
11170 session_deps_.net_log = &net_log;
11171
11172 // Configure alternative service with a hostname that is not bypassed by the
11173 // proxy.
11174 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11175 HttpServerProperties* http_server_properties =
11176 session->http_server_properties();
11177 url::SchemeHostPort server("https", "www.example.org", 443);
11178 HostPortPair alternative("www.example.com", 443);
11179 AlternativeService alternative_service(
11180 AlternateProtocolFromNextProto(kProtoHTTP2), alternative);
11181 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11182 http_server_properties->SetAlternativeService(server, alternative_service,
11183 expiration);
11184
11185 // Non-alternative job should hang.
11186 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11187 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11188 nullptr, 0);
11189 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11190 session_deps_.socket_factory->AddSocketDataProvider(
11191 &hanging_alternate_protocol_socket);
11192
bnc032658ba2016-09-26 18:17:1511193 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911194
11195 HttpRequestInfo request;
11196 request.method = "GET";
11197 request.url = GURL("https://www.example.org/");
11198 request.load_flags = 0;
11199
11200 SpdySerializedFrame req(
11201 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11202
11203 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11204
11205 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11206 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11207 MockRead spdy_reads[] = {
11208 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11209 };
11210
11211 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11212 arraysize(spdy_writes));
11213 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11214
11215 TestCompletionCallback callback;
11216
11217 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11218
tfarina428341112016-09-22 13:38:2011219 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911220 EXPECT_THAT(callback.GetResult(rv), IsOk());
11221
11222 const HttpResponseInfo* response = trans.GetResponseInfo();
11223 ASSERT_TRUE(response);
11224 ASSERT_TRUE(response->headers);
11225 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11226 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211227 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911228
11229 std::string response_data;
11230 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11231 EXPECT_EQ("hello!", response_data);
11232
11233 // Origin host bypasses proxy, no resolution should have happened.
11234 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11235}
11236
bncd16676a2016-07-20 16:23:0111237TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111238 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211239 proxy_config.set_auto_detect(true);
11240 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111241
sammc5dd160c2015-04-02 02:43:1311242 CapturingProxyResolver capturing_proxy_resolver;
ricea2deef682016-09-09 08:04:0711243 session_deps_.proxy_service.reset(
11244 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
11245 base::MakeUnique<CapturingProxyResolverFactory>(
11246 &capturing_proxy_resolver),
11247 NULL));
vishal.b62985ca92015-04-17 08:45:5111248 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711249 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111250
11251 HttpRequestInfo request;
11252 request.method = "GET";
bncb26024382016-06-29 02:39:4511253 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111254
11255 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211256 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311257 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211258 MockRead("\r\n"),
11259 MockRead("hello world"),
11260 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11261 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111262 };
11263
11264 StaticSocketDataProvider first_transaction(
11265 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711266 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511267 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611268 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511269 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111270
bnc032658ba2016-09-26 18:17:1511271 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111272
bncdf80d44fd2016-07-15 20:27:4111273 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511274 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111275 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311276 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511277 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11278 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311279 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111280 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111281 };
11282
[email protected]d911f1b2010-05-05 22:39:4211283 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11284
bnc42331402016-07-25 13:36:1511285 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111286 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111287 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111288 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11289 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111290 };
11291
rch8e6c6c42015-05-01 14:05:1311292 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11293 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711294 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111295
[email protected]d973e99a2012-02-17 21:02:3611296 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511297 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11298 NULL, 0, NULL, 0);
11299 hanging_non_alternate_protocol_socket.set_connect_data(
11300 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711301 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511302 &hanging_non_alternate_protocol_socket);
11303
[email protected]49639fa2011-12-20 23:22:4111304 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111305
danakj1fd259a02016-04-16 03:17:0911306 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611307 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011308 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111309
tfarina428341112016-09-22 13:38:2011310 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111311 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11312 EXPECT_THAT(callback.WaitForResult(), IsOk());
11313
11314 const HttpResponseInfo* response = trans->GetResponseInfo();
11315 ASSERT_TRUE(response);
11316 ASSERT_TRUE(response->headers);
11317 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11318 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211319 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111320
11321 std::string response_data;
11322 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11323 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111324
[email protected]90499482013-06-01 00:39:5011325 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111326
tfarina428341112016-09-22 13:38:2011327 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11329 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111330
mmenkea2dcd3bf2016-08-16 21:49:4111331 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211332 ASSERT_TRUE(response);
11333 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211334 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311335 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211336 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111337
robpercival214763f2016-07-01 23:27:0111338 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111339 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511340 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11341 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311342 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311343 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311344 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111345
[email protected]029c83b62013-01-24 05:28:2011346 LoadTimingInfo load_timing_info;
11347 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11348 TestLoadTimingNotReusedWithPac(load_timing_info,
11349 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111350}
[email protected]631f1322010-04-30 17:59:1111351
bncd16676a2016-07-20 16:23:0111352TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811353 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411354 HttpRequestInfo request;
11355 request.method = "GET";
bncb26024382016-06-29 02:39:4511356 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411357
11358 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211359 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311360 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211361 MockRead("\r\n"),
11362 MockRead("hello world"),
11363 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411364 };
11365
11366 StaticSocketDataProvider first_transaction(
11367 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711368 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511369 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611370 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411372
bnc032658ba2016-09-26 18:17:1511373 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411374
bncdf80d44fd2016-07-15 20:27:4111375 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511376 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111377 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411378
bnc42331402016-07-25 13:36:1511379 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111380 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411381 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111382 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411383 };
11384
rch8e6c6c42015-05-01 14:05:1311385 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11386 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711387 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411388
[email protected]83039bb2011-12-09 18:43:5511389 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411390
danakj1fd259a02016-04-16 03:17:0911391 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411392
bnc691fda62016-08-12 00:43:1611393 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011394 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411395
tfarina428341112016-09-22 13:38:2011396 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11398 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411399
11400 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211401 ASSERT_TRUE(response);
11402 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411403 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11404
11405 std::string response_data;
robpercival214763f2016-07-01 23:27:0111406 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411407 EXPECT_EQ("hello world", response_data);
11408
11409 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511410 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011411 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311412 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711413 base::WeakPtr<SpdySession> spdy_session =
tfarina428341112016-09-22 13:38:2011414 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811415
[email protected]90499482013-06-01 00:39:5011416 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411417
tfarina428341112016-09-22 13:38:2011418 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111419 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11420 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411421
11422 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211423 ASSERT_TRUE(response);
11424 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211425 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311426 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211427 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411428
robpercival214763f2016-07-01 23:27:0111429 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411430 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211431}
11432
[email protected]044de0642010-06-17 10:42:1511433// GenerateAuthToken is a mighty big test.
11434// It tests all permutation of GenerateAuthToken behavior:
11435// - Synchronous and Asynchronous completion.
11436// - OK or error on completion.
11437// - Direct connection, non-authenticating proxy, and authenticating proxy.
11438// - HTTP or HTTPS backend (to include proxy tunneling).
11439// - Non-authenticating and authenticating backend.
11440//
[email protected]fe3b7dc2012-02-03 19:52:0911441// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511442// problems generating an auth token for an authenticating proxy, we don't
11443// need to test all permutations of the backend server).
11444//
11445// The test proceeds by going over each of the configuration cases, and
11446// potentially running up to three rounds in each of the tests. The TestConfig
11447// specifies both the configuration for the test as well as the expectations
11448// for the results.
bncd16676a2016-07-20 16:23:0111449TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011450 static const char kServer[] = "http://www.example.com";
11451 static const char kSecureServer[] = "https://www.example.com";
11452 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511453
11454 enum AuthTiming {
11455 AUTH_NONE,
11456 AUTH_SYNC,
11457 AUTH_ASYNC,
11458 };
11459
11460 const MockWrite kGet(
11461 "GET / HTTP/1.1\r\n"
11462 "Host: www.example.com\r\n"
11463 "Connection: keep-alive\r\n\r\n");
11464 const MockWrite kGetProxy(
11465 "GET http://www.example.com/ HTTP/1.1\r\n"
11466 "Host: www.example.com\r\n"
11467 "Proxy-Connection: keep-alive\r\n\r\n");
11468 const MockWrite kGetAuth(
11469 "GET / HTTP/1.1\r\n"
11470 "Host: www.example.com\r\n"
11471 "Connection: keep-alive\r\n"
11472 "Authorization: auth_token\r\n\r\n");
11473 const MockWrite kGetProxyAuth(
11474 "GET http://www.example.com/ HTTP/1.1\r\n"
11475 "Host: www.example.com\r\n"
11476 "Proxy-Connection: keep-alive\r\n"
11477 "Proxy-Authorization: auth_token\r\n\r\n");
11478 const MockWrite kGetAuthThroughProxy(
11479 "GET http://www.example.com/ HTTP/1.1\r\n"
11480 "Host: www.example.com\r\n"
11481 "Proxy-Connection: keep-alive\r\n"
11482 "Authorization: auth_token\r\n\r\n");
11483 const MockWrite kGetAuthWithProxyAuth(
11484 "GET http://www.example.com/ HTTP/1.1\r\n"
11485 "Host: www.example.com\r\n"
11486 "Proxy-Connection: keep-alive\r\n"
11487 "Proxy-Authorization: auth_token\r\n"
11488 "Authorization: auth_token\r\n\r\n");
11489 const MockWrite kConnect(
11490 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711491 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511492 "Proxy-Connection: keep-alive\r\n\r\n");
11493 const MockWrite kConnectProxyAuth(
11494 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711495 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511496 "Proxy-Connection: keep-alive\r\n"
11497 "Proxy-Authorization: auth_token\r\n\r\n");
11498
11499 const MockRead kSuccess(
11500 "HTTP/1.1 200 OK\r\n"
11501 "Content-Type: text/html; charset=iso-8859-1\r\n"
11502 "Content-Length: 3\r\n\r\n"
11503 "Yes");
11504 const MockRead kFailure(
11505 "Should not be called.");
11506 const MockRead kServerChallenge(
11507 "HTTP/1.1 401 Unauthorized\r\n"
11508 "WWW-Authenticate: Mock realm=server\r\n"
11509 "Content-Type: text/html; charset=iso-8859-1\r\n"
11510 "Content-Length: 14\r\n\r\n"
11511 "Unauthorized\r\n");
11512 const MockRead kProxyChallenge(
11513 "HTTP/1.1 407 Unauthorized\r\n"
11514 "Proxy-Authenticate: Mock realm=proxy\r\n"
11515 "Proxy-Connection: close\r\n"
11516 "Content-Type: text/html; charset=iso-8859-1\r\n"
11517 "Content-Length: 14\r\n\r\n"
11518 "Unauthorized\r\n");
11519 const MockRead kProxyConnected(
11520 "HTTP/1.1 200 Connection Established\r\n\r\n");
11521
11522 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11523 // no constructors, but the C++ compiler on Windows warns about
11524 // unspecified data in compound literals. So, moved to using constructors,
11525 // and TestRound's created with the default constructor should not be used.
11526 struct TestRound {
11527 TestRound()
11528 : expected_rv(ERR_UNEXPECTED),
11529 extra_write(NULL),
11530 extra_read(NULL) {
11531 }
11532 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11533 int expected_rv_arg)
11534 : write(write_arg),
11535 read(read_arg),
11536 expected_rv(expected_rv_arg),
11537 extra_write(NULL),
11538 extra_read(NULL) {
11539 }
11540 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11541 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111542 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511543 : write(write_arg),
11544 read(read_arg),
11545 expected_rv(expected_rv_arg),
11546 extra_write(extra_write_arg),
11547 extra_read(extra_read_arg) {
11548 }
11549 MockWrite write;
11550 MockRead read;
11551 int expected_rv;
11552 const MockWrite* extra_write;
11553 const MockRead* extra_read;
11554 };
11555
11556 static const int kNoSSL = 500;
11557
11558 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5111559 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511560 AuthTiming proxy_auth_timing;
11561 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5111562 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511563 AuthTiming server_auth_timing;
11564 int server_auth_rv;
11565 int num_auth_rounds;
11566 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611567 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511568 } test_configs[] = {
asankac93076192016-10-03 15:46:0211569 // Non-authenticating HTTP server with a direct connection.
11570 {NULL,
11571 AUTH_NONE,
11572 OK,
11573 kServer,
11574 AUTH_NONE,
11575 OK,
11576 1,
11577 kNoSSL,
11578 {TestRound(kGet, kSuccess, OK)}},
11579 // Authenticating HTTP server with a direct connection.
11580 {NULL,
11581 AUTH_NONE,
11582 OK,
11583 kServer,
11584 AUTH_SYNC,
11585 OK,
11586 2,
11587 kNoSSL,
11588 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511589 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211590 {NULL,
11591 AUTH_NONE,
11592 OK,
11593 kServer,
11594 AUTH_SYNC,
11595 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611596 3,
11597 kNoSSL,
11598 {TestRound(kGet, kServerChallenge, OK),
11599 TestRound(kGet, kServerChallenge, OK),
11600 TestRound(kGetAuth, kSuccess, OK)}},
11601 {NULL,
11602 AUTH_NONE,
11603 OK,
11604 kServer,
11605 AUTH_SYNC,
11606 ERR_UNSUPPORTED_AUTH_SCHEME,
11607 2,
11608 kNoSSL,
11609 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
11610 {NULL,
11611 AUTH_NONE,
11612 OK,
11613 kServer,
11614 AUTH_SYNC,
11615 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11616 2,
11617 kNoSSL,
11618 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
11619 {kProxy,
11620 AUTH_SYNC,
11621 ERR_FAILED,
11622 kServer,
11623 AUTH_NONE,
11624 OK,
11625 2,
11626 kNoSSL,
11627 {TestRound(kGetProxy, kProxyChallenge, OK),
11628 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
11629 {kProxy,
11630 AUTH_ASYNC,
11631 ERR_FAILED,
11632 kServer,
11633 AUTH_NONE,
11634 OK,
11635 2,
11636 kNoSSL,
11637 {TestRound(kGetProxy, kProxyChallenge, OK),
11638 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
11639 {NULL,
11640 AUTH_NONE,
11641 OK,
11642 kServer,
11643 AUTH_SYNC,
11644 ERR_FAILED,
asankac93076192016-10-03 15:46:0211645 2,
11646 kNoSSL,
11647 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611648 TestRound(kGet, kFailure, ERR_FAILED)}},
11649 {NULL,
11650 AUTH_NONE,
11651 OK,
11652 kServer,
11653 AUTH_ASYNC,
11654 ERR_FAILED,
11655 2,
11656 kNoSSL,
11657 {TestRound(kGet, kServerChallenge, OK),
11658 TestRound(kGet, kFailure, ERR_FAILED)}},
asankac93076192016-10-03 15:46:0211659 {NULL,
11660 AUTH_NONE,
11661 OK,
11662 kServer,
11663 AUTH_ASYNC,
11664 OK,
11665 2,
11666 kNoSSL,
11667 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511668 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211669 {NULL,
11670 AUTH_NONE,
11671 OK,
11672 kServer,
11673 AUTH_ASYNC,
11674 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611675 3,
asankac93076192016-10-03 15:46:0211676 kNoSSL,
11677 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611678 // The second round uses a HttpAuthHandlerMock that always succeeds.
11679 TestRound(kGet, kServerChallenge, OK),
11680 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211681 // Non-authenticating HTTP server through a non-authenticating proxy.
11682 {kProxy,
11683 AUTH_NONE,
11684 OK,
11685 kServer,
11686 AUTH_NONE,
11687 OK,
11688 1,
11689 kNoSSL,
11690 {TestRound(kGetProxy, kSuccess, OK)}},
11691 // Authenticating HTTP server through a non-authenticating proxy.
11692 {kProxy,
11693 AUTH_NONE,
11694 OK,
11695 kServer,
11696 AUTH_SYNC,
11697 OK,
11698 2,
11699 kNoSSL,
11700 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511701 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211702 {kProxy,
11703 AUTH_NONE,
11704 OK,
11705 kServer,
11706 AUTH_SYNC,
11707 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611708 3,
asankac93076192016-10-03 15:46:0211709 kNoSSL,
11710 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611711 TestRound(kGetProxy, kServerChallenge, OK),
11712 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211713 {kProxy,
11714 AUTH_NONE,
11715 OK,
11716 kServer,
11717 AUTH_ASYNC,
11718 OK,
11719 2,
11720 kNoSSL,
11721 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511722 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211723 {kProxy,
11724 AUTH_NONE,
11725 OK,
11726 kServer,
11727 AUTH_ASYNC,
11728 ERR_INVALID_AUTH_CREDENTIALS,
11729 2,
11730 kNoSSL,
11731 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611732 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211733 // Non-authenticating HTTP server through an authenticating proxy.
11734 {kProxy,
11735 AUTH_SYNC,
11736 OK,
11737 kServer,
11738 AUTH_NONE,
11739 OK,
11740 2,
11741 kNoSSL,
11742 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511743 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211744 {kProxy,
11745 AUTH_SYNC,
11746 ERR_INVALID_AUTH_CREDENTIALS,
11747 kServer,
11748 AUTH_NONE,
11749 OK,
11750 2,
11751 kNoSSL,
11752 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611753 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211754 {kProxy,
11755 AUTH_ASYNC,
11756 OK,
11757 kServer,
11758 AUTH_NONE,
11759 OK,
11760 2,
11761 kNoSSL,
11762 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511763 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211764 {kProxy,
11765 AUTH_ASYNC,
11766 ERR_INVALID_AUTH_CREDENTIALS,
11767 kServer,
11768 AUTH_NONE,
11769 OK,
11770 2,
11771 kNoSSL,
11772 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611773 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211774 // Authenticating HTTP server through an authenticating proxy.
11775 {kProxy,
11776 AUTH_SYNC,
11777 OK,
11778 kServer,
11779 AUTH_SYNC,
11780 OK,
11781 3,
11782 kNoSSL,
11783 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511784 TestRound(kGetProxyAuth, kServerChallenge, OK),
11785 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211786 {kProxy,
11787 AUTH_SYNC,
11788 OK,
11789 kServer,
11790 AUTH_SYNC,
11791 ERR_INVALID_AUTH_CREDENTIALS,
11792 3,
11793 kNoSSL,
11794 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511795 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611796 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211797 {kProxy,
11798 AUTH_ASYNC,
11799 OK,
11800 kServer,
11801 AUTH_SYNC,
11802 OK,
11803 3,
11804 kNoSSL,
11805 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511806 TestRound(kGetProxyAuth, kServerChallenge, OK),
11807 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211808 {kProxy,
11809 AUTH_ASYNC,
11810 OK,
11811 kServer,
11812 AUTH_SYNC,
11813 ERR_INVALID_AUTH_CREDENTIALS,
11814 3,
11815 kNoSSL,
11816 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511817 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611818 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211819 {kProxy,
11820 AUTH_SYNC,
11821 OK,
11822 kServer,
11823 AUTH_ASYNC,
11824 OK,
11825 3,
11826 kNoSSL,
11827 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511828 TestRound(kGetProxyAuth, kServerChallenge, OK),
11829 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211830 {kProxy,
11831 AUTH_SYNC,
11832 OK,
11833 kServer,
11834 AUTH_ASYNC,
11835 ERR_INVALID_AUTH_CREDENTIALS,
11836 3,
11837 kNoSSL,
11838 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511839 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611840 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211841 {kProxy,
11842 AUTH_ASYNC,
11843 OK,
11844 kServer,
11845 AUTH_ASYNC,
11846 OK,
11847 3,
11848 kNoSSL,
11849 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511850 TestRound(kGetProxyAuth, kServerChallenge, OK),
11851 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211852 {kProxy,
11853 AUTH_ASYNC,
11854 OK,
11855 kServer,
11856 AUTH_ASYNC,
11857 ERR_INVALID_AUTH_CREDENTIALS,
11858 3,
11859 kNoSSL,
11860 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511861 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611862 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211863 // Non-authenticating HTTPS server with a direct connection.
11864 {NULL,
11865 AUTH_NONE,
11866 OK,
11867 kSecureServer,
11868 AUTH_NONE,
11869 OK,
11870 1,
11871 0,
11872 {TestRound(kGet, kSuccess, OK)}},
11873 // Authenticating HTTPS server with a direct connection.
11874 {NULL,
11875 AUTH_NONE,
11876 OK,
11877 kSecureServer,
11878 AUTH_SYNC,
11879 OK,
11880 2,
11881 0,
11882 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511883 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211884 {NULL,
11885 AUTH_NONE,
11886 OK,
11887 kSecureServer,
11888 AUTH_SYNC,
11889 ERR_INVALID_AUTH_CREDENTIALS,
11890 2,
11891 0,
asankae2257db2016-10-11 22:03:1611892 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211893 {NULL,
11894 AUTH_NONE,
11895 OK,
11896 kSecureServer,
11897 AUTH_ASYNC,
11898 OK,
11899 2,
11900 0,
11901 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511902 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211903 {NULL,
11904 AUTH_NONE,
11905 OK,
11906 kSecureServer,
11907 AUTH_ASYNC,
11908 ERR_INVALID_AUTH_CREDENTIALS,
11909 2,
11910 0,
asankae2257db2016-10-11 22:03:1611911 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211912 // Non-authenticating HTTPS server with a non-authenticating proxy.
11913 {kProxy,
11914 AUTH_NONE,
11915 OK,
11916 kSecureServer,
11917 AUTH_NONE,
11918 OK,
11919 1,
11920 0,
11921 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11922 // Authenticating HTTPS server through a non-authenticating proxy.
11923 {kProxy,
11924 AUTH_NONE,
11925 OK,
11926 kSecureServer,
11927 AUTH_SYNC,
11928 OK,
11929 2,
11930 0,
11931 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1511932 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211933 {kProxy,
11934 AUTH_NONE,
11935 OK,
11936 kSecureServer,
11937 AUTH_SYNC,
11938 ERR_INVALID_AUTH_CREDENTIALS,
11939 2,
11940 0,
11941 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1611942 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211943 {kProxy,
11944 AUTH_NONE,
11945 OK,
11946 kSecureServer,
11947 AUTH_ASYNC,
11948 OK,
11949 2,
11950 0,
11951 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1511952 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211953 {kProxy,
11954 AUTH_NONE,
11955 OK,
11956 kSecureServer,
11957 AUTH_ASYNC,
11958 ERR_INVALID_AUTH_CREDENTIALS,
11959 2,
11960 0,
11961 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1611962 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211963 // Non-Authenticating HTTPS server through an authenticating proxy.
11964 {kProxy,
11965 AUTH_SYNC,
11966 OK,
11967 kSecureServer,
11968 AUTH_NONE,
11969 OK,
11970 2,
11971 1,
11972 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511973 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0211974 {kProxy,
11975 AUTH_SYNC,
11976 ERR_INVALID_AUTH_CREDENTIALS,
11977 kSecureServer,
11978 AUTH_NONE,
11979 OK,
11980 2,
11981 kNoSSL,
11982 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611983 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11984 {kProxy,
11985 AUTH_SYNC,
11986 ERR_UNSUPPORTED_AUTH_SCHEME,
11987 kSecureServer,
11988 AUTH_NONE,
11989 OK,
11990 2,
11991 kNoSSL,
11992 {TestRound(kConnect, kProxyChallenge, OK),
11993 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11994 {kProxy,
11995 AUTH_SYNC,
11996 ERR_UNEXPECTED,
11997 kSecureServer,
11998 AUTH_NONE,
11999 OK,
12000 2,
12001 kNoSSL,
12002 {TestRound(kConnect, kProxyChallenge, OK),
12003 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asankac93076192016-10-03 15:46:0212004 {kProxy,
12005 AUTH_ASYNC,
12006 OK,
12007 kSecureServer,
12008 AUTH_NONE,
12009 OK,
12010 2,
12011 1,
12012 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512013 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212014 {kProxy,
12015 AUTH_ASYNC,
12016 ERR_INVALID_AUTH_CREDENTIALS,
12017 kSecureServer,
12018 AUTH_NONE,
12019 OK,
12020 2,
12021 kNoSSL,
12022 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612023 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212024 // Authenticating HTTPS server through an authenticating proxy.
12025 {kProxy,
12026 AUTH_SYNC,
12027 OK,
12028 kSecureServer,
12029 AUTH_SYNC,
12030 OK,
12031 3,
12032 1,
12033 {TestRound(kConnect, kProxyChallenge, OK),
12034 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12035 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512036 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212037 {kProxy,
12038 AUTH_SYNC,
12039 OK,
12040 kSecureServer,
12041 AUTH_SYNC,
12042 ERR_INVALID_AUTH_CREDENTIALS,
12043 3,
12044 1,
12045 {TestRound(kConnect, kProxyChallenge, OK),
12046 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12047 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612048 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212049 {kProxy,
12050 AUTH_ASYNC,
12051 OK,
12052 kSecureServer,
12053 AUTH_SYNC,
12054 OK,
12055 3,
12056 1,
12057 {TestRound(kConnect, kProxyChallenge, OK),
12058 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12059 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512060 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212061 {kProxy,
12062 AUTH_ASYNC,
12063 OK,
12064 kSecureServer,
12065 AUTH_SYNC,
12066 ERR_INVALID_AUTH_CREDENTIALS,
12067 3,
12068 1,
12069 {TestRound(kConnect, kProxyChallenge, OK),
12070 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12071 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612072 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212073 {kProxy,
12074 AUTH_SYNC,
12075 OK,
12076 kSecureServer,
12077 AUTH_ASYNC,
12078 OK,
12079 3,
12080 1,
12081 {TestRound(kConnect, kProxyChallenge, OK),
12082 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12083 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512084 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212085 {kProxy,
12086 AUTH_SYNC,
12087 OK,
12088 kSecureServer,
12089 AUTH_ASYNC,
12090 ERR_INVALID_AUTH_CREDENTIALS,
12091 3,
12092 1,
12093 {TestRound(kConnect, kProxyChallenge, OK),
12094 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12095 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612096 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212097 {kProxy,
12098 AUTH_ASYNC,
12099 OK,
12100 kSecureServer,
12101 AUTH_ASYNC,
12102 OK,
12103 3,
12104 1,
12105 {TestRound(kConnect, kProxyChallenge, OK),
12106 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12107 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512108 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212109 {kProxy,
12110 AUTH_ASYNC,
12111 OK,
12112 kSecureServer,
12113 AUTH_ASYNC,
12114 ERR_INVALID_AUTH_CREDENTIALS,
12115 3,
12116 1,
12117 {TestRound(kConnect, kProxyChallenge, OK),
12118 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12119 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612120 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512121 };
12122
viettrungluue4a8b882014-10-16 06:17:3812123 for (size_t i = 0; i < arraysize(test_configs); ++i) {
asankae2257db2016-10-11 22:03:1612124 SCOPED_TRACE(::testing::Message() << "Test config " << i);
[email protected]2d01c262011-08-11 23:07:0812125 HttpAuthHandlerMock::Factory* auth_factory(
12126 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712127 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912128 SSLInfo empty_ssl_info;
[email protected]044de0642010-06-17 10:42:1512129 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2612130
12131 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512132 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0812133 for (int n = 0; n < 2; n++) {
12134 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12135 std::string auth_challenge = "Mock realm=proxy";
12136 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412137 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12138 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812139 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina428341112016-09-22 13:38:2012140 empty_ssl_info, origin,
12141 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812142 auth_handler->SetGenerateExpectation(
12143 test_config.proxy_auth_timing == AUTH_ASYNC,
12144 test_config.proxy_auth_rv);
12145 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12146 }
[email protected]044de0642010-06-17 10:42:1512147 }
12148 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012149 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512150 std::string auth_challenge = "Mock realm=server";
12151 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412152 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12153 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512154 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina428341112016-09-22 13:38:2012155 empty_ssl_info, origin,
12156 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512157 auth_handler->SetGenerateExpectation(
12158 test_config.server_auth_timing == AUTH_ASYNC,
12159 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0812160 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612161
12162 // The second handler always succeeds. It should only be used where there
12163 // are multiple auth sessions for server auth in the same network
12164 // transaction using the same auth scheme.
12165 std::unique_ptr<HttpAuthHandlerMock> second_handler =
12166 base::MakeUnique<HttpAuthHandlerMock>();
12167 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12168 empty_ssl_info, origin,
12169 NetLogWithSource());
12170 second_handler->SetGenerateExpectation(true, OK);
12171 auth_factory->AddMockHandler(second_handler.release(),
12172 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512173 }
12174 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312175 session_deps_.proxy_service =
12176 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512177 } else {
rdsmith82957ad2015-09-16 19:42:0312178 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512179 }
12180
12181 HttpRequestInfo request;
12182 request.method = "GET";
12183 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512184
danakj1fd259a02016-04-16 03:17:0912185 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512186
rchcb68dc62015-05-21 04:45:3612187 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12188
12189 std::vector<std::vector<MockRead>> mock_reads(1);
12190 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512191 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
12192 const TestRound& read_write_round = test_config.rounds[round];
12193
12194 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612195 mock_reads.back().push_back(read_write_round.read);
12196 mock_writes.back().push_back(read_write_round.write);
12197
12198 // kProxyChallenge uses Proxy-Connection: close which means that the
12199 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412200 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612201 mock_reads.push_back(std::vector<MockRead>());
12202 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512203 }
12204
rchcb68dc62015-05-21 04:45:3612205 if (read_write_round.extra_read) {
12206 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512207 }
rchcb68dc62015-05-21 04:45:3612208 if (read_write_round.extra_write) {
12209 mock_writes.back().push_back(*read_write_round.extra_write);
12210 }
[email protected]044de0642010-06-17 10:42:1512211
12212 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512213 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712214 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512215 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612216 }
[email protected]044de0642010-06-17 10:42:1512217
danakj1fd259a02016-04-16 03:17:0912218 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612219 for (size_t i = 0; i < mock_reads.size(); ++i) {
danakj1fd259a02016-04-16 03:17:0912220 data_providers.push_back(base::WrapUnique(new StaticSocketDataProvider(
davidben5f8b6bc2015-11-25 03:19:5412221 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
olli.raula525048c2015-12-10 07:38:3212222 mock_writes[i].size())));
rchcb68dc62015-05-21 04:45:3612223 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212224 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612225 }
12226
mmenkecc2298e2015-12-07 18:20:1812227 // Transaction must be created after DataProviders, so it's destroyed before
12228 // they are as well.
12229 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12230
rchcb68dc62015-05-21 04:45:3612231 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
12232 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512233 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112234 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512235 int rv;
12236 if (round == 0) {
tfarina428341112016-09-22 13:38:2012237 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512238 } else {
[email protected]49639fa2011-12-20 23:22:4112239 rv = trans.RestartWithAuth(
12240 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512241 }
12242 if (rv == ERR_IO_PENDING)
12243 rv = callback.WaitForResult();
12244
12245 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612246 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012247 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512248 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512249 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12250 continue;
12251 }
12252 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212253 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512254 } else {
wezca1070932016-05-26 20:30:5212255 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612256 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512257 }
12258 }
[email protected]e5ae96a2010-04-14 20:12:4512259 }
12260}
12261
bncd16676a2016-07-20 16:23:0112262TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412263 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412264 HttpAuthHandlerMock::Factory* auth_factory(
12265 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712266 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312267 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712268 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12269 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412270
12271 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12272 auth_handler->set_connection_based(true);
12273 std::string auth_challenge = "Mock realm=server";
12274 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412275 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12276 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912277 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412278 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina428341112016-09-22 13:38:2012279 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812280 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412281
[email protected]c871bce92010-07-15 21:51:1412282 int rv = OK;
12283 const HttpResponseInfo* response = NULL;
12284 HttpRequestInfo request;
12285 request.method = "GET";
12286 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712287
danakj1fd259a02016-04-16 03:17:0912288 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012289
12290 // Use a TCP Socket Pool with only one connection per group. This is used
12291 // to validate that the TCP socket is not released to the pool between
12292 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212293 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812294 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012295 50, // Max sockets for pool
12296 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112297 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12298 NULL, session_deps_.net_log);
danakj1fd259a02016-04-16 03:17:0912299 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:4412300 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0212301 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812302 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012303
bnc691fda62016-08-12 00:43:1612304 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112305 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412306
12307 const MockWrite kGet(
12308 "GET / HTTP/1.1\r\n"
12309 "Host: www.example.com\r\n"
12310 "Connection: keep-alive\r\n\r\n");
12311 const MockWrite kGetAuth(
12312 "GET / HTTP/1.1\r\n"
12313 "Host: www.example.com\r\n"
12314 "Connection: keep-alive\r\n"
12315 "Authorization: auth_token\r\n\r\n");
12316
12317 const MockRead kServerChallenge(
12318 "HTTP/1.1 401 Unauthorized\r\n"
12319 "WWW-Authenticate: Mock realm=server\r\n"
12320 "Content-Type: text/html; charset=iso-8859-1\r\n"
12321 "Content-Length: 14\r\n\r\n"
12322 "Unauthorized\r\n");
12323 const MockRead kSuccess(
12324 "HTTP/1.1 200 OK\r\n"
12325 "Content-Type: text/html; charset=iso-8859-1\r\n"
12326 "Content-Length: 3\r\n\r\n"
12327 "Yes");
12328
12329 MockWrite writes[] = {
12330 // First round
12331 kGet,
12332 // Second round
12333 kGetAuth,
12334 // Third round
12335 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012336 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012337 kGetAuth,
12338 // Competing request
12339 kGet,
[email protected]c871bce92010-07-15 21:51:1412340 };
12341 MockRead reads[] = {
12342 // First round
12343 kServerChallenge,
12344 // Second round
12345 kServerChallenge,
12346 // Third round
[email protected]eca50e122010-09-11 14:03:3012347 kServerChallenge,
12348 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412349 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012350 // Competing response
12351 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412352 };
12353 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12354 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712355 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412356
thestig9d3bb0c2015-01-24 00:49:5112357 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012358
12359 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412360 auth_handler->SetGenerateExpectation(false, OK);
tfarina428341112016-09-22 13:38:2012361 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412362 if (rv == ERR_IO_PENDING)
12363 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112364 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612365 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212366 ASSERT_TRUE(response);
12367 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812368 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412369
[email protected]7ef4cbbb2011-02-06 11:19:1012370 // In between rounds, another request comes in for the same domain.
12371 // It should not be able to grab the TCP socket that trans has already
12372 // claimed.
bnc691fda62016-08-12 00:43:1612373 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112374 TestCompletionCallback callback_compete;
tfarina428341112016-09-22 13:38:2012375 rv = trans_compete.Start(&request, callback_compete.callback(),
12376 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112377 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012378 // callback_compete.WaitForResult at this point would stall forever,
12379 // since the HttpNetworkTransaction does not release the request back to
12380 // the pool until after authentication completes.
12381
12382 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412383 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612384 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412385 if (rv == ERR_IO_PENDING)
12386 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112387 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612388 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212389 ASSERT_TRUE(response);
12390 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812391 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412392
[email protected]7ef4cbbb2011-02-06 11:19:1012393 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412394 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612395 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412396 if (rv == ERR_IO_PENDING)
12397 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112398 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612399 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212400 ASSERT_TRUE(response);
12401 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812402 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3012403
[email protected]7ef4cbbb2011-02-06 11:19:1012404 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012405 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612406 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012407 if (rv == ERR_IO_PENDING)
12408 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112409 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612410 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212411 ASSERT_TRUE(response);
12412 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812413 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012414
12415 // Read the body since the fourth round was successful. This will also
12416 // release the socket back to the pool.
12417 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612418 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012419 if (rv == ERR_IO_PENDING)
12420 rv = callback.WaitForResult();
12421 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612422 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012423 EXPECT_EQ(0, rv);
12424 // There are still 0 idle sockets, since the trans_compete transaction
12425 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812426 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012427
12428 // The competing request can now finish. Wait for the headers and then
12429 // read the body.
12430 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112431 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612432 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012433 if (rv == ERR_IO_PENDING)
12434 rv = callback.WaitForResult();
12435 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612436 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012437 EXPECT_EQ(0, rv);
12438
12439 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812440 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412441}
12442
[email protected]65041fa2010-05-21 06:56:5312443// This tests the case that a request is issued via http instead of spdy after
12444// npn is negotiated.
bncd16676a2016-07-20 16:23:0112445TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312446 HttpRequestInfo request;
12447 request.method = "GET";
bncce36dca22015-04-21 22:11:2312448 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312449
12450 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312451 MockWrite(
12452 "GET / HTTP/1.1\r\n"
12453 "Host: www.example.org\r\n"
12454 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312455 };
12456
12457 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212458 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312459 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212460 MockRead("\r\n"),
12461 MockRead("hello world"),
12462 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312463 };
12464
[email protected]8ddf8322012-02-23 18:08:0612465 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612466 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312467
[email protected]bb88e1d32013-05-03 23:11:0712468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312469
12470 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12471 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712472 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312473
[email protected]49639fa2011-12-20 23:22:4112474 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312475
danakj1fd259a02016-04-16 03:17:0912476 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612477 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312478
tfarina428341112016-09-22 13:38:2012479 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312480
robpercival214763f2016-07-01 23:27:0112481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12482 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312483
bnc691fda62016-08-12 00:43:1612484 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212485 ASSERT_TRUE(response);
12486 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312487 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12488
12489 std::string response_data;
bnc691fda62016-08-12 00:43:1612490 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312491 EXPECT_EQ("hello world", response_data);
12492
12493 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212494 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312495}
[email protected]26ef6582010-06-24 02:30:4712496
bnc55ff9da2015-08-19 18:42:3512497// Simulate the SSL handshake completing with an NPN negotiation followed by an
12498// immediate server closing of the socket.
12499// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112500TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712501 HttpRequestInfo request;
12502 request.method = "GET";
bncce36dca22015-04-21 22:11:2312503 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712504
[email protected]8ddf8322012-02-23 18:08:0612505 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612506 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712507 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712508
bncdf80d44fd2016-07-15 20:27:4112509 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912510 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112511 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712512
12513 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612514 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712515 };
12516
rch8e6c6c42015-05-01 14:05:1312517 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12518 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712519 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712520
[email protected]49639fa2011-12-20 23:22:4112521 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712522
danakj1fd259a02016-04-16 03:17:0912523 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712525
tfarina428341112016-09-22 13:38:2012526 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112527 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12528 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712529}
[email protected]65d34382010-07-01 18:12:2612530
[email protected]795cbf82013-07-22 09:37:2712531// A subclass of HttpAuthHandlerMock that records the request URL when
12532// it gets it. This is needed since the auth handler may get destroyed
12533// before we get a chance to query it.
12534class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12535 public:
12536 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12537
dchengb03027d2014-10-21 12:00:2012538 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712539
12540 protected:
dchengb03027d2014-10-21 12:00:2012541 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12542 const HttpRequestInfo* request,
12543 const CompletionCallback& callback,
12544 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712545 *url_ = request->url;
12546 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12547 credentials, request, callback, auth_token);
12548 }
12549
12550 private:
12551 GURL* url_;
12552};
12553
[email protected]8e6441ca2010-08-19 05:56:3812554// Test that if we cancel the transaction as the connection is completing, that
12555// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112556TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812557 // Setup everything about the connection to complete synchronously, so that
12558 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12559 // for is the callback from the HttpStreamRequest.
12560 // Then cancel the transaction.
12561 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612562 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812563 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612564 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12565 MockRead(SYNCHRONOUS, "hello world"),
12566 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812567 };
12568
[email protected]8e6441ca2010-08-19 05:56:3812569 HttpRequestInfo request;
12570 request.method = "GET";
bncce36dca22015-04-21 22:11:2312571 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812572
[email protected]bb88e1d32013-05-03 23:11:0712573 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912574 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612575 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112576 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2712577
[email protected]8e6441ca2010-08-19 05:56:3812578 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12579 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712580 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812581
[email protected]49639fa2011-12-20 23:22:4112582 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812583
vishal.b62985ca92015-04-17 08:45:5112584 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112585 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112586 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3812587 trans.reset(); // Cancel the transaction here.
12588
fdoray92e35a72016-06-10 15:54:5512589 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012590}
12591
[email protected]ecab6e052014-05-16 14:58:1212592// Test that if a transaction is cancelled after receiving the headers, the
12593// stream is drained properly and added back to the socket pool. The main
12594// purpose of this test is to make sure that an HttpStreamParser can be read
12595// from after the HttpNetworkTransaction and the objects it owns have been
12596// deleted.
12597// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0112598TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1212599 MockRead data_reads[] = {
12600 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12601 MockRead(ASYNC, "Content-Length: 2\r\n"),
12602 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12603 MockRead(ASYNC, "1"),
12604 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12605 // HttpNetworkTransaction has been deleted.
12606 MockRead(ASYNC, "2"),
12607 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12608 };
12609 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12610 session_deps_.socket_factory->AddSocketDataProvider(&data);
12611
danakj1fd259a02016-04-16 03:17:0912612 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212613
12614 {
12615 HttpRequestInfo request;
12616 request.method = "GET";
bncce36dca22015-04-21 22:11:2312617 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212618
dcheng48459ac22014-08-26 00:46:4112619 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212620 TestCompletionCallback callback;
12621
tfarina428341112016-09-22 13:38:2012622 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112623 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1212624 callback.WaitForResult();
12625
12626 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212627 ASSERT_TRUE(response);
12628 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212629 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12630
12631 // The transaction and HttpRequestInfo are deleted.
12632 }
12633
12634 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512635 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212636
12637 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112638 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212639}
12640
[email protected]76a505b2010-08-25 06:23:0012641// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0112642TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312643 session_deps_.proxy_service =
12644 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112645 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712646 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912647 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012648
[email protected]76a505b2010-08-25 06:23:0012649 HttpRequestInfo request;
12650 request.method = "GET";
bncce36dca22015-04-21 22:11:2312651 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012652
12653 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312654 MockWrite(
12655 "GET http://www.example.org/ HTTP/1.1\r\n"
12656 "Host: www.example.org\r\n"
12657 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012658 };
12659
12660 MockRead data_reads1[] = {
12661 MockRead("HTTP/1.1 200 OK\r\n"),
12662 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12663 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612664 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012665 };
12666
12667 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12668 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712669 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012670
[email protected]49639fa2011-12-20 23:22:4112671 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012672
bnc691fda62016-08-12 00:43:1612673 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912674 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612675 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912676 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12677 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012678
bnc691fda62016-08-12 00:43:1612679 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012681
12682 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112683 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0012684
bnc691fda62016-08-12 00:43:1612685 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212686 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012687
12688 EXPECT_TRUE(response->headers->IsKeepAlive());
12689 EXPECT_EQ(200, response->headers->response_code());
12690 EXPECT_EQ(100, response->headers->GetContentLength());
12691 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712692 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12693 HostPortPair::FromString("myproxy:70")),
12694 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912695 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12696 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12697 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012698 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012699
12700 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612701 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012702 TestLoadTimingNotReusedWithPac(load_timing_info,
12703 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012704}
12705
12706// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0112707TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312708 session_deps_.proxy_service =
12709 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112710 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712711 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912712 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012713
[email protected]76a505b2010-08-25 06:23:0012714 HttpRequestInfo request;
12715 request.method = "GET";
bncce36dca22015-04-21 22:11:2312716 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012717
12718 // Since we have proxy, should try to establish tunnel.
12719 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712720 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12721 "Host: www.example.org:443\r\n"
12722 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012723
rsleevidb16bb02015-11-12 23:47:1712724 MockWrite("GET / HTTP/1.1\r\n"
12725 "Host: www.example.org\r\n"
12726 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012727 };
12728
12729 MockRead data_reads1[] = {
12730 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12731
12732 MockRead("HTTP/1.1 200 OK\r\n"),
12733 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12734 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612735 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012736 };
12737
12738 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12739 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712740 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612741 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712742 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012743
[email protected]49639fa2011-12-20 23:22:4112744 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012745
bnc691fda62016-08-12 00:43:1612746 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912747 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612748 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912749 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12750 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012751
bnc691fda62016-08-12 00:43:1612752 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112753 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012754
12755 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112756 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4612757 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012758 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012759 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012760 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12761 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012762 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012763 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012764 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12765 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012766
bnc691fda62016-08-12 00:43:1612767 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212768 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012769
12770 EXPECT_TRUE(response->headers->IsKeepAlive());
12771 EXPECT_EQ(200, response->headers->response_code());
12772 EXPECT_EQ(100, response->headers->GetContentLength());
12773 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12774 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712775 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12776 HostPortPair::FromString("myproxy:70")),
12777 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912778 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12779 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12780 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012781
12782 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612783 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012784 TestLoadTimingNotReusedWithPac(load_timing_info,
12785 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012786}
12787
rsleevidb16bb02015-11-12 23:47:1712788// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12789// literal host.
bncd16676a2016-07-20 16:23:0112790TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1712791 session_deps_.proxy_service =
12792 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12793 BoundTestNetLog log;
12794 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912795 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712796
12797 HttpRequestInfo request;
12798 request.method = "GET";
12799 request.url = GURL("https://[::1]:443/");
12800
12801 // Since we have proxy, should try to establish tunnel.
12802 MockWrite data_writes1[] = {
12803 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12804 "Host: [::1]:443\r\n"
12805 "Proxy-Connection: keep-alive\r\n\r\n"),
12806
12807 MockWrite("GET / HTTP/1.1\r\n"
12808 "Host: [::1]\r\n"
12809 "Connection: keep-alive\r\n\r\n"),
12810 };
12811
12812 MockRead data_reads1[] = {
12813 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12814
12815 MockRead("HTTP/1.1 200 OK\r\n"),
12816 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12817 MockRead("Content-Length: 100\r\n\r\n"),
12818 MockRead(SYNCHRONOUS, OK),
12819 };
12820
12821 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12822 data_writes1, arraysize(data_writes1));
12823 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12824 SSLSocketDataProvider ssl(ASYNC, OK);
12825 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12826
12827 TestCompletionCallback callback1;
12828
bnc691fda62016-08-12 00:43:1612829 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1712830
bnc691fda62016-08-12 00:43:1612831 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1712833
12834 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112835 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1712836 TestNetLogEntry::List entries;
12837 log.GetEntries(&entries);
12838 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012839 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12840 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712841 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012842 entries, pos,
12843 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12844 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712845
bnc691fda62016-08-12 00:43:1612846 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212847 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712848
12849 EXPECT_TRUE(response->headers->IsKeepAlive());
12850 EXPECT_EQ(200, response->headers->response_code());
12851 EXPECT_EQ(100, response->headers->GetContentLength());
12852 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12853 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712854 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12855 HostPortPair::FromString("myproxy:70")),
12856 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1712857
12858 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612859 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1712860 TestLoadTimingNotReusedWithPac(load_timing_info,
12861 CONNECT_TIMING_HAS_SSL_TIMES);
12862}
12863
[email protected]76a505b2010-08-25 06:23:0012864// Test a basic HTTPS GET request through a proxy, but the server hangs up
12865// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0112866TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312867 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112868 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712869 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912870 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012871
[email protected]76a505b2010-08-25 06:23:0012872 HttpRequestInfo request;
12873 request.method = "GET";
bncce36dca22015-04-21 22:11:2312874 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012875
12876 // Since we have proxy, should try to establish tunnel.
12877 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712878 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12879 "Host: www.example.org:443\r\n"
12880 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012881
rsleevidb16bb02015-11-12 23:47:1712882 MockWrite("GET / HTTP/1.1\r\n"
12883 "Host: www.example.org\r\n"
12884 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012885 };
12886
12887 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0612888 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0012889 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612890 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0012891 };
12892
12893 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12894 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712895 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612896 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712897 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012898
[email protected]49639fa2011-12-20 23:22:4112899 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012900
bnc691fda62016-08-12 00:43:1612901 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5012902
bnc691fda62016-08-12 00:43:1612903 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012905
12906 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112907 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4612908 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012909 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012910 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012911 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12912 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012913 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012914 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012915 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12916 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012917}
12918
[email protected]749eefa82010-09-13 22:14:0312919// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0112920TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4112921 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912922 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112923 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0312924
bnc42331402016-07-25 13:36:1512925 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4112926 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0312927 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112928 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0312929 };
12930
rch8e6c6c42015-05-01 14:05:1312931 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12932 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712933 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0312934
[email protected]8ddf8322012-02-23 18:08:0612935 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612936 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712937 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0312938
danakj1fd259a02016-04-16 03:17:0912939 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0312940
12941 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2312942 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012943 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5312944 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2712945 base::WeakPtr<SpdySession> spdy_session =
bnc032658ba2016-09-26 18:17:1512946 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0312947
12948 HttpRequestInfo request;
12949 request.method = "GET";
bncce36dca22015-04-21 22:11:2312950 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0312951
12952 // This is the important line that marks this as a preconnect.
12953 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
12954
bnc691fda62016-08-12 00:43:1612955 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0312956
[email protected]41d64e82013-07-03 22:44:2612957 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:2012958 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12960 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0312961}
12962
[email protected]73b8dd222010-11-11 19:55:2412963// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1612964// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0212965void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0712966 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2912967 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712968 request_info.url = GURL("https://www.example.com/");
12969 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912970 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712971
[email protected]8ddf8322012-02-23 18:08:0612972 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2912973 MockWrite data_writes[] = {
12974 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2412975 };
ttuttle859dc7a2015-04-23 19:42:2912976 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712977 session_deps_.socket_factory->AddSocketDataProvider(&data);
12978 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2412979
danakj1fd259a02016-04-16 03:17:0912980 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612981 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2412982
[email protected]49639fa2011-12-20 23:22:4112983 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:2012984 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2912985 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2412986 rv = callback.WaitForResult();
12987 ASSERT_EQ(error, rv);
12988}
12989
bncd16676a2016-07-20 16:23:0112990TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2412991 // Just check a grab bag of cert errors.
12992 static const int kErrors[] = {
12993 ERR_CERT_COMMON_NAME_INVALID,
12994 ERR_CERT_AUTHORITY_INVALID,
12995 ERR_CERT_DATE_INVALID,
12996 };
12997 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0612998 CheckErrorIsPassedBack(kErrors[i], ASYNC);
12999 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413000 }
13001}
13002
[email protected]bd0b6772011-01-11 19:59:3013003// Ensure that a client certificate is removed from the SSL client auth
13004// cache when:
13005// 1) No proxy is involved.
13006// 2) TLS False Start is disabled.
13007// 3) The initial TLS handshake requests a client certificate.
13008// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113009TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913010 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713011 request_info.url = GURL("https://www.example.com/");
13012 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913013 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713014
[email protected]bd0b6772011-01-11 19:59:3013015 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113016 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013017
13018 // [ssl_]data1 contains the data for the first SSL handshake. When a
13019 // CertificateRequest is received for the first time, the handshake will
13020 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913021 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013022 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713023 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913024 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713025 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013026
13027 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13028 // False Start is not being used, the result of the SSL handshake will be
13029 // returned as part of the SSLClientSocket::Connect() call. This test
13030 // matches the result of a server sending a handshake_failure alert,
13031 // rather than a Finished message, because it requires a client
13032 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913033 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013034 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713035 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913036 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713037 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013038
13039 // [ssl_]data3 contains the data for the third SSL handshake. When a
13040 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213041 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13042 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013043 // of the HttpNetworkTransaction. Because this test failure is due to
13044 // requiring a client certificate, this fallback handshake should also
13045 // fail.
ttuttle859dc7a2015-04-23 19:42:2913046 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013047 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713048 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913049 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713050 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013051
[email protected]80c75f682012-05-26 16:22:1713052 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13053 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213054 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13055 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713056 // of the HttpNetworkTransaction. Because this test failure is due to
13057 // requiring a client certificate, this fallback handshake should also
13058 // fail.
ttuttle859dc7a2015-04-23 19:42:2913059 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713060 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713061 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913062 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713063 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713064
danakj1fd259a02016-04-16 03:17:0913065 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613066 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013067
[email protected]bd0b6772011-01-11 19:59:3013068 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113069 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:2013070 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113071 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013072
13073 // Complete the SSL handshake, which should abort due to requiring a
13074 // client certificate.
13075 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113076 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013077
13078 // Indicate that no certificate should be supplied. From the perspective
13079 // of SSLClientCertCache, NULL is just as meaningful as a real
13080 // certificate, so this is the same as supply a
13081 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613082 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113083 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013084
13085 // Ensure the certificate was added to the client auth cache before
13086 // allowing the connection to continue restarting.
13087 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413088 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113089 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413090 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213091 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013092
13093 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713094 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13095 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013096 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113097 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013098
13099 // Ensure that the client certificate is removed from the cache on a
13100 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113101 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413102 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013103}
13104
13105// Ensure that a client certificate is removed from the SSL client auth
13106// cache when:
13107// 1) No proxy is involved.
13108// 2) TLS False Start is enabled.
13109// 3) The initial TLS handshake requests a client certificate.
13110// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113111TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913112 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713113 request_info.url = GURL("https://www.example.com/");
13114 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913115 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713116
[email protected]bd0b6772011-01-11 19:59:3013117 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113118 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013119
13120 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13121 // return successfully after reading up to the peer's Certificate message.
13122 // This is to allow the caller to call SSLClientSocket::Write(), which can
13123 // enqueue application data to be sent in the same packet as the
13124 // ChangeCipherSpec and Finished messages.
13125 // The actual handshake will be finished when SSLClientSocket::Read() is
13126 // called, which expects to process the peer's ChangeCipherSpec and
13127 // Finished messages. If there was an error negotiating with the peer,
13128 // such as due to the peer requiring a client certificate when none was
13129 // supplied, the alert sent by the peer won't be processed until Read() is
13130 // called.
13131
13132 // Like the non-False Start case, when a client certificate is requested by
13133 // the peer, the handshake is aborted during the Connect() call.
13134 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913135 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013136 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713137 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913138 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713139 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013140
13141 // When a client certificate is supplied, Connect() will not be aborted
13142 // when the peer requests the certificate. Instead, the handshake will
13143 // artificially succeed, allowing the caller to write the HTTP request to
13144 // the socket. The handshake messages are not processed until Read() is
13145 // called, which then detects that the handshake was aborted, due to the
13146 // peer sending a handshake_failure because it requires a client
13147 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913148 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013149 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713150 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913151 MockRead data2_reads[] = {
13152 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013153 };
ttuttle859dc7a2015-04-23 19:42:2913154 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713155 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013156
13157 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713158 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13159 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913160 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013161 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713162 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913163 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713164 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013165
[email protected]80c75f682012-05-26 16:22:1713166 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13167 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913168 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713169 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713170 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913171 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713172 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713173
[email protected]7799de12013-05-30 05:52:5113174 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913175 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113176 ssl_data5.cert_request_info = cert_request.get();
13177 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913178 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113179 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13180
danakj1fd259a02016-04-16 03:17:0913181 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613182 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013183
[email protected]bd0b6772011-01-11 19:59:3013184 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113185 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:2013186 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113187 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013188
13189 // Complete the SSL handshake, which should abort due to requiring a
13190 // client certificate.
13191 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113192 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013193
13194 // Indicate that no certificate should be supplied. From the perspective
13195 // of SSLClientCertCache, NULL is just as meaningful as a real
13196 // certificate, so this is the same as supply a
13197 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613198 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113199 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013200
13201 // Ensure the certificate was added to the client auth cache before
13202 // allowing the connection to continue restarting.
13203 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413204 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113205 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413206 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213207 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013208
[email protected]bd0b6772011-01-11 19:59:3013209 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713210 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13211 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013212 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113213 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013214
13215 // Ensure that the client certificate is removed from the cache on a
13216 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113217 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413218 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013219}
13220
[email protected]8c405132011-01-11 22:03:1813221// Ensure that a client certificate is removed from the SSL client auth
13222// cache when:
13223// 1) An HTTPS proxy is involved.
13224// 3) The HTTPS proxy requests a client certificate.
13225// 4) The client supplies an invalid/unacceptable certificate for the
13226// proxy.
13227// The test is repeated twice, first for connecting to an HTTPS endpoint,
13228// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113229TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313230 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113231 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713232 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813233
13234 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113235 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813236
13237 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13238 // [ssl_]data[1-3]. Rather than represending the endpoint
13239 // (www.example.com:443), they represent failures with the HTTPS proxy
13240 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913241 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813242 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713243 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913244 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713245 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813246
ttuttle859dc7a2015-04-23 19:42:2913247 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813248 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713249 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913250 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713251 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813252
[email protected]80c75f682012-05-26 16:22:1713253 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13254#if 0
ttuttle859dc7a2015-04-23 19:42:2913255 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813256 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713257 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913258 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713259 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713260#endif
[email protected]8c405132011-01-11 22:03:1813261
ttuttle859dc7a2015-04-23 19:42:2913262 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813263 requests[0].url = GURL("https://www.example.com/");
13264 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913265 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813266
13267 requests[1].url = GURL("http://www.example.com/");
13268 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913269 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813270
13271 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713272 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913273 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613274 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813275
13276 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113277 TestCompletionCallback callback;
tfarina428341112016-09-22 13:38:2013278 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113279 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813280
13281 // Complete the SSL handshake, which should abort due to requiring a
13282 // client certificate.
13283 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113284 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813285
13286 // Indicate that no certificate should be supplied. From the perspective
13287 // of SSLClientCertCache, NULL is just as meaningful as a real
13288 // certificate, so this is the same as supply a
13289 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613290 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113291 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813292
13293 // Ensure the certificate was added to the client auth cache before
13294 // allowing the connection to continue restarting.
13295 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413296 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113297 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413298 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213299 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813300 // Ensure the certificate was NOT cached for the endpoint. This only
13301 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113302 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413303 HostPortPair("www.example.com", 443), &client_cert,
13304 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813305
13306 // Restart the handshake. This will consume ssl_data2, which fails, and
13307 // then consume ssl_data3, which should also fail. The result code is
13308 // checked against what ssl_data3 should return.
13309 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113310 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813311
13312 // Now that the new handshake has failed, ensure that the client
13313 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113314 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413315 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113316 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413317 HostPortPair("www.example.com", 443), &client_cert,
13318 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813319 }
13320}
13321
bncd16676a2016-07-20 16:23:0113322TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613323 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713324 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913325 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613326
bnc032658ba2016-09-26 18:17:1513327 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613328
bncdf80d44fd2016-07-15 20:27:4113329 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913330 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813331 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113332 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713333 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613334 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113335 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613336 };
bnc42331402016-07-25 13:36:1513337 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113338 SpdySerializedFrame host1_resp_body(
13339 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513340 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113341 SpdySerializedFrame host2_resp_body(
13342 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613343 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113344 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13345 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313346 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613347 };
13348
eroman36d84e54432016-03-17 03:23:0213349 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213350 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313351 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13352 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713353 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613354
[email protected]aa22b242011-11-16 18:58:2913355 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613356 HttpRequestInfo request1;
13357 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313358 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613359 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013360 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613361
tfarina428341112016-09-22 13:38:2013362 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113363 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13364 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613365
13366 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213367 ASSERT_TRUE(response);
13368 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213369 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613370
13371 std::string response_data;
robpercival214763f2016-07-01 23:27:0113372 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613373 EXPECT_EQ("hello!", response_data);
13374
bnca4d611d2016-09-22 19:55:3713375 // Preload mail.example.com into HostCache.
13376 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013377 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613378 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013379 std::unique_ptr<HostResolver::Request> request;
13380 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13381 &ignored, callback.callback(),
tfarina428341112016-09-22 13:38:2013382 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113383 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713384 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113385 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613386
13387 HttpRequestInfo request2;
13388 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713389 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613390 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013391 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613392
tfarina428341112016-09-22 13:38:2013393 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113394 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13395 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613396
13397 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213398 ASSERT_TRUE(response);
13399 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213400 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613401 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213402 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113403 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613404 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613405}
13406
bncd16676a2016-07-20 16:23:0113407TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213408 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713409 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913410 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213411
bnc032658ba2016-09-26 18:17:1513412 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213413
bncdf80d44fd2016-07-15 20:27:4113414 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913415 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813416 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113417 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713418 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213419 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113420 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213421 };
bnc42331402016-07-25 13:36:1513422 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113423 SpdySerializedFrame host1_resp_body(
13424 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513425 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113426 SpdySerializedFrame host2_resp_body(
13427 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213428 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113429 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13430 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313431 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213432 };
13433
eroman36d84e54432016-03-17 03:23:0213434 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213435 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313436 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13437 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713438 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213439
13440 TestCompletionCallback callback;
13441 HttpRequestInfo request1;
13442 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313443 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213444 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013445 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213446
tfarina428341112016-09-22 13:38:2013447 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13449 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213450
13451 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213452 ASSERT_TRUE(response);
13453 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213454 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213455
13456 std::string response_data;
robpercival214763f2016-07-01 23:27:0113457 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213458 EXPECT_EQ("hello!", response_data);
13459
13460 HttpRequestInfo request2;
13461 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713462 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213463 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013464 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213465
tfarina428341112016-09-22 13:38:2013466 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13468 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213469
13470 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213471 ASSERT_TRUE(response);
13472 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213473 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213474 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213475 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113476 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213477 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213478}
13479
ttuttle859dc7a2015-04-23 19:42:2913480class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4613481 public:
13482 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
13483 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013484 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613485
13486 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
13487
13488 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2013489 int Resolve(const RequestInfo& info,
13490 RequestPriority priority,
13491 AddressList* addresses,
13492 const CompletionCallback& callback,
maksim.sisov31452af2016-07-27 06:38:1013493 std::unique_ptr<Request>* out_req,
tfarina428341112016-09-22 13:38:2013494 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013495 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1013496 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4013497 }
13498
dchengb03027d2014-10-21 12:00:2013499 int ResolveFromCache(const RequestInfo& info,
13500 AddressList* addresses,
tfarina428341112016-09-22 13:38:2013501 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013502 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
13503 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0913504 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613505 return rv;
13506 }
13507
[email protected]46da33be2011-07-19 21:58:0413508 MockCachingHostResolver* GetMockHostResolver() {
13509 return &host_resolver_;
13510 }
13511
[email protected]e3ceb682011-06-28 23:55:4613512 private:
13513 MockCachingHostResolver host_resolver_;
13514 const HostPortPair host_port_;
13515};
13516
bncd16676a2016-07-20 16:23:0113517TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1313518 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4613519 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
bnca4d611d2016-09-22 19:55:3713520 OneTimeCachingHostResolver host_resolver(
13521 HostPortPair("mail.example.com", 443));
[email protected]c6bf8152012-12-02 07:43:3413522 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0713523 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4613524 params.host_resolver = &host_resolver;
danakj1fd259a02016-04-16 03:17:0913525 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613526
bnc032658ba2016-09-26 18:17:1513527 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613528
bncdf80d44fd2016-07-15 20:27:4113529 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913530 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813531 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113532 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713533 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613534 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113535 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613536 };
bnc42331402016-07-25 13:36:1513537 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113538 SpdySerializedFrame host1_resp_body(
13539 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513540 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113541 SpdySerializedFrame host2_resp_body(
13542 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613543 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113544 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13545 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313546 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613547 };
13548
eroman36d84e54432016-03-17 03:23:0213549 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213550 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313551 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13552 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713553 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613554
[email protected]aa22b242011-11-16 18:58:2913555 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613556 HttpRequestInfo request1;
13557 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313558 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613559 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013560 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613561
tfarina428341112016-09-22 13:38:2013562 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13564 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613565
13566 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213567 ASSERT_TRUE(response);
13568 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213569 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613570
13571 std::string response_data;
robpercival214763f2016-07-01 23:27:0113572 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613573 EXPECT_EQ("hello!", response_data);
13574
13575 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3713576 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613577 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013578 std::unique_ptr<HostResolver::Request> request;
13579 rv = host_resolver.Resolve(resolve_info, DEFAULT_PRIORITY, &ignored,
tfarina428341112016-09-22 13:38:2013580 callback.callback(), &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113581 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713582 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113583 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613584
13585 HttpRequestInfo request2;
13586 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713587 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613588 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013589 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613590
tfarina428341112016-09-22 13:38:2013591 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113592 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13593 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613594
13595 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213596 ASSERT_TRUE(response);
13597 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213598 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613599 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213600 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113601 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613602 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613603}
13604
bncd16676a2016-07-20 16:23:0113605TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313606 const std::string https_url = "https://www.example.org:8080/";
13607 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413608
13609 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4113610 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4913611 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413612
13613 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113614 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0413615 };
13616
bnc42331402016-07-25 13:36:1513617 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113618 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13619 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5913620 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413621
rch8e6c6c42015-05-01 14:05:1313622 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13623 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413624 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713625 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413626
13627 // HTTP GET for the HTTP URL
13628 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313629 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413630 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313631 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413632 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413633 };
13634
13635 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313636 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13637 MockRead(ASYNC, 2, "hello"),
13638 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413639 };
13640
rch8e6c6c42015-05-01 14:05:1313641 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13642 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0413643
[email protected]8450d722012-07-02 19:14:0413644 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613645 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713646 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13647 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13648 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0413649
danakj1fd259a02016-04-16 03:17:0913650 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413651
13652 // Start the first transaction to set up the SpdySession
13653 HttpRequestInfo request1;
13654 request1.method = "GET";
13655 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413656 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013657 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413658 TestCompletionCallback callback1;
13659 EXPECT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2013660 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5513661 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413662
robpercival214763f2016-07-01 23:27:0113663 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0413664 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13665
13666 // Now, start the HTTP request
13667 HttpRequestInfo request2;
13668 request2.method = "GET";
13669 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413670 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013671 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413672 TestCompletionCallback callback2;
13673 EXPECT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2013674 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5513675 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413676
robpercival214763f2016-07-01 23:27:0113677 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0413678 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13679}
13680
bnc5452e2a2015-05-08 16:27:4213681// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
13682// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0113683TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2513684 url::SchemeHostPort server("https", "www.example.org", 443);
13685 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4213686
bnc8bef8da22016-05-30 01:28:2513687 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4213688 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613689 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4213690 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13691
13692 // No data should be read from the alternative, because HTTP/1.1 is
13693 // negotiated.
13694 StaticSocketDataProvider data;
13695 session_deps_.socket_factory->AddSocketDataProvider(&data);
13696
13697 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4613698 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4213699 // mocked. This way the request relies on the alternate Job.
13700 StaticSocketDataProvider data_refused;
13701 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13702 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13703
zhongyi3d4a55e72016-04-22 20:36:4613704 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013706 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4213707 session->http_server_properties();
13708 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4013709 AlternateProtocolFromNextProto(kProtoHTTP2), alternative);
bnc7dc7e1b42015-07-28 14:43:1213710 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613711 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013712 expiration);
bnc5452e2a2015-05-08 16:27:4213713
bnc691fda62016-08-12 00:43:1613714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4213715 HttpRequestInfo request;
13716 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2513717 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4213718 TestCompletionCallback callback;
13719
13720 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5213721 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina428341112016-09-22 13:38:2013722 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5213723 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4213724}
13725
bnc40448a532015-05-11 19:13:1413726// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4613727// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1413728// succeeds, the request should succeed, even if the latter fails because
13729// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0113730TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2513731 url::SchemeHostPort server("https", "www.example.org", 443);
13732 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1413733
13734 // Negotiate HTTP/1.1 with alternative.
13735 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613736 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1413737 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13738
13739 // No data should be read from the alternative, because HTTP/1.1 is
13740 // negotiated.
13741 StaticSocketDataProvider data;
13742 session_deps_.socket_factory->AddSocketDataProvider(&data);
13743
zhongyi3d4a55e72016-04-22 20:36:4613744 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1413745 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613746 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1413747 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13748
13749 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2513750 MockWrite("GET / HTTP/1.1\r\n"
13751 "Host: www.example.org\r\n"
13752 "Connection: keep-alive\r\n\r\n"),
13753 MockWrite("GET /second HTTP/1.1\r\n"
13754 "Host: www.example.org\r\n"
13755 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1413756 };
13757
13758 MockRead http_reads[] = {
13759 MockRead("HTTP/1.1 200 OK\r\n"),
13760 MockRead("Content-Type: text/html\r\n"),
13761 MockRead("Content-Length: 6\r\n\r\n"),
13762 MockRead("foobar"),
13763 MockRead("HTTP/1.1 200 OK\r\n"),
13764 MockRead("Content-Type: text/html\r\n"),
13765 MockRead("Content-Length: 7\r\n\r\n"),
13766 MockRead("another"),
13767 };
13768 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13769 http_writes, arraysize(http_writes));
13770 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13771
zhongyi3d4a55e72016-04-22 20:36:4613772 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913773 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013774 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1413775 session->http_server_properties();
13776 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4013777 AlternateProtocolFromNextProto(kProtoHTTP2), alternative);
bnc7dc7e1b42015-07-28 14:43:1213778 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613779 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013780 expiration);
bnc40448a532015-05-11 19:13:1413781
13782 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13783 HttpRequestInfo request1;
13784 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2513785 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1413786 request1.load_flags = 0;
13787 TestCompletionCallback callback1;
13788
tfarina428341112016-09-22 13:38:2013789 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1413790 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0113791 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1413792
13793 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213794 ASSERT_TRUE(response1);
13795 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1413796 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13797
13798 std::string response_data1;
robpercival214763f2016-07-01 23:27:0113799 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1413800 EXPECT_EQ("foobar", response_data1);
13801
13802 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13803 // for alternative service.
13804 EXPECT_TRUE(
13805 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13806
zhongyi3d4a55e72016-04-22 20:36:4613807 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1413808 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4613809 // to server.
bnc40448a532015-05-11 19:13:1413810 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13811 HttpRequestInfo request2;
13812 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2513813 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1413814 request2.load_flags = 0;
13815 TestCompletionCallback callback2;
13816
tfarina428341112016-09-22 13:38:2013817 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1413818 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0113819 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1413820
13821 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213822 ASSERT_TRUE(response2);
13823 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1413824 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13825
13826 std::string response_data2;
robpercival214763f2016-07-01 23:27:0113827 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1413828 EXPECT_EQ("another", response_data2);
13829}
13830
bnc5452e2a2015-05-08 16:27:4213831// Alternative service requires HTTP/2 (or SPDY), but there is already a
13832// HTTP/1.1 socket open to the alternative server. That socket should not be
13833// used.
bncd16676a2016-07-20 16:23:0113834TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4613835 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4213836 HostPortPair alternative("alternative.example.org", 443);
13837 std::string origin_url = "https://origin.example.org:443";
13838 std::string alternative_url = "https://alternative.example.org:443";
13839
13840 // Negotiate HTTP/1.1 with alternative.example.org.
13841 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613842 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4213843 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13844
13845 // HTTP/1.1 data for |request1| and |request2|.
13846 MockWrite http_writes[] = {
13847 MockWrite(
13848 "GET / HTTP/1.1\r\n"
13849 "Host: alternative.example.org\r\n"
13850 "Connection: keep-alive\r\n\r\n"),
13851 MockWrite(
13852 "GET / HTTP/1.1\r\n"
13853 "Host: alternative.example.org\r\n"
13854 "Connection: keep-alive\r\n\r\n"),
13855 };
13856
13857 MockRead http_reads[] = {
13858 MockRead(
13859 "HTTP/1.1 200 OK\r\n"
13860 "Content-Type: text/html; charset=iso-8859-1\r\n"
13861 "Content-Length: 40\r\n\r\n"
13862 "first HTTP/1.1 response from alternative"),
13863 MockRead(
13864 "HTTP/1.1 200 OK\r\n"
13865 "Content-Type: text/html; charset=iso-8859-1\r\n"
13866 "Content-Length: 41\r\n\r\n"
13867 "second HTTP/1.1 response from alternative"),
13868 };
13869 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13870 http_writes, arraysize(http_writes));
13871 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13872
13873 // This test documents that an alternate Job should not pool to an already
13874 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4613875 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4213876 StaticSocketDataProvider data_refused;
13877 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13878 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13879
zhongyi3d4a55e72016-04-22 20:36:4613880 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913881 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013882 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4213883 session->http_server_properties();
13884 AlternativeService alternative_service(
bnca9b9e222016-07-11 20:10:4013885 AlternateProtocolFromNextProto(kProtoHTTP2), alternative);
bnc7dc7e1b42015-07-28 14:43:1213886 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613887 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013888 expiration);
bnc5452e2a2015-05-08 16:27:4213889
13890 // First transaction to alternative to open an HTTP/1.1 socket.
bnc691fda62016-08-12 00:43:1613891 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4213892 HttpRequestInfo request1;
13893 request1.method = "GET";
13894 request1.url = GURL(alternative_url);
13895 request1.load_flags = 0;
13896 TestCompletionCallback callback1;
13897
tfarina428341112016-09-22 13:38:2013898 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113899 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1613900 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4213901 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5213902 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4213903 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5213904 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4213905 EXPECT_FALSE(response1->was_fetched_via_spdy);
13906 std::string response_data1;
bnc691fda62016-08-12 00:43:1613907 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4213908 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
13909
13910 // Request for origin.example.org, which has an alternative service. This
13911 // will start two Jobs: the alternative looks for connections to pool to,
13912 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4613913 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4213914 // this request fails.
bnc691fda62016-08-12 00:43:1613915 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4213916 HttpRequestInfo request2;
13917 request2.method = "GET";
13918 request2.url = GURL(origin_url);
13919 request2.load_flags = 0;
13920 TestCompletionCallback callback2;
13921
tfarina428341112016-09-22 13:38:2013922 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113923 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4213924
13925 // Another transaction to alternative. This is to test that the HTTP/1.1
13926 // socket is still open and in the pool.
bnc691fda62016-08-12 00:43:1613927 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4213928 HttpRequestInfo request3;
13929 request3.method = "GET";
13930 request3.url = GURL(alternative_url);
13931 request3.load_flags = 0;
13932 TestCompletionCallback callback3;
13933
tfarina428341112016-09-22 13:38:2013934 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113935 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1613936 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4213937 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5213938 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4213939 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5213940 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4213941 EXPECT_FALSE(response3->was_fetched_via_spdy);
13942 std::string response_data3;
bnc691fda62016-08-12 00:43:1613943 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4213944 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
13945}
13946
bncd16676a2016-07-20 16:23:0113947TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2313948 const std::string https_url = "https://www.example.org:8080/";
13949 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413950
rdsmithebb50aa2015-11-12 03:44:3813951 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0113952 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3813953
[email protected]8450d722012-07-02 19:14:0413954 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2313955 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4113956 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3413957 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4113958 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4913959 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113960 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0213961 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3913962
13963 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2913964 SpdyHeaderBlock req2_block;
13965 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2313966 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2913967 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4913968 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4113969 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1513970 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0413971
13972 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113973 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
13974 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0413975 };
13976
bncdf80d44fd2016-07-15 20:27:4113977 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1513978 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113979 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1513980 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113981 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
13982 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3813983 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4113984 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3813985 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1513986 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113987 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3313988 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4113989 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3313990 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4113991 CreateMockRead(wrapped_resp1, 4),
13992 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3313993 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4113994 CreateMockRead(resp2, 8),
13995 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3313996 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
13997 };
[email protected]8450d722012-07-02 19:14:0413998
mmenke666a6fea2015-12-19 04:16:3313999 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14000 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414001 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714002 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414003
rdsmith82957ad2015-09-16 19:42:0314004 session_deps_.proxy_service =
14005 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114006 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714007 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414008 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614009 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314010 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414011 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614012 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314013 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14014 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414015
danakj1fd259a02016-04-16 03:17:0914016 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414017
14018 // Start the first transaction to set up the SpdySession
14019 HttpRequestInfo request1;
14020 request1.method = "GET";
14021 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414022 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014023 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414024 TestCompletionCallback callback1;
tfarina428341112016-09-22 13:38:2014025 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414026
mmenke666a6fea2015-12-19 04:16:3314027 // This pause is a hack to avoid running into https://crbug.com/497228.
14028 data1.RunUntilPaused();
14029 base::RunLoop().RunUntilIdle();
14030 data1.Resume();
robpercival214763f2016-07-01 23:27:0114031 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414032 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14033
[email protected]f6c63db52013-02-02 00:35:2214034 LoadTimingInfo load_timing_info1;
14035 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14036 TestLoadTimingNotReusedWithPac(load_timing_info1,
14037 CONNECT_TIMING_HAS_SSL_TIMES);
14038
mmenke666a6fea2015-12-19 04:16:3314039 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414040 HttpRequestInfo request2;
14041 request2.method = "GET";
14042 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414043 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014044 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414045 TestCompletionCallback callback2;
tfarina428341112016-09-22 13:38:2014046 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414047
mmenke666a6fea2015-12-19 04:16:3314048 // This pause is a hack to avoid running into https://crbug.com/497228.
14049 data1.RunUntilPaused();
14050 base::RunLoop().RunUntilIdle();
14051 data1.Resume();
robpercival214763f2016-07-01 23:27:0114052 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314053
[email protected]8450d722012-07-02 19:14:0414054 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214055
14056 LoadTimingInfo load_timing_info2;
14057 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14058 // The established SPDY sessions is considered reused by the HTTP request.
14059 TestLoadTimingReusedWithPac(load_timing_info2);
14060 // HTTP requests over a SPDY session should have a different connection
14061 // socket_log_id than requests over a tunnel.
14062 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414063}
14064
[email protected]2d88e7d2012-07-19 17:55:1714065// Test that in the case where we have a SPDY session to a SPDY proxy
14066// that we do not pool other origins that resolve to the same IP when
14067// the certificate does not match the new origin.
14068// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114069TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314070 const std::string url1 = "http://www.example.org/";
14071 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714072 const std::string ip_addr = "1.2.3.4";
14073
rdsmithebb50aa2015-11-12 03:44:3814074 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114075 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814076
[email protected]2d88e7d2012-07-19 17:55:1714077 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614078 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314079 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114080 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514081 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714082
14083 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114084 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714085 };
14086
bnc42331402016-07-25 13:36:1514087 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114088 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714089 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114090 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14091 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714092 };
14093
mmenke666a6fea2015-12-19 04:16:3314094 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14095 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214096 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914097 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714098 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14099 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314100 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714101
14102 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114103 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914104 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714105
14106 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114107 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714108 };
14109
bnc42331402016-07-25 13:36:1514110 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114111 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14112 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314113 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714114
mmenke666a6fea2015-12-19 04:16:3314115 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14116 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714117 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314118 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714119
14120 // Set up a proxy config that sends HTTP requests to a proxy, and
14121 // all others direct.
14122 ProxyConfig proxy_config;
14123 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0714124 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0914125 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), nullptr,
csharrisonb7e3a082015-09-22 19:13:0414126 NULL));
[email protected]2d88e7d2012-07-19 17:55:1714127
bncce36dca22015-04-21 22:11:2314128 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614129 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714130 // Load a valid cert. Note, that this does not need to
14131 // be valid for proxy because the MockSSLClientSocket does
14132 // not actually verify it. But SpdySession will use this
14133 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314134 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214135 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314136 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14137 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714138
14139 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614140 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314141 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14142 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714143
[email protected]bb88e1d32013-05-03 23:11:0714144 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2314145 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714146 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714147
danakj1fd259a02016-04-16 03:17:0914148 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714149
14150 // Start the first transaction to set up the SpdySession
14151 HttpRequestInfo request1;
14152 request1.method = "GET";
14153 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714154 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014155 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714156 TestCompletionCallback callback1;
14157 ASSERT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2014158 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314159 // This pause is a hack to avoid running into https://crbug.com/497228.
14160 data1.RunUntilPaused();
14161 base::RunLoop().RunUntilIdle();
14162 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714163
robpercival214763f2016-07-01 23:27:0114164 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714165 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14166
14167 // Now, start the HTTP request
14168 HttpRequestInfo request2;
14169 request2.method = "GET";
14170 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714171 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014172 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714173 TestCompletionCallback callback2;
14174 EXPECT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2014175 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514176 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714177
14178 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114179 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714180 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14181}
14182
[email protected]85f97342013-04-17 06:12:2414183// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14184// error) in SPDY session, removes the socket from pool and closes the SPDY
14185// session. Verify that new url's from the same HttpNetworkSession (and a new
14186// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114187TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314188 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414189
14190 MockRead reads1[] = {
14191 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14192 };
14193
mmenke11eb5152015-06-09 14:50:5014194 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414195
bncdf80d44fd2016-07-15 20:27:4114196 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914197 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414198 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114199 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414200 };
14201
bnc42331402016-07-25 13:36:1514202 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114203 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414204 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114205 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14206 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414207 };
14208
mmenke11eb5152015-06-09 14:50:5014209 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14210 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414211
[email protected]85f97342013-04-17 06:12:2414212 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614213 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014214 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14215 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414216
14217 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614218 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014219 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14220 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414221
danakj1fd259a02016-04-16 03:17:0914222 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014223 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414224
14225 // Start the first transaction to set up the SpdySession and verify that
14226 // connection was closed.
14227 HttpRequestInfo request1;
14228 request1.method = "GET";
14229 request1.url = GURL(https_url);
14230 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014231 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414232 TestCompletionCallback callback1;
14233 EXPECT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2014234 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114235 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414236
14237 // Now, start the second request and make sure it succeeds.
14238 HttpRequestInfo request2;
14239 request2.method = "GET";
14240 request2.url = GURL(https_url);
14241 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014242 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414243 TestCompletionCallback callback2;
14244 EXPECT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2014245 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414246
robpercival214763f2016-07-01 23:27:0114247 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414248 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14249}
14250
bncd16676a2016-07-20 16:23:0114251TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314252 ClientSocketPoolManager::set_max_sockets_per_group(
14253 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14254 ClientSocketPoolManager::set_max_sockets_per_pool(
14255 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14256
14257 // Use two different hosts with different IPs so they don't get pooled.
14258 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14259 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914260 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314261
14262 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614263 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314264 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614265 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314266 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14267 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14268
bncdf80d44fd2016-07-15 20:27:4114269 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914270 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314271 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114272 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314273 };
bnc42331402016-07-25 13:36:1514274 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114275 SpdySerializedFrame host1_resp_body(
14276 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314277 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114278 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914279 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314280 };
14281
rdsmithebb50aa2015-11-12 03:44:3814282 // Use a separate test instance for the separate SpdySession that will be
14283 // created.
bncd16676a2016-07-20 16:23:0114284 SpdyTestUtil spdy_util_2;
danakj1fd259a02016-04-16 03:17:0914285 std::unique_ptr<SequencedSocketData> spdy1_data(
rch8e6c6c42015-05-01 14:05:1314286 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14287 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0314288 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14289
bncdf80d44fd2016-07-15 20:27:4114290 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914291 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314292 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114293 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314294 };
bnc42331402016-07-25 13:36:1514295 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114296 SpdySerializedFrame host2_resp_body(
14297 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314298 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114299 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914300 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314301 };
14302
danakj1fd259a02016-04-16 03:17:0914303 std::unique_ptr<SequencedSocketData> spdy2_data(
rch8e6c6c42015-05-01 14:05:1314304 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14305 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0314306 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14307
14308 MockWrite http_write[] = {
14309 MockWrite("GET / HTTP/1.1\r\n"
14310 "Host: www.a.com\r\n"
14311 "Connection: keep-alive\r\n\r\n"),
14312 };
14313
14314 MockRead http_read[] = {
14315 MockRead("HTTP/1.1 200 OK\r\n"),
14316 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14317 MockRead("Content-Length: 6\r\n\r\n"),
14318 MockRead("hello!"),
14319 };
14320 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14321 http_write, arraysize(http_write));
14322 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14323
14324 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014325 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314326 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314327 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614328 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314329
14330 TestCompletionCallback callback;
14331 HttpRequestInfo request1;
14332 request1.method = "GET";
14333 request1.url = GURL("https://www.a.com/");
14334 request1.load_flags = 0;
danakj1fd259a02016-04-16 03:17:0914335 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5014336 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314337
tfarina428341112016-09-22 13:38:2014338 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114339 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14340 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314341
14342 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214343 ASSERT_TRUE(response);
14344 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214345 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314346 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214347 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0314348
14349 std::string response_data;
robpercival214763f2016-07-01 23:27:0114350 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314351 EXPECT_EQ("hello!", response_data);
14352 trans.reset();
14353 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614354 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314355
14356 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014357 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314358 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314359 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614360 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314361 HttpRequestInfo request2;
14362 request2.method = "GET";
14363 request2.url = GURL("https://www.b.com/");
14364 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014365 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314366
tfarina428341112016-09-22 13:38:2014367 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114368 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14369 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314370
14371 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214372 ASSERT_TRUE(response);
14373 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214374 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314375 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214376 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114377 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314378 EXPECT_EQ("hello!", response_data);
14379 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614380 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314381 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614382 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314383
14384 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014385 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314386 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314387 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614388 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314389 HttpRequestInfo request3;
14390 request3.method = "GET";
14391 request3.url = GURL("http://www.a.com/");
14392 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014393 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314394
tfarina428341112016-09-22 13:38:2014395 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114396 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14397 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314398
14399 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214400 ASSERT_TRUE(response);
14401 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314402 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14403 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214404 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114405 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314406 EXPECT_EQ("hello!", response_data);
14407 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614408 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314409 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614410 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314411}
14412
bncd16676a2016-07-20 16:23:0114413TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414414 HttpRequestInfo request;
14415 request.method = "GET";
bncce36dca22015-04-21 22:11:2314416 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414417
danakj1fd259a02016-04-16 03:17:0914418 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614419 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414420
ttuttled9dbc652015-09-29 20:00:5914421 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414422 StaticSocketDataProvider data;
14423 data.set_connect_data(mock_connect);
14424 session_deps_.socket_factory->AddSocketDataProvider(&data);
14425
14426 TestCompletionCallback callback;
14427
tfarina428341112016-09-22 13:38:2014428 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114429 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414430
14431 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114432 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414433
[email protected]79e1fd62013-06-20 06:50:0414434 // We don't care whether this succeeds or fails, but it shouldn't crash.
14435 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614436 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714437
14438 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614439 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714440 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114441 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914442
14443 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614444 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914445 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414446}
14447
bncd16676a2016-07-20 16:23:0114448TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414449 HttpRequestInfo request;
14450 request.method = "GET";
bncce36dca22015-04-21 22:11:2314451 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414452
danakj1fd259a02016-04-16 03:17:0914453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614454 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414455
ttuttled9dbc652015-09-29 20:00:5914456 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414457 StaticSocketDataProvider data;
14458 data.set_connect_data(mock_connect);
14459 session_deps_.socket_factory->AddSocketDataProvider(&data);
14460
14461 TestCompletionCallback callback;
14462
tfarina428341112016-09-22 13:38:2014463 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114464 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414465
14466 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114467 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414468
[email protected]79e1fd62013-06-20 06:50:0414469 // We don't care whether this succeeds or fails, but it shouldn't crash.
14470 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614471 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714472
14473 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614474 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714475 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114476 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914477
14478 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614479 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914480 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414481}
14482
bncd16676a2016-07-20 16:23:0114483TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414484 HttpRequestInfo request;
14485 request.method = "GET";
bncce36dca22015-04-21 22:11:2314486 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414487
danakj1fd259a02016-04-16 03:17:0914488 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614489 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414490
14491 MockWrite data_writes[] = {
14492 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14493 };
14494 MockRead data_reads[] = {
14495 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14496 };
14497
14498 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14499 data_writes, arraysize(data_writes));
14500 session_deps_.socket_factory->AddSocketDataProvider(&data);
14501
14502 TestCompletionCallback callback;
14503
tfarina428341112016-09-22 13:38:2014504 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114505 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414506
14507 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114508 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414509
[email protected]79e1fd62013-06-20 06:50:0414510 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614511 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414512 EXPECT_TRUE(request_headers.HasHeader("Host"));
14513}
14514
bncd16676a2016-07-20 16:23:0114515TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414516 HttpRequestInfo request;
14517 request.method = "GET";
bncce36dca22015-04-21 22:11:2314518 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414519
danakj1fd259a02016-04-16 03:17:0914520 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614521 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414522
14523 MockWrite data_writes[] = {
14524 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14525 };
14526 MockRead data_reads[] = {
14527 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14528 };
14529
14530 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14531 data_writes, arraysize(data_writes));
14532 session_deps_.socket_factory->AddSocketDataProvider(&data);
14533
14534 TestCompletionCallback callback;
14535
tfarina428341112016-09-22 13:38:2014536 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114537 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414538
14539 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114540 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414541
[email protected]79e1fd62013-06-20 06:50:0414542 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614543 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414544 EXPECT_TRUE(request_headers.HasHeader("Host"));
14545}
14546
bncd16676a2016-07-20 16:23:0114547TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414548 HttpRequestInfo request;
14549 request.method = "GET";
bncce36dca22015-04-21 22:11:2314550 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414551
danakj1fd259a02016-04-16 03:17:0914552 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614553 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414554
14555 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314556 MockWrite(
14557 "GET / HTTP/1.1\r\n"
14558 "Host: www.example.org\r\n"
14559 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414560 };
14561 MockRead data_reads[] = {
14562 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14563 };
14564
14565 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14566 data_writes, arraysize(data_writes));
14567 session_deps_.socket_factory->AddSocketDataProvider(&data);
14568
14569 TestCompletionCallback callback;
14570
tfarina428341112016-09-22 13:38:2014571 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114572 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414573
14574 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114575 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414576
[email protected]79e1fd62013-06-20 06:50:0414577 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614578 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414579 EXPECT_TRUE(request_headers.HasHeader("Host"));
14580}
14581
bncd16676a2016-07-20 16:23:0114582TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414583 HttpRequestInfo request;
14584 request.method = "GET";
bncce36dca22015-04-21 22:11:2314585 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414586
danakj1fd259a02016-04-16 03:17:0914587 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614588 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414589
14590 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314591 MockWrite(
14592 "GET / HTTP/1.1\r\n"
14593 "Host: www.example.org\r\n"
14594 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414595 };
14596 MockRead data_reads[] = {
14597 MockRead(ASYNC, ERR_CONNECTION_RESET),
14598 };
14599
14600 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14601 data_writes, arraysize(data_writes));
14602 session_deps_.socket_factory->AddSocketDataProvider(&data);
14603
14604 TestCompletionCallback callback;
14605
tfarina428341112016-09-22 13:38:2014606 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114607 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414608
14609 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114610 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414611
[email protected]79e1fd62013-06-20 06:50:0414612 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614613 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414614 EXPECT_TRUE(request_headers.HasHeader("Host"));
14615}
14616
bncd16676a2016-07-20 16:23:0114617TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0414618 HttpRequestInfo request;
14619 request.method = "GET";
bncce36dca22015-04-21 22:11:2314620 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414621 request.extra_headers.SetHeader("X-Foo", "bar");
14622
danakj1fd259a02016-04-16 03:17:0914623 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614624 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414625
14626 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314627 MockWrite(
14628 "GET / HTTP/1.1\r\n"
14629 "Host: www.example.org\r\n"
14630 "Connection: keep-alive\r\n"
14631 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414632 };
14633 MockRead data_reads[] = {
14634 MockRead("HTTP/1.1 200 OK\r\n"
14635 "Content-Length: 5\r\n\r\n"
14636 "hello"),
14637 MockRead(ASYNC, ERR_UNEXPECTED),
14638 };
14639
14640 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14641 data_writes, arraysize(data_writes));
14642 session_deps_.socket_factory->AddSocketDataProvider(&data);
14643
14644 TestCompletionCallback callback;
14645
tfarina428341112016-09-22 13:38:2014646 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414648
14649 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114650 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0414651
14652 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614653 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414654 std::string foo;
14655 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14656 EXPECT_EQ("bar", foo);
14657}
14658
[email protected]bf828982013-08-14 18:01:4714659namespace {
14660
yhiranoa7e05bb2014-11-06 05:40:3914661// Fake HttpStream that simply records calls to SetPriority().
14662class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0314663 public base::SupportsWeakPtr<FakeStream> {
14664 public:
14665 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2014666 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0314667
14668 RequestPriority priority() const { return priority_; }
14669
dchengb03027d2014-10-21 12:00:2014670 int InitializeStream(const HttpRequestInfo* request_info,
14671 RequestPriority priority,
tfarina428341112016-09-22 13:38:2014672 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2014673 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314674 return ERR_IO_PENDING;
14675 }
14676
dchengb03027d2014-10-21 12:00:2014677 int SendRequest(const HttpRequestHeaders& request_headers,
14678 HttpResponseInfo* response,
14679 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314680 ADD_FAILURE();
14681 return ERR_UNEXPECTED;
14682 }
14683
dchengb03027d2014-10-21 12:00:2014684 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314685 ADD_FAILURE();
14686 return ERR_UNEXPECTED;
14687 }
14688
dchengb03027d2014-10-21 12:00:2014689 int ReadResponseBody(IOBuffer* buf,
14690 int buf_len,
14691 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314692 ADD_FAILURE();
14693 return ERR_UNEXPECTED;
14694 }
14695
dchengb03027d2014-10-21 12:00:2014696 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0314697
dchengb03027d2014-10-21 12:00:2014698 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0314699 ADD_FAILURE();
14700 return false;
14701 }
14702
dchengb03027d2014-10-21 12:00:2014703 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0314704 ADD_FAILURE();
14705 return false;
14706 }
14707
dchengb03027d2014-10-21 12:00:2014708 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314709
mmenkebd84c392015-09-02 14:12:3414710 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314711
sclittle4de1bab92015-09-22 21:28:2414712 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914713 ADD_FAILURE();
14714 return 0;
14715 }
14716
sclittlebe1ccf62015-09-02 19:40:3614717 int64_t GetTotalSentBytes() const override {
14718 ADD_FAILURE();
14719 return 0;
14720 }
14721
dchengb03027d2014-10-21 12:00:2014722 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314723 ADD_FAILURE();
14724 return false;
14725 }
14726
dchengb03027d2014-10-21 12:00:2014727 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14728
14729 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314730 ADD_FAILURE();
14731 }
14732
ttuttled9dbc652015-09-29 20:00:5914733 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14734
nharper78e6d2b2016-09-21 05:42:3514735 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
14736 TokenBindingType tb_type,
14737 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1414738 ADD_FAILURE();
14739 return ERR_NOT_IMPLEMENTED;
14740 }
14741
dchengb03027d2014-10-21 12:00:2014742 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314743
zhongyica364fbb2015-12-12 03:39:1214744 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14745
dchengb03027d2014-10-21 12:00:2014746 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314747
yhiranoa7e05bb2014-11-06 05:40:3914748 HttpStream* RenewStreamForAuth() override { return NULL; }
14749
[email protected]e86839fd2013-08-14 18:29:0314750 private:
14751 RequestPriority priority_;
14752
14753 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14754};
14755
14756// Fake HttpStreamRequest that simply records calls to SetPriority()
14757// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714758class FakeStreamRequest : public HttpStreamRequest,
14759 public base::SupportsWeakPtr<FakeStreamRequest> {
14760 public:
[email protected]e86839fd2013-08-14 18:29:0314761 FakeStreamRequest(RequestPriority priority,
14762 HttpStreamRequest::Delegate* delegate)
14763 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414764 delegate_(delegate),
14765 websocket_stream_create_helper_(NULL) {}
14766
14767 FakeStreamRequest(RequestPriority priority,
14768 HttpStreamRequest::Delegate* delegate,
14769 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14770 : priority_(priority),
14771 delegate_(delegate),
14772 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314773
dchengb03027d2014-10-21 12:00:2014774 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714775
14776 RequestPriority priority() const { return priority_; }
14777
[email protected]831e4a32013-11-14 02:14:4414778 const WebSocketHandshakeStreamBase::CreateHelper*
14779 websocket_stream_create_helper() const {
14780 return websocket_stream_create_helper_;
14781 }
14782
[email protected]e86839fd2013-08-14 18:29:0314783 // Create a new FakeStream and pass it to the request's
14784 // delegate. Returns a weak pointer to the FakeStream.
14785 base::WeakPtr<FakeStream> FinishStreamRequest() {
14786 FakeStream* fake_stream = new FakeStream(priority_);
14787 // Do this before calling OnStreamReady() as OnStreamReady() may
14788 // immediately delete |fake_stream|.
14789 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14790 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14791 return weak_stream;
14792 }
14793
dchengb03027d2014-10-21 12:00:2014794 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714795 ADD_FAILURE();
14796 return ERR_UNEXPECTED;
14797 }
14798
dchengb03027d2014-10-21 12:00:2014799 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714800 ADD_FAILURE();
14801 return LoadState();
14802 }
14803
dchengb03027d2014-10-21 12:00:2014804 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714805
bnc94c92842016-09-21 15:22:5214806 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714807
bnc6227b26e2016-08-12 02:00:4314808 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714809
dchengb03027d2014-10-21 12:00:2014810 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714811
ttuttle1f2d7e92015-04-28 16:17:4714812 const ConnectionAttempts& connection_attempts() const override {
14813 static ConnectionAttempts no_attempts;
14814 return no_attempts;
14815 }
14816
[email protected]bf828982013-08-14 18:01:4714817 private:
14818 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314819 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414820 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714821
14822 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14823};
14824
14825// Fake HttpStreamFactory that vends FakeStreamRequests.
14826class FakeStreamFactory : public HttpStreamFactory {
14827 public:
14828 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014829 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714830
14831 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14832 // RequestStream() (which may be NULL if it was destroyed already).
14833 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14834 return last_stream_request_;
14835 }
14836
dchengb03027d2014-10-21 12:00:2014837 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14838 RequestPriority priority,
14839 const SSLConfig& server_ssl_config,
14840 const SSLConfig& proxy_ssl_config,
14841 HttpStreamRequest::Delegate* delegate,
tfarina428341112016-09-22 13:38:2014842 const NetLogWithSource& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314843 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714844 last_stream_request_ = fake_request->AsWeakPtr();
14845 return fake_request;
14846 }
14847
xunjieli5749218c2016-03-22 16:43:0614848 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0814849 const HttpRequestInfo& info,
14850 RequestPriority priority,
14851 const SSLConfig& server_ssl_config,
14852 const SSLConfig& proxy_ssl_config,
14853 HttpStreamRequest::Delegate* delegate,
tfarina428341112016-09-22 13:38:2014854 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0814855 NOTREACHED();
14856 return nullptr;
14857 }
14858
dchengb03027d2014-10-21 12:00:2014859 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714860 const HttpRequestInfo& info,
14861 RequestPriority priority,
14862 const SSLConfig& server_ssl_config,
14863 const SSLConfig& proxy_ssl_config,
14864 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614865 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
tfarina428341112016-09-22 13:38:2014866 const NetLogWithSource& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414867 FakeStreamRequest* fake_request =
14868 new FakeStreamRequest(priority, delegate, create_helper);
14869 last_stream_request_ = fake_request->AsWeakPtr();
14870 return fake_request;
[email protected]bf828982013-08-14 18:01:4714871 }
14872
dchengb03027d2014-10-21 12:00:2014873 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5914874 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4714875 ADD_FAILURE();
14876 }
14877
dchengb03027d2014-10-21 12:00:2014878 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714879 ADD_FAILURE();
14880 return NULL;
14881 }
14882
14883 private:
14884 base::WeakPtr<FakeStreamRequest> last_stream_request_;
14885
14886 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
14887};
14888
Adam Rice425cf122015-01-19 06:18:2414889// TODO(ricea): Maybe unify this with the one in
14890// url_request_http_job_unittest.cc ?
14891class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
14892 public:
danakj1fd259a02016-04-16 03:17:0914893 FakeWebSocketBasicHandshakeStream(
14894 std::unique_ptr<ClientSocketHandle> connection,
14895 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5214896 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2414897
14898 // Fake implementation of HttpStreamBase methods.
14899 // This ends up being quite "real" because this object has to really send data
14900 // on the mock socket. It might be easier to use the real implementation, but
14901 // the fact that the WebSocket code is not compiled on iOS makes that
14902 // difficult.
14903 int InitializeStream(const HttpRequestInfo* request_info,
14904 RequestPriority priority,
tfarina428341112016-09-22 13:38:2014905 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2414906 const CompletionCallback& callback) override {
14907 state_.Initialize(request_info, priority, net_log, callback);
14908 return OK;
14909 }
14910
14911 int SendRequest(const HttpRequestHeaders& request_headers,
14912 HttpResponseInfo* response,
14913 const CompletionCallback& callback) override {
14914 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
14915 response, callback);
14916 }
14917
14918 int ReadResponseHeaders(const CompletionCallback& callback) override {
14919 return parser()->ReadResponseHeaders(callback);
14920 }
14921
14922 int ReadResponseBody(IOBuffer* buf,
14923 int buf_len,
14924 const CompletionCallback& callback) override {
14925 NOTREACHED();
14926 return ERR_IO_PENDING;
14927 }
14928
14929 void Close(bool not_reusable) override {
14930 if (parser())
14931 parser()->Close(true);
14932 }
14933
14934 bool IsResponseBodyComplete() const override {
14935 NOTREACHED();
14936 return false;
14937 }
14938
Adam Rice425cf122015-01-19 06:18:2414939 bool IsConnectionReused() const override {
14940 NOTREACHED();
14941 return false;
14942 }
14943 void SetConnectionReused() override { NOTREACHED(); }
14944
mmenkebd84c392015-09-02 14:12:3414945 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2414946
sclittle4de1bab92015-09-22 21:28:2414947 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2414948 NOTREACHED();
14949 return 0;
14950 }
14951
sclittlebe1ccf62015-09-02 19:40:3614952 int64_t GetTotalSentBytes() const override {
14953 NOTREACHED();
14954 return 0;
14955 }
14956
Adam Rice425cf122015-01-19 06:18:2414957 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
14958 NOTREACHED();
14959 return false;
14960 }
14961
Adam Ricecb76ac62015-02-20 05:33:2514962 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2414963
14964 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
14965 NOTREACHED();
14966 }
14967
ttuttled9dbc652015-09-29 20:00:5914968 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14969
nharper78e6d2b2016-09-21 05:42:3514970 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
14971 TokenBindingType tb_type,
14972 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1414973 ADD_FAILURE();
14974 return ERR_NOT_IMPLEMENTED;
14975 }
14976
Adam Rice425cf122015-01-19 06:18:2414977 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
14978
zhongyica364fbb2015-12-12 03:39:1214979 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14980
Adam Rice425cf122015-01-19 06:18:2414981 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
14982
Adam Rice425cf122015-01-19 06:18:2414983 HttpStream* RenewStreamForAuth() override {
14984 NOTREACHED();
14985 return nullptr;
14986 }
14987
14988 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0914989 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2414990 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0914991 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2414992 }
14993
14994 private:
14995 HttpStreamParser* parser() const { return state_.parser(); }
14996 HttpBasicState state_;
14997
14998 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
14999};
15000
[email protected]831e4a32013-11-14 02:14:4415001// TODO(yhirano): Split this class out into a net/websockets file, if it is
15002// worth doing.
15003class FakeWebSocketStreamCreateHelper :
15004 public WebSocketHandshakeStreamBase::CreateHelper {
15005 public:
dchengb03027d2014-10-21 12:00:2015006 WebSocketHandshakeStreamBase* CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915007 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315008 bool using_proxy) override {
dchengc7eeda422015-12-26 03:56:4815009 return new FakeWebSocketBasicHandshakeStream(std::move(connection),
Adam Rice425cf122015-01-19 06:18:2415010 using_proxy);
[email protected]831e4a32013-11-14 02:14:4415011 }
15012
dchengb03027d2014-10-21 12:00:2015013 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4415014 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1315015 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4415016 NOTREACHED();
15017 return NULL;
15018 };
15019
dchengb03027d2014-10-21 12:00:2015020 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415021
danakj1fd259a02016-04-16 03:17:0915022 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415023 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915024 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415025 }
15026};
15027
[email protected]bf828982013-08-14 18:01:4715028} // namespace
15029
15030// Make sure that HttpNetworkTransaction passes on its priority to its
15031// stream request on start.
bncd16676a2016-07-20 16:23:0115032TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915033 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215034 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715035 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915036 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715037
dcheng48459ac22014-08-26 00:46:4115038 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715039
wezca1070932016-05-26 20:30:5215040 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715041
15042 HttpRequestInfo request;
15043 TestCompletionCallback callback;
15044 EXPECT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2015045 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715046
15047 base::WeakPtr<FakeStreamRequest> fake_request =
15048 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215049 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715050 EXPECT_EQ(LOW, fake_request->priority());
15051}
15052
15053// Make sure that HttpNetworkTransaction passes on its priority
15054// updates to its stream request.
bncd16676a2016-07-20 16:23:0115055TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915056 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215057 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715058 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915059 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715060
dcheng48459ac22014-08-26 00:46:4115061 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715062
15063 HttpRequestInfo request;
15064 TestCompletionCallback callback;
15065 EXPECT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2015066 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715067
15068 base::WeakPtr<FakeStreamRequest> fake_request =
15069 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215070 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715071 EXPECT_EQ(LOW, fake_request->priority());
15072
15073 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215074 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715075 EXPECT_EQ(LOWEST, fake_request->priority());
15076}
15077
[email protected]e86839fd2013-08-14 18:29:0315078// Make sure that HttpNetworkTransaction passes on its priority
15079// updates to its stream.
bncd16676a2016-07-20 16:23:0115080TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915081 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215082 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315083 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915084 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315085
dcheng48459ac22014-08-26 00:46:4115086 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315087
15088 HttpRequestInfo request;
15089 TestCompletionCallback callback;
15090 EXPECT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2015091 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315092
15093 base::WeakPtr<FakeStreamRequest> fake_request =
15094 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215095 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315096 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215097 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315098 EXPECT_EQ(LOW, fake_stream->priority());
15099
15100 trans.SetPriority(LOWEST);
15101 EXPECT_EQ(LOWEST, fake_stream->priority());
15102}
15103
bncd16676a2016-07-20 16:23:0115104TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415105 // The same logic needs to be tested for both ws: and wss: schemes, but this
15106 // test is already parameterised on NextProto, so it uses a loop to verify
15107 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315108 std::string test_cases[] = {"ws://www.example.org/",
15109 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415110 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915111 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215112 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415113 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15114 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315115 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915116 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415117
dcheng48459ac22014-08-26 00:46:4115118 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415119 trans.SetWebSocketHandshakeStreamCreateHelper(
15120 &websocket_stream_create_helper);
15121
15122 HttpRequestInfo request;
15123 TestCompletionCallback callback;
15124 request.method = "GET";
15125 request.url = GURL(test_cases[i]);
15126
15127 EXPECT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2015128 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415129
15130 base::WeakPtr<FakeStreamRequest> fake_request =
15131 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215132 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415133 EXPECT_EQ(&websocket_stream_create_helper,
15134 fake_request->websocket_stream_create_helper());
15135 }
15136}
15137
[email protected]043b68c82013-08-22 23:41:5215138// Tests that when a used socket is returned to the SSL socket pool, it's closed
15139// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115140TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215141 ClientSocketPoolManager::set_max_sockets_per_group(
15142 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15143 ClientSocketPoolManager::set_max_sockets_per_pool(
15144 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15145
15146 // Set up SSL request.
15147
15148 HttpRequestInfo ssl_request;
15149 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315150 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215151
15152 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315153 MockWrite(
15154 "GET / HTTP/1.1\r\n"
15155 "Host: www.example.org\r\n"
15156 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215157 };
15158 MockRead ssl_reads[] = {
15159 MockRead("HTTP/1.1 200 OK\r\n"),
15160 MockRead("Content-Length: 11\r\n\r\n"),
15161 MockRead("hello world"),
15162 MockRead(SYNCHRONOUS, OK),
15163 };
15164 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15165 ssl_writes, arraysize(ssl_writes));
15166 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15167
15168 SSLSocketDataProvider ssl(ASYNC, OK);
15169 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15170
15171 // Set up HTTP request.
15172
15173 HttpRequestInfo http_request;
15174 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315175 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215176
15177 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315178 MockWrite(
15179 "GET / HTTP/1.1\r\n"
15180 "Host: www.example.org\r\n"
15181 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215182 };
15183 MockRead http_reads[] = {
15184 MockRead("HTTP/1.1 200 OK\r\n"),
15185 MockRead("Content-Length: 7\r\n\r\n"),
15186 MockRead("falafel"),
15187 MockRead(SYNCHRONOUS, OK),
15188 };
15189 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15190 http_writes, arraysize(http_writes));
15191 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15192
danakj1fd259a02016-04-16 03:17:0915193 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215194
15195 // Start the SSL request.
15196 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615197 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:2015198 ASSERT_EQ(ERR_IO_PENDING,
15199 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15200 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215201
15202 // Start the HTTP request. Pool should stall.
15203 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615204 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:2015205 ASSERT_EQ(ERR_IO_PENDING,
15206 http_trans.Start(&http_request, http_callback.callback(),
15207 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115208 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215209
15210 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115211 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215212 std::string response_data;
bnc691fda62016-08-12 00:43:1615213 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215214 EXPECT_EQ("hello world", response_data);
15215
15216 // The SSL socket should automatically be closed, so the HTTP request can
15217 // start.
dcheng48459ac22014-08-26 00:46:4115218 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15219 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215220
15221 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115222 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615223 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215224 EXPECT_EQ("falafel", response_data);
15225
dcheng48459ac22014-08-26 00:46:4115226 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215227}
15228
15229// Tests that when a SSL connection is established but there's no corresponding
15230// request that needs it, the new socket is closed if the transport socket pool
15231// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115232TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215233 ClientSocketPoolManager::set_max_sockets_per_group(
15234 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15235 ClientSocketPoolManager::set_max_sockets_per_pool(
15236 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15237
15238 // Set up an ssl request.
15239
15240 HttpRequestInfo ssl_request;
15241 ssl_request.method = "GET";
15242 ssl_request.url = GURL("https://www.foopy.com/");
15243
15244 // No data will be sent on the SSL socket.
15245 StaticSocketDataProvider ssl_data;
15246 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15247
15248 SSLSocketDataProvider ssl(ASYNC, OK);
15249 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15250
15251 // Set up HTTP request.
15252
15253 HttpRequestInfo http_request;
15254 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315255 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215256
15257 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315258 MockWrite(
15259 "GET / HTTP/1.1\r\n"
15260 "Host: www.example.org\r\n"
15261 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215262 };
15263 MockRead http_reads[] = {
15264 MockRead("HTTP/1.1 200 OK\r\n"),
15265 MockRead("Content-Length: 7\r\n\r\n"),
15266 MockRead("falafel"),
15267 MockRead(SYNCHRONOUS, OK),
15268 };
15269 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15270 http_writes, arraysize(http_writes));
15271 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15272
danakj1fd259a02016-04-16 03:17:0915273 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215274
15275 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15276 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915277 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915278 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115279 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215280
15281 // Start the HTTP request. Pool should stall.
15282 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615283 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:2015284 ASSERT_EQ(ERR_IO_PENDING,
15285 http_trans.Start(&http_request, http_callback.callback(),
15286 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115287 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215288
15289 // The SSL connection will automatically be closed once the connection is
15290 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0115291 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215292 std::string response_data;
bnc691fda62016-08-12 00:43:1615293 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215294 EXPECT_EQ("falafel", response_data);
15295
dcheng48459ac22014-08-26 00:46:4115296 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215297}
15298
bncd16676a2016-07-20 16:23:0115299TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915300 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215301 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715302 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215303 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415304
15305 HttpRequestInfo request;
15306 request.method = "POST";
15307 request.url = GURL("http://www.foo.com/");
15308 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415309
danakj1fd259a02016-04-16 03:17:0915310 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615311 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415312 // Send headers successfully, but get an error while sending the body.
15313 MockWrite data_writes[] = {
15314 MockWrite("POST / HTTP/1.1\r\n"
15315 "Host: www.foo.com\r\n"
15316 "Connection: keep-alive\r\n"
15317 "Content-Length: 3\r\n\r\n"),
15318 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15319 };
15320
15321 MockRead data_reads[] = {
15322 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15323 MockRead("hello world"),
15324 MockRead(SYNCHRONOUS, OK),
15325 };
15326 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15327 arraysize(data_writes));
15328 session_deps_.socket_factory->AddSocketDataProvider(&data);
15329
15330 TestCompletionCallback callback;
15331
tfarina428341112016-09-22 13:38:2015332 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115333 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415334
15335 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115336 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415337
bnc691fda62016-08-12 00:43:1615338 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215339 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415340
wezca1070932016-05-26 20:30:5215341 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415342 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15343
15344 std::string response_data;
bnc691fda62016-08-12 00:43:1615345 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115346 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415347 EXPECT_EQ("hello world", response_data);
15348}
15349
15350// This test makes sure the retry logic doesn't trigger when reading an error
15351// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0115352TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415353 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415355 MockWrite data_writes[] = {
15356 MockWrite("GET / HTTP/1.1\r\n"
15357 "Host: www.foo.com\r\n"
15358 "Connection: keep-alive\r\n\r\n"),
15359 MockWrite("POST / HTTP/1.1\r\n"
15360 "Host: www.foo.com\r\n"
15361 "Connection: keep-alive\r\n"
15362 "Content-Length: 3\r\n\r\n"),
15363 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15364 };
15365
15366 MockRead data_reads[] = {
15367 MockRead("HTTP/1.1 200 Peachy\r\n"
15368 "Content-Length: 14\r\n\r\n"),
15369 MockRead("first response"),
15370 MockRead("HTTP/1.1 400 Not OK\r\n"
15371 "Content-Length: 15\r\n\r\n"),
15372 MockRead("second response"),
15373 MockRead(SYNCHRONOUS, OK),
15374 };
15375 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15376 arraysize(data_writes));
15377 session_deps_.socket_factory->AddSocketDataProvider(&data);
15378
15379 TestCompletionCallback callback;
15380 HttpRequestInfo request1;
15381 request1.method = "GET";
15382 request1.url = GURL("http://www.foo.com/");
15383 request1.load_flags = 0;
15384
bnc691fda62016-08-12 00:43:1615385 std::unique_ptr<HttpNetworkTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4115386 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina428341112016-09-22 13:38:2015387 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115388 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415389
15390 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115391 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415392
15393 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215394 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415395
wezca1070932016-05-26 20:30:5215396 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415397 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15398
15399 std::string response_data1;
15400 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0115401 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415402 EXPECT_EQ("first response", response_data1);
15403 // Delete the transaction to release the socket back into the socket pool.
15404 trans1.reset();
15405
danakj1fd259a02016-04-16 03:17:0915406 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215407 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915408 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215409 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415410
15411 HttpRequestInfo request2;
15412 request2.method = "POST";
15413 request2.url = GURL("http://www.foo.com/");
15414 request2.upload_data_stream = &upload_data_stream;
15415 request2.load_flags = 0;
15416
bnc691fda62016-08-12 00:43:1615417 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina428341112016-09-22 13:38:2015418 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115419 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415420
15421 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115422 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415423
bnc691fda62016-08-12 00:43:1615424 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215425 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415426
wezca1070932016-05-26 20:30:5215427 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415428 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15429
15430 std::string response_data2;
bnc691fda62016-08-12 00:43:1615431 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0115432 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415433 EXPECT_EQ("second response", response_data2);
15434}
15435
bncd16676a2016-07-20 16:23:0115436TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415437 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915438 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215439 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715440 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215441 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415442
15443 HttpRequestInfo request;
15444 request.method = "POST";
15445 request.url = GURL("http://www.foo.com/");
15446 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415447
danakj1fd259a02016-04-16 03:17:0915448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615449 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415450 // Send headers successfully, but get an error while sending the body.
15451 MockWrite data_writes[] = {
15452 MockWrite("POST / HTTP/1.1\r\n"
15453 "Host: www.foo.com\r\n"
15454 "Connection: keep-alive\r\n"
15455 "Content-Length: 3\r\n\r\n"
15456 "fo"),
15457 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15458 };
15459
15460 MockRead data_reads[] = {
15461 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15462 MockRead("hello world"),
15463 MockRead(SYNCHRONOUS, OK),
15464 };
15465 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15466 arraysize(data_writes));
15467 session_deps_.socket_factory->AddSocketDataProvider(&data);
15468
15469 TestCompletionCallback callback;
15470
tfarina428341112016-09-22 13:38:2015471 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115472 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415473
15474 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115475 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415476
bnc691fda62016-08-12 00:43:1615477 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215478 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415479
wezca1070932016-05-26 20:30:5215480 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415481 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15482
15483 std::string response_data;
bnc691fda62016-08-12 00:43:1615484 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115485 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415486 EXPECT_EQ("hello world", response_data);
15487}
15488
15489// This tests the more common case than the previous test, where headers and
15490// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0115491TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715492 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415493
15494 HttpRequestInfo request;
15495 request.method = "POST";
15496 request.url = GURL("http://www.foo.com/");
15497 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415498
danakj1fd259a02016-04-16 03:17:0915499 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615500 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415501 // Send headers successfully, but get an error while sending the body.
15502 MockWrite data_writes[] = {
15503 MockWrite("POST / HTTP/1.1\r\n"
15504 "Host: www.foo.com\r\n"
15505 "Connection: keep-alive\r\n"
15506 "Transfer-Encoding: chunked\r\n\r\n"),
15507 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15508 };
15509
15510 MockRead data_reads[] = {
15511 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15512 MockRead("hello world"),
15513 MockRead(SYNCHRONOUS, OK),
15514 };
15515 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15516 arraysize(data_writes));
15517 session_deps_.socket_factory->AddSocketDataProvider(&data);
15518
15519 TestCompletionCallback callback;
15520
tfarina428341112016-09-22 13:38:2015521 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115522 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415523 // Make sure the headers are sent before adding a chunk. This ensures that
15524 // they can't be merged with the body in a single send. Not currently
15525 // necessary since a chunked body is never merged with headers, but this makes
15526 // the test more future proof.
15527 base::RunLoop().RunUntilIdle();
15528
mmenkecbc2b712014-10-09 20:29:0715529 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415530
15531 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115532 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415533
bnc691fda62016-08-12 00:43:1615534 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215535 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415536
wezca1070932016-05-26 20:30:5215537 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415538 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15539
15540 std::string response_data;
bnc691fda62016-08-12 00:43:1615541 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115542 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415543 EXPECT_EQ("hello world", response_data);
15544}
15545
bncd16676a2016-07-20 16:23:0115546TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915547 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215548 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715549 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215550 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415551
15552 HttpRequestInfo request;
15553 request.method = "POST";
15554 request.url = GURL("http://www.foo.com/");
15555 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415556
danakj1fd259a02016-04-16 03:17:0915557 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615558 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415559
15560 MockWrite data_writes[] = {
15561 MockWrite("POST / HTTP/1.1\r\n"
15562 "Host: www.foo.com\r\n"
15563 "Connection: keep-alive\r\n"
15564 "Content-Length: 3\r\n\r\n"),
15565 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15566 };
15567
15568 MockRead data_reads[] = {
15569 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15570 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15571 MockRead("hello world"),
15572 MockRead(SYNCHRONOUS, OK),
15573 };
15574 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15575 arraysize(data_writes));
15576 session_deps_.socket_factory->AddSocketDataProvider(&data);
15577
15578 TestCompletionCallback callback;
15579
tfarina428341112016-09-22 13:38:2015580 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115581 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415582
15583 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115584 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415585
bnc691fda62016-08-12 00:43:1615586 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215587 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415588
wezca1070932016-05-26 20:30:5215589 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415590 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15591
15592 std::string response_data;
bnc691fda62016-08-12 00:43:1615593 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115594 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415595 EXPECT_EQ("hello world", response_data);
15596}
15597
bncd16676a2016-07-20 16:23:0115598TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915599 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215600 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715601 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215602 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415603
15604 HttpRequestInfo request;
15605 request.method = "POST";
15606 request.url = GURL("http://www.foo.com/");
15607 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415608
danakj1fd259a02016-04-16 03:17:0915609 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615610 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415611 // Send headers successfully, but get an error while sending the body.
15612 MockWrite data_writes[] = {
15613 MockWrite("POST / HTTP/1.1\r\n"
15614 "Host: www.foo.com\r\n"
15615 "Connection: keep-alive\r\n"
15616 "Content-Length: 3\r\n\r\n"),
15617 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15618 };
15619
15620 MockRead data_reads[] = {
15621 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15622 MockRead("hello world"),
15623 MockRead(SYNCHRONOUS, OK),
15624 };
15625 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15626 arraysize(data_writes));
15627 session_deps_.socket_factory->AddSocketDataProvider(&data);
15628
15629 TestCompletionCallback callback;
15630
tfarina428341112016-09-22 13:38:2015631 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115632 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415633
15634 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115635 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415636}
15637
bncd16676a2016-07-20 16:23:0115638TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415639 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915640 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215641 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715642 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215643 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415644
15645 HttpRequestInfo request;
15646 request.method = "POST";
15647 request.url = GURL("http://www.foo.com/");
15648 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415649
danakj1fd259a02016-04-16 03:17:0915650 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615651 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415652 // Send headers successfully, but get an error while sending the body.
15653 MockWrite data_writes[] = {
15654 MockWrite("POST / HTTP/1.1\r\n"
15655 "Host: www.foo.com\r\n"
15656 "Connection: keep-alive\r\n"
15657 "Content-Length: 3\r\n\r\n"),
15658 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15659 };
15660
15661 MockRead data_reads[] = {
15662 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15663 MockRead("HTTP/1.0 302 Redirect\r\n"),
15664 MockRead("Location: http://somewhere-else.com/\r\n"),
15665 MockRead("Content-Length: 0\r\n\r\n"),
15666 MockRead(SYNCHRONOUS, OK),
15667 };
15668 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15669 arraysize(data_writes));
15670 session_deps_.socket_factory->AddSocketDataProvider(&data);
15671
15672 TestCompletionCallback callback;
15673
tfarina428341112016-09-22 13:38:2015674 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415676
15677 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115678 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415679}
15680
bncd16676a2016-07-20 16:23:0115681TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915682 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215683 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715684 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215685 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415686
15687 HttpRequestInfo request;
15688 request.method = "POST";
15689 request.url = GURL("http://www.foo.com/");
15690 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415691
danakj1fd259a02016-04-16 03:17:0915692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415694 // Send headers successfully, but get an error while sending the body.
15695 MockWrite data_writes[] = {
15696 MockWrite("POST / HTTP/1.1\r\n"
15697 "Host: www.foo.com\r\n"
15698 "Connection: keep-alive\r\n"
15699 "Content-Length: 3\r\n\r\n"),
15700 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15701 };
15702
15703 MockRead data_reads[] = {
15704 MockRead("HTTP 0.9 rocks!"),
15705 MockRead(SYNCHRONOUS, OK),
15706 };
15707 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15708 arraysize(data_writes));
15709 session_deps_.socket_factory->AddSocketDataProvider(&data);
15710
15711 TestCompletionCallback callback;
15712
tfarina428341112016-09-22 13:38:2015713 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415715
15716 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115717 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415718}
15719
bncd16676a2016-07-20 16:23:0115720TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0915721 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215722 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715723 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215724 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415725
15726 HttpRequestInfo request;
15727 request.method = "POST";
15728 request.url = GURL("http://www.foo.com/");
15729 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415730
danakj1fd259a02016-04-16 03:17:0915731 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615732 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415733 // Send headers successfully, but get an error while sending the body.
15734 MockWrite data_writes[] = {
15735 MockWrite("POST / HTTP/1.1\r\n"
15736 "Host: www.foo.com\r\n"
15737 "Connection: keep-alive\r\n"
15738 "Content-Length: 3\r\n\r\n"),
15739 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15740 };
15741
15742 MockRead data_reads[] = {
15743 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15744 MockRead(SYNCHRONOUS, OK),
15745 };
15746 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15747 arraysize(data_writes));
15748 session_deps_.socket_factory->AddSocketDataProvider(&data);
15749
15750 TestCompletionCallback callback;
15751
tfarina428341112016-09-22 13:38:2015752 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115753 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415754
15755 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115756 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415757}
15758
Adam Rice425cf122015-01-19 06:18:2415759// Verify that proxy headers are not sent to the destination server when
15760// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0115761TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2415762 HttpRequestInfo request;
15763 request.method = "GET";
bncce36dca22015-04-21 22:11:2315764 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415765 AddWebSocketHeaders(&request.extra_headers);
15766
15767 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315768 session_deps_.proxy_service =
15769 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415770
danakj1fd259a02016-04-16 03:17:0915771 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415772
15773 // Since a proxy is configured, try to establish a tunnel.
15774 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1715775 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15776 "Host: www.example.org:443\r\n"
15777 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415778
15779 // After calling trans->RestartWithAuth(), this is the request we should
15780 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1715781 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15782 "Host: www.example.org:443\r\n"
15783 "Proxy-Connection: keep-alive\r\n"
15784 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415785
rsleevidb16bb02015-11-12 23:47:1715786 MockWrite("GET / HTTP/1.1\r\n"
15787 "Host: www.example.org\r\n"
15788 "Connection: Upgrade\r\n"
15789 "Upgrade: websocket\r\n"
15790 "Origin: http://www.example.org\r\n"
15791 "Sec-WebSocket-Version: 13\r\n"
15792 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415793 };
15794
15795 // The proxy responds to the connect with a 407, using a persistent
15796 // connection.
15797 MockRead data_reads[] = {
15798 // No credentials.
15799 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15800 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415801 MockRead("Content-Length: 0\r\n"),
15802 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415803
15804 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15805
15806 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15807 MockRead("Upgrade: websocket\r\n"),
15808 MockRead("Connection: Upgrade\r\n"),
15809 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15810 };
15811
15812 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15813 arraysize(data_writes));
15814 session_deps_.socket_factory->AddSocketDataProvider(&data);
15815 SSLSocketDataProvider ssl(ASYNC, OK);
15816 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15817
bnc691fda62016-08-12 00:43:1615818 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415819 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15820 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15821 trans->SetWebSocketHandshakeStreamCreateHelper(
15822 &websocket_stream_create_helper);
15823
15824 {
15825 TestCompletionCallback callback;
15826
tfarina428341112016-09-22 13:38:2015827 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115828 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2415829
15830 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115831 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2415832 }
15833
15834 const HttpResponseInfo* response = trans->GetResponseInfo();
15835 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215836 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415837 EXPECT_EQ(407, response->headers->response_code());
15838
15839 {
15840 TestCompletionCallback callback;
15841
15842 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15843 callback.callback());
robpercival214763f2016-07-01 23:27:0115844 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2415845
15846 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115847 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2415848 }
15849
15850 response = trans->GetResponseInfo();
15851 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215852 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415853
15854 EXPECT_EQ(101, response->headers->response_code());
15855
15856 trans.reset();
15857 session->CloseAllConnections();
15858}
15859
15860// Verify that proxy headers are not sent to the destination server when
15861// establishing a tunnel for an insecure WebSocket connection.
15862// This requires the authentication info to be injected into the auth cache
15863// due to crbug.com/395064
15864// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0115865TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2415866 HttpRequestInfo request;
15867 request.method = "GET";
bncce36dca22015-04-21 22:11:2315868 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415869 AddWebSocketHeaders(&request.extra_headers);
15870
15871 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315872 session_deps_.proxy_service =
15873 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415874
danakj1fd259a02016-04-16 03:17:0915875 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415876
15877 MockWrite data_writes[] = {
15878 // Try to establish a tunnel for the WebSocket connection, with
15879 // credentials. Because WebSockets have a separate set of socket pools,
15880 // they cannot and will not use the same TCP/IP connection as the
15881 // preflight HTTP request.
15882 MockWrite(
bncce36dca22015-04-21 22:11:2315883 "CONNECT www.example.org:80 HTTP/1.1\r\n"
15884 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2415885 "Proxy-Connection: keep-alive\r\n"
15886 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15887
15888 MockWrite(
15889 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315890 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415891 "Connection: Upgrade\r\n"
15892 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315893 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415894 "Sec-WebSocket-Version: 13\r\n"
15895 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
15896 };
15897
15898 MockRead data_reads[] = {
15899 // HTTP CONNECT with credentials.
15900 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15901
15902 // WebSocket connection established inside tunnel.
15903 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15904 MockRead("Upgrade: websocket\r\n"),
15905 MockRead("Connection: Upgrade\r\n"),
15906 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15907 };
15908
15909 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15910 arraysize(data_writes));
15911 session_deps_.socket_factory->AddSocketDataProvider(&data);
15912
15913 session->http_auth_cache()->Add(
15914 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
15915 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
15916
bnc691fda62016-08-12 00:43:1615917 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415918 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15919 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15920 trans->SetWebSocketHandshakeStreamCreateHelper(
15921 &websocket_stream_create_helper);
15922
15923 TestCompletionCallback callback;
15924
tfarina428341112016-09-22 13:38:2015925 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2415927
15928 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115929 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2415930
15931 const HttpResponseInfo* response = trans->GetResponseInfo();
15932 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215933 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415934
15935 EXPECT_EQ(101, response->headers->response_code());
15936
15937 trans.reset();
15938 session->CloseAllConnections();
15939}
15940
bncd16676a2016-07-20 16:23:0115941TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0915942 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215943 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715944 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215945 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215946
15947 HttpRequestInfo request;
15948 request.method = "POST";
15949 request.url = GURL("http://www.foo.com/");
15950 request.upload_data_stream = &upload_data_stream;
15951
danakj1fd259a02016-04-16 03:17:0915952 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615953 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2215954 MockWrite data_writes[] = {
15955 MockWrite("POST / HTTP/1.1\r\n"
15956 "Host: www.foo.com\r\n"
15957 "Connection: keep-alive\r\n"
15958 "Content-Length: 3\r\n\r\n"),
15959 MockWrite("foo"),
15960 };
15961
15962 MockRead data_reads[] = {
15963 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15964 MockRead(SYNCHRONOUS, OK),
15965 };
15966 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15967 arraysize(data_writes));
15968 session_deps_.socket_factory->AddSocketDataProvider(&data);
15969
15970 TestCompletionCallback callback;
15971
15972 EXPECT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2015973 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115974 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2215975
15976 std::string response_data;
bnc691fda62016-08-12 00:43:1615977 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2215978
15979 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1615980 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2215981 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1615982 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2215983}
15984
bncd16676a2016-07-20 16:23:0115985TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0915986 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215987 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715988 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215989 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215990
15991 HttpRequestInfo request;
15992 request.method = "POST";
15993 request.url = GURL("http://www.foo.com/");
15994 request.upload_data_stream = &upload_data_stream;
15995
danakj1fd259a02016-04-16 03:17:0915996 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615997 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2215998 MockWrite data_writes[] = {
15999 MockWrite("POST / HTTP/1.1\r\n"
16000 "Host: www.foo.com\r\n"
16001 "Connection: keep-alive\r\n"
16002 "Content-Length: 3\r\n\r\n"),
16003 MockWrite("foo"),
16004 };
16005
16006 MockRead data_reads[] = {
16007 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16008 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16009 MockRead(SYNCHRONOUS, OK),
16010 };
16011 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16012 arraysize(data_writes));
16013 session_deps_.socket_factory->AddSocketDataProvider(&data);
16014
16015 TestCompletionCallback callback;
16016
16017 EXPECT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2016018 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116019 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216020
16021 std::string response_data;
bnc691fda62016-08-12 00:43:1616022 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216023
16024 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616025 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216026 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616027 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216028}
16029
bncd16676a2016-07-20 16:23:0116030TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216031 ChunkedUploadDataStream upload_data_stream(0);
16032
16033 HttpRequestInfo request;
16034 request.method = "POST";
16035 request.url = GURL("http://www.foo.com/");
16036 request.upload_data_stream = &upload_data_stream;
16037
danakj1fd259a02016-04-16 03:17:0916038 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616039 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216040 // Send headers successfully, but get an error while sending the body.
16041 MockWrite data_writes[] = {
16042 MockWrite("POST / HTTP/1.1\r\n"
16043 "Host: www.foo.com\r\n"
16044 "Connection: keep-alive\r\n"
16045 "Transfer-Encoding: chunked\r\n\r\n"),
16046 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16047 };
16048
16049 MockRead data_reads[] = {
16050 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16051 MockRead(SYNCHRONOUS, OK),
16052 };
16053 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16054 arraysize(data_writes));
16055 session_deps_.socket_factory->AddSocketDataProvider(&data);
16056
16057 TestCompletionCallback callback;
16058
16059 EXPECT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2016060 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216061
16062 base::RunLoop().RunUntilIdle();
16063 upload_data_stream.AppendData("f", 1, false);
16064
16065 base::RunLoop().RunUntilIdle();
16066 upload_data_stream.AppendData("oo", 2, true);
16067
robpercival214763f2016-07-01 23:27:0116068 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216069
16070 std::string response_data;
bnc691fda62016-08-12 00:43:1616071 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216072
16073 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616074 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216075 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616076 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216077}
16078
rdsmith1d343be52016-10-21 20:37:5016079// Confirm that transactions whose throttle is created in (and stays in)
16080// the unthrottled state are not blocked.
16081TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16082 TestNetworkStreamThrottler* throttler(nullptr);
16083 std::unique_ptr<HttpNetworkSession> session(
16084 CreateSessionWithThrottler(&session_deps_, &throttler));
16085
16086 // Send a simple request and make sure it goes through.
16087 HttpRequestInfo request;
16088 request.method = "GET";
16089 request.url = GURL("http://www.example.org/");
16090
16091 std::unique_ptr<HttpTransaction> trans(
16092 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16093
16094 MockWrite data_writes[] = {
16095 MockWrite("GET / HTTP/1.1\r\n"
16096 "Host: www.example.org\r\n"
16097 "Connection: keep-alive\r\n\r\n"),
16098 };
16099 MockRead data_reads[] = {
16100 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16101 MockRead(SYNCHRONOUS, OK),
16102 };
16103 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16104 arraysize(data_writes));
16105 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16106
16107 TestCompletionCallback callback;
16108 trans->Start(&request, callback.callback(), NetLogWithSource());
16109 EXPECT_EQ(OK, callback.WaitForResult());
16110}
16111
16112// Confirm requests can be blocked by a throttler, and are resumed
16113// when the throttle is unblocked.
16114TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16115 TestNetworkStreamThrottler* throttler(nullptr);
16116 std::unique_ptr<HttpNetworkSession> session(
16117 CreateSessionWithThrottler(&session_deps_, &throttler));
16118
16119 // Send a simple request and make sure it goes through.
16120 HttpRequestInfo request;
16121 request.method = "GET";
16122 request.url = GURL("http://www.example.org/");
16123
16124 MockWrite data_writes[] = {
16125 MockWrite("GET / HTTP/1.1\r\n"
16126 "Host: www.example.org\r\n"
16127 "Connection: keep-alive\r\n\r\n"),
16128 };
16129 MockRead data_reads[] = {
16130 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16131 MockRead(SYNCHRONOUS, OK),
16132 };
16133 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16134 arraysize(data_writes));
16135 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16136
16137 // Start a request that will be throttled at start; confirm it
16138 // doesn't complete.
16139 throttler->set_throttle_new_requests(true);
16140 std::unique_ptr<HttpTransaction> trans(
16141 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16142
16143 TestCompletionCallback callback;
16144 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16145 EXPECT_EQ(ERR_IO_PENDING, rv);
16146
16147 base::RunLoop().RunUntilIdle();
16148 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16149 EXPECT_FALSE(callback.have_result());
16150
16151 // Confirm the request goes on to complete when unthrottled.
16152 throttler->UnthrottleAllRequests();
16153 base::RunLoop().RunUntilIdle();
16154 ASSERT_TRUE(callback.have_result());
16155 EXPECT_EQ(OK, callback.WaitForResult());
16156}
16157
16158// Destroy a request while it's throttled.
16159TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16160 TestNetworkStreamThrottler* throttler(nullptr);
16161 std::unique_ptr<HttpNetworkSession> session(
16162 CreateSessionWithThrottler(&session_deps_, &throttler));
16163
16164 // Send a simple request and make sure it goes through.
16165 HttpRequestInfo request;
16166 request.method = "GET";
16167 request.url = GURL("http://www.example.org/");
16168
16169 MockWrite data_writes[] = {
16170 MockWrite("GET / HTTP/1.1\r\n"
16171 "Host: www.example.org\r\n"
16172 "Connection: keep-alive\r\n\r\n"),
16173 };
16174 MockRead data_reads[] = {
16175 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16176 MockRead(SYNCHRONOUS, OK),
16177 };
16178 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16179 arraysize(data_writes));
16180 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16181
16182 // Start a request that will be throttled at start; confirm it
16183 // doesn't complete.
16184 throttler->set_throttle_new_requests(true);
16185 std::unique_ptr<HttpTransaction> trans(
16186 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16187
16188 TestCompletionCallback callback;
16189 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16190 EXPECT_EQ(ERR_IO_PENDING, rv);
16191
16192 base::RunLoop().RunUntilIdle();
16193 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16194 EXPECT_FALSE(callback.have_result());
16195
16196 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16197 trans.reset();
16198 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16199}
16200
16201// Confirm the throttler receives SetPriority calls.
16202TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16203 TestNetworkStreamThrottler* throttler(nullptr);
16204 std::unique_ptr<HttpNetworkSession> session(
16205 CreateSessionWithThrottler(&session_deps_, &throttler));
16206
16207 // Send a simple request and make sure it goes through.
16208 HttpRequestInfo request;
16209 request.method = "GET";
16210 request.url = GURL("http://www.example.org/");
16211
16212 MockWrite data_writes[] = {
16213 MockWrite("GET / HTTP/1.1\r\n"
16214 "Host: www.example.org\r\n"
16215 "Connection: keep-alive\r\n\r\n"),
16216 };
16217 MockRead data_reads[] = {
16218 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16219 MockRead(SYNCHRONOUS, OK),
16220 };
16221 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16222 arraysize(data_writes));
16223 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16224
16225 throttler->set_throttle_new_requests(true);
16226 std::unique_ptr<HttpTransaction> trans(
16227 new HttpNetworkTransaction(IDLE, session.get()));
16228 // Start the transaction to associate a throttle with it.
16229 TestCompletionCallback callback;
16230 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16231 EXPECT_EQ(ERR_IO_PENDING, rv);
16232
16233 EXPECT_EQ(0, throttler->num_set_priority_calls());
16234 trans->SetPriority(LOW);
16235 EXPECT_EQ(1, throttler->num_set_priority_calls());
16236 EXPECT_EQ(LOW, throttler->last_priority_set());
16237
16238 throttler->UnthrottleAllRequests();
16239 base::RunLoop().RunUntilIdle();
16240 ASSERT_TRUE(callback.have_result());
16241 EXPECT_EQ(OK, callback.WaitForResult());
16242}
16243
16244// Confirm that unthrottling from a SetPriority call by the
16245// throttler works properly.
16246TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16247 TestNetworkStreamThrottler* throttler(nullptr);
16248 std::unique_ptr<HttpNetworkSession> session(
16249 CreateSessionWithThrottler(&session_deps_, &throttler));
16250
16251 // Send a simple request and make sure it goes through.
16252 HttpRequestInfo request;
16253 request.method = "GET";
16254 request.url = GURL("http://www.example.org/");
16255
16256 MockWrite data_writes[] = {
16257 MockWrite("GET / HTTP/1.1\r\n"
16258 "Host: www.example.org\r\n"
16259 "Connection: keep-alive\r\n\r\n"),
16260 };
16261 MockRead data_reads[] = {
16262 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16263 MockRead(SYNCHRONOUS, OK),
16264 };
16265 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16266 arraysize(data_writes));
16267 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16268
16269 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16270 data_writes, arraysize(data_writes));
16271 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16272
16273 // Start a request that will be throttled at start; confirm it
16274 // doesn't complete.
16275 throttler->set_throttle_new_requests(true);
16276 std::unique_ptr<HttpTransaction> trans(
16277 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16278
16279 TestCompletionCallback callback;
16280 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16281 EXPECT_EQ(ERR_IO_PENDING, rv);
16282
16283 base::RunLoop().RunUntilIdle();
16284 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16285 EXPECT_FALSE(callback.have_result());
16286
16287 // Create a new request, call SetPriority on it to unthrottle,
16288 // and make sure that allows the original request to complete.
16289 std::unique_ptr<HttpTransaction> trans1(
16290 new HttpNetworkTransaction(LOW, session.get()));
16291 throttler->set_priority_change_closure(
16292 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
16293 base::Unretained(throttler)));
16294
16295 // Start the transaction to associate a throttle with it.
16296 TestCompletionCallback callback1;
16297 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
16298 EXPECT_EQ(ERR_IO_PENDING, rv);
16299
16300 trans1->SetPriority(IDLE);
16301
16302 base::RunLoop().RunUntilIdle();
16303 ASSERT_TRUE(callback.have_result());
16304 EXPECT_EQ(OK, callback.WaitForResult());
16305 ASSERT_TRUE(callback1.have_result());
16306 EXPECT_EQ(OK, callback1.WaitForResult());
16307}
16308
16309// Transaction will be destroyed when the unique_ptr goes out of scope.
16310void DestroyTransaction(std::unique_ptr<HttpTransaction> transaction) {}
16311
16312// Confirm that destroying a transaction from a SetPriority call by the
16313// throttler works properly.
16314TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
16315 TestNetworkStreamThrottler* throttler(nullptr);
16316 std::unique_ptr<HttpNetworkSession> session(
16317 CreateSessionWithThrottler(&session_deps_, &throttler));
16318
16319 // Send a simple request and make sure it goes through.
16320 HttpRequestInfo request;
16321 request.method = "GET";
16322 request.url = GURL("http://www.example.org/");
16323
16324 MockWrite data_writes[] = {
16325 MockWrite("GET / HTTP/1.1\r\n"
16326 "Host: www.example.org\r\n"
16327 "Connection: keep-alive\r\n\r\n"),
16328 };
16329 MockRead data_reads[] = {
16330 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16331 MockRead(SYNCHRONOUS, OK),
16332 };
16333 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16334 arraysize(data_writes));
16335 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16336
16337 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16338 data_writes, arraysize(data_writes));
16339 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16340
16341 // Start a request that will be throttled at start; confirm it
16342 // doesn't complete.
16343 throttler->set_throttle_new_requests(true);
16344 std::unique_ptr<HttpTransaction> trans(
16345 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16346
16347 TestCompletionCallback callback;
16348 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16349 EXPECT_EQ(ERR_IO_PENDING, rv);
16350
16351 base::RunLoop().RunUntilIdle();
16352 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16353 EXPECT_FALSE(callback.have_result());
16354
16355 // Arrange for the set priority call on the above transaction to delete
16356 // the transaction.
16357 HttpTransaction* trans_ptr(trans.get());
16358 throttler->set_priority_change_closure(
16359 base::Bind(&DestroyTransaction, base::Passed(&trans)));
16360
16361 // Call it and check results (partially a "doesn't crash" test).
16362 trans_ptr->SetPriority(IDLE);
16363 trans_ptr = nullptr; // No longer a valid pointer.
16364
16365 base::RunLoop().RunUntilIdle();
16366 ASSERT_FALSE(callback.have_result());
16367}
16368
nharperb7441ef2016-01-25 23:54:1416369#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0116370TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1416371 const std::string https_url = "https://www.example.com";
16372 HttpRequestInfo request;
16373 request.url = GURL(https_url);
16374 request.method = "GET";
16375
16376 SSLSocketDataProvider ssl(ASYNC, OK);
16377 ssl.token_binding_negotiated = true;
16378 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3616379 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1416380 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16381
bnc42331402016-07-25 13:36:1516382 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4116383 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
16384 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1416385 MockRead(ASYNC, ERR_IO_PENDING)};
16386 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16387 session_deps_.socket_factory->AddSocketDataProvider(&data);
16388 session_deps_.channel_id_service.reset(new ChannelIDService(
16389 new DefaultChannelIDStore(nullptr), base::ThreadTaskRunnerHandle::Get()));
danakj1fd259a02016-04-16 03:17:0916390 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416391
16392 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16393 TestCompletionCallback callback;
16394 EXPECT_EQ(ERR_IO_PENDING,
tfarina428341112016-09-22 13:38:2016395 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516396 base::RunLoop().RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416397
16398 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16399 HttpRequestHeaders headers;
16400 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16401 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16402}
16403#endif // !defined(OS_IOS)
16404
[email protected]89ceba9a2009-03-21 03:46:0616405} // namespace net