blob: ce38cf200026d2a23e9cc68e3bb2be7adb465e13 [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) {
rdsmithbf8c3c12016-11-18 18:16:24138 if (throttle->IsBlocked())
rdsmith1d343be52016-10-21 20:37:50139 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
rdsmithbf8c3c12016-11-18 18:16:24165 bool IsBlocked() const override { return throttled_; }
166 RequestPriority Priority() const override {
167 NOTREACHED();
168 return IDLE;
169 }
rdsmith1d343be52016-10-21 20:37:50170 void SetPriority(RequestPriority priority) override {
171 throttler_->SetPriorityCalled(priority);
172 }
173
174 TestThrottle(bool throttled,
175 ThrottleDelegate* delegate,
176 TestNetworkStreamThrottler* throttler)
177 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
178
179 void Unthrottle() {
180 EXPECT_TRUE(throttled_);
181
182 throttled_ = false;
rdsmithbf8c3c12016-11-18 18:16:24183 delegate_->OnThrottleUnblocked(this);
rdsmith1d343be52016-10-21 20:37:50184 }
185
186 bool throttled_;
187 ThrottleDelegate* delegate_;
188 TestNetworkStreamThrottler* throttler_;
189 };
190
191 void OnThrottleDestroyed(TestThrottle* throttle) {
192 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
193 outstanding_throttles_.erase(throttle);
194 }
195
196 void SetPriorityCalled(RequestPriority priority) {
197 ++num_set_priority_calls_;
198 last_priority_set_ = priority;
199 if (!priority_change_closure_.is_null())
200 priority_change_closure_.Run();
201 }
202
203 // Includes both throttled and unthrottled throttles.
204 std::set<TestThrottle*> outstanding_throttles_;
205 bool throttle_new_requests_;
206 int num_set_priority_calls_;
207 RequestPriority last_priority_set_;
208 base::Closure priority_change_closure_;
209
210 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
211};
212
[email protected]42cba2fb2013-03-29 19:58:57213const base::string16 kBar(ASCIIToUTF16("bar"));
214const base::string16 kBar2(ASCIIToUTF16("bar2"));
215const base::string16 kBar3(ASCIIToUTF16("bar3"));
216const base::string16 kBaz(ASCIIToUTF16("baz"));
217const base::string16 kFirst(ASCIIToUTF16("first"));
218const base::string16 kFoo(ASCIIToUTF16("foo"));
219const base::string16 kFoo2(ASCIIToUTF16("foo2"));
220const base::string16 kFoo3(ASCIIToUTF16("foo3"));
221const base::string16 kFou(ASCIIToUTF16("fou"));
222const base::string16 kSecond(ASCIIToUTF16("second"));
223const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
224const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44225
bnc2df4b522016-07-08 18:17:43226const char kAlternativeServiceHttpHeader[] =
227 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
228
ttuttle859dc7a2015-04-23 19:42:29229int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
230 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
231 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02232}
233
ttuttle859dc7a2015-04-23 19:42:29234int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
235 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
236 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02237}
238
ttuttle859dc7a2015-04-23 19:42:29239bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
240 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
241 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52242}
243
[email protected]f3da152d2012-06-02 01:00:57244// Takes in a Value created from a NetLogHttpResponseParameter, and returns
245// a JSONified list of headers as a single string. Uses single quotes instead
246// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27247bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57248 if (!params)
249 return false;
[email protected]ea5ef4c2013-06-13 22:50:27250 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57251 if (!params->GetList("headers", &header_list))
252 return false;
253 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34254 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28255 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57256 return true;
257}
258
[email protected]029c83b62013-01-24 05:28:20259// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
260// used.
ttuttle859dc7a2015-04-23 19:42:29261void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20262 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19263 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25264
[email protected]029c83b62013-01-24 05:28:20265 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
266 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
267
ttuttle859dc7a2015-04-23 19:42:29268 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20269 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25270
271 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25272
[email protected]3b23a222013-05-15 21:33:25273 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25274 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
275 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25276 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25277}
278
[email protected]029c83b62013-01-24 05:28:20279// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
280// used.
ttuttle859dc7a2015-04-23 19:42:29281void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25282 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20283 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19284 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20285
286 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
287 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
288
ttuttle859dc7a2015-04-23 19:42:29289 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
290 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20291 EXPECT_LE(load_timing_info.connect_timing.connect_end,
292 load_timing_info.send_start);
293
294 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20295
[email protected]3b23a222013-05-15 21:33:25296 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20297 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
298 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25299 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20300}
301
302// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
303// used.
ttuttle859dc7a2015-04-23 19:42:29304void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20305 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19306 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20307
ttuttle859dc7a2015-04-23 19:42:29308 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20309
310 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
311 EXPECT_LE(load_timing_info.proxy_resolve_start,
312 load_timing_info.proxy_resolve_end);
313 EXPECT_LE(load_timing_info.proxy_resolve_end,
314 load_timing_info.send_start);
315 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20316
[email protected]3b23a222013-05-15 21:33:25317 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20318 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
319 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25320 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20321}
322
323// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
324// used.
ttuttle859dc7a2015-04-23 19:42:29325void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20326 int connect_timing_flags) {
327 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19328 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20329
330 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
331 EXPECT_LE(load_timing_info.proxy_resolve_start,
332 load_timing_info.proxy_resolve_end);
333 EXPECT_LE(load_timing_info.proxy_resolve_end,
334 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29335 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
336 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20337 EXPECT_LE(load_timing_info.connect_timing.connect_end,
338 load_timing_info.send_start);
339
340 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20341
[email protected]3b23a222013-05-15 21:33:25342 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20343 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
344 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25345 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25346}
347
ttuttle859dc7a2015-04-23 19:42:29348void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24349 headers->SetHeader("Connection", "Upgrade");
350 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23351 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24352 headers->SetHeader("Sec-WebSocket-Version", "13");
353 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
354}
355
danakj1fd259a02016-04-16 03:17:09356std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42357 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34358 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14359}
360
rdsmith1d343be52016-10-21 20:37:50361// Note that the pointer written into |*throttler| will only be valid
362// for the lifetime of the returned HttpNetworkSession.
363std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
364 SpdySessionDependencies* session_deps,
365 TestNetworkStreamThrottler** throttler) {
366 std::unique_ptr<HttpNetworkSession> session(
367 SpdySessionDependencies::SpdyCreateSession(session_deps));
368
369 std::unique_ptr<TestNetworkStreamThrottler> owned_throttler(
370 new TestNetworkStreamThrottler);
371 *throttler = owned_throttler.get();
372
373 HttpNetworkSessionPeer peer(session.get());
374 peer.SetNetworkStreamThrottler(std::move(owned_throttler));
375
376 return session;
377}
378
[email protected]448d4ca52012-03-04 04:12:23379} // namespace
380
bncd16676a2016-07-20 16:23:01381class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03382 public:
bncd16676a2016-07-20 16:23:01383 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03384 // Important to restore the per-pool limit first, since the pool limit must
385 // always be greater than group limit, and the tests reduce both limits.
386 ClientSocketPoolManager::set_max_sockets_per_pool(
387 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
388 ClientSocketPoolManager::set_max_sockets_per_group(
389 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
390 }
391
[email protected]e3ceb682011-06-28 23:55:46392 protected:
[email protected]23e482282013-06-14 16:08:02393 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15394 : ssl_(ASYNC, OK),
395 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03396 HttpNetworkSession::NORMAL_SOCKET_POOL)),
397 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
398 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bncb26024382016-06-29 02:39:45399 session_deps_.enable_http2_alternative_service_with_different_host = true;
[email protected]483fa202013-05-14 01:07:03400 }
[email protected]bb88e1d32013-05-03 23:11:07401
[email protected]e3ceb682011-06-28 23:55:46402 struct SimpleGetHelperResult {
403 int rv;
404 std::string status_line;
405 std::string response_data;
sclittlefb249892015-09-10 21:33:22406 int64_t total_received_bytes;
407 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25408 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47409 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59410 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46411 };
412
dcheng67be2b1f2014-10-27 21:47:29413 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50414 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55415 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54416 }
417
dcheng67be2b1f2014-10-27 21:47:29418 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50419 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55420 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09421 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55422 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09423 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50424 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55425 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09426 }
427
[email protected]202965992011-12-07 23:04:51428 // Either |write_failure| specifies a write failure or |read_failure|
429 // specifies a read failure when using a reused socket. In either case, the
430 // failure should cause the network transaction to resend the request, and the
431 // other argument should be NULL.
432 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
433 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52434
[email protected]a34f61ee2014-03-18 20:59:49435 // Either |write_failure| specifies a write failure or |read_failure|
436 // specifies a read failure when using a reused socket. In either case, the
437 // failure should cause the network transaction to resend the request, and the
438 // other argument should be NULL.
439 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10440 const MockRead* read_failure,
441 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49442
[email protected]5a60c8b2011-10-19 20:14:29443 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
444 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15445 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52446
[email protected]ff007e162009-05-23 09:13:15447 HttpRequestInfo request;
448 request.method = "GET";
bncce36dca22015-04-21 22:11:23449 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:52450
vishal.b62985ca92015-04-17 08:45:51451 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07452 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09453 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16454 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27455
[email protected]5a60c8b2011-10-19 20:14:29456 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07457 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29458 }
initial.commit586acc5fe2008-07-26 22:42:52459
[email protected]49639fa2011-12-20 23:22:41460 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52461
eroman24bc6a12015-05-06 19:55:48462 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16463 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01464 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52465
[email protected]ff007e162009-05-23 09:13:15466 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16467 out.total_received_bytes = trans.GetTotalReceivedBytes();
468 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25469
470 // Even in the failure cases that use this function, connections are always
471 // successfully established before the error.
bnc691fda62016-08-12 00:43:16472 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25473 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
474
[email protected]ff007e162009-05-23 09:13:15475 if (out.rv != OK)
476 return out;
477
bnc691fda62016-08-12 00:43:16478 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50479 // Can't use ASSERT_* inside helper functions like this, so
480 // return an error.
wezca1070932016-05-26 20:30:52481 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50482 out.rv = ERR_UNEXPECTED;
483 return out;
484 }
[email protected]ff007e162009-05-23 09:13:15485 out.status_line = response->headers->GetStatusLine();
486
[email protected]80a09a82012-11-16 17:40:06487 EXPECT_EQ("127.0.0.1", response->socket_address.host());
488 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19489
ttuttled9dbc652015-09-29 20:00:59490 bool got_endpoint =
bnc691fda62016-08-12 00:43:16491 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59492 EXPECT_EQ(got_endpoint,
493 out.remote_endpoint_after_start.address().size() > 0);
494
bnc691fda62016-08-12 00:43:16495 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01496 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40497
mmenke43758e62015-05-04 21:09:46498 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40499 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39500 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00501 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
502 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39503 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00504 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
505 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15506
[email protected]f3da152d2012-06-02 01:00:57507 std::string line;
508 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
509 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
510
[email protected]79e1fd62013-06-20 06:50:04511 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16512 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04513 std::string value;
514 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23515 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04516 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
517 EXPECT_EQ("keep-alive", value);
518
519 std::string response_headers;
520 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23521 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04522 response_headers);
[email protected]3deb9a52010-11-11 00:24:40523
bnc691fda62016-08-12 00:43:16524 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22525 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16526 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22527
bnc691fda62016-08-12 00:43:16528 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47529 return out;
[email protected]ff007e162009-05-23 09:13:15530 }
initial.commit586acc5fe2008-07-26 22:42:52531
[email protected]5a60c8b2011-10-19 20:14:29532 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
533 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22534 MockWrite data_writes[] = {
535 MockWrite("GET / HTTP/1.1\r\n"
536 "Host: www.example.org\r\n"
537 "Connection: keep-alive\r\n\r\n"),
538 };
[email protected]5a60c8b2011-10-19 20:14:29539
sclittlefb249892015-09-10 21:33:22540 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
541 arraysize(data_writes));
542 StaticSocketDataProvider* data[] = {&reads};
543 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
544
545 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
546 out.total_sent_bytes);
547 return out;
[email protected]b8015c42013-12-24 15:18:19548 }
549
bnc032658ba2016-09-26 18:17:15550 void AddSSLSocketData() {
551 ssl_.next_proto = kProtoHTTP2;
552 ssl_.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
553 ASSERT_TRUE(ssl_.cert);
554 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
555 }
556
[email protected]ff007e162009-05-23 09:13:15557 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
558 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52559
[email protected]ff007e162009-05-23 09:13:15560 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07561
562 void BypassHostCacheOnRefreshHelper(int load_flags);
563
564 void CheckErrorIsPassedBack(int error, IoMode mode);
565
[email protected]4bd46222013-05-14 19:32:23566 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07567 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15568 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03569
570 // Original socket limits. Some tests set these. Safest to always restore
571 // them once each test has been run.
572 int old_max_group_sockets_;
573 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15574};
[email protected]231d5a32008-09-13 00:45:27575
[email protected]448d4ca52012-03-04 04:12:23576namespace {
577
ryansturm49a8cb12016-06-15 16:51:09578class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27579 public:
ryansturm49a8cb12016-06-15 16:51:09580 BeforeHeadersSentHandler()
581 : observed_before_headers_sent_with_proxy_(false),
582 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27583
ryansturm49a8cb12016-06-15 16:51:09584 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
585 HttpRequestHeaders* request_headers) {
586 observed_before_headers_sent_ = true;
587 if (!proxy_info.is_http() && !proxy_info.is_https() &&
588 !proxy_info.is_quic()) {
589 return;
590 }
591 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27592 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
593 }
594
ryansturm49a8cb12016-06-15 16:51:09595 bool observed_before_headers_sent_with_proxy() const {
596 return observed_before_headers_sent_with_proxy_;
597 }
598
599 bool observed_before_headers_sent() const {
600 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27601 }
602
603 std::string observed_proxy_server_uri() const {
604 return observed_proxy_server_uri_;
605 }
606
607 private:
ryansturm49a8cb12016-06-15 16:51:09608 bool observed_before_headers_sent_with_proxy_;
609 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27610 std::string observed_proxy_server_uri_;
611
ryansturm49a8cb12016-06-15 16:51:09612 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27613};
614
[email protected]15a5ccf82008-10-23 19:57:43615// Fill |str| with a long header list that consumes >= |size| bytes.
616void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51617 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19618 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
619 const int sizeof_row = strlen(row);
620 const int num_rows = static_cast<int>(
621 ceil(static_cast<float>(size) / sizeof_row));
622 const int sizeof_data = num_rows * sizeof_row;
623 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43624 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51625
[email protected]4ddaf2502008-10-23 18:26:19626 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43627 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19628}
629
thakis84dff942015-07-28 20:47:38630#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29631// Alternative functions that eliminate randomness and dependency on the local
632// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14633void MockGenerateRandom1(uint8_t* output, size_t n) {
634 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
635 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29636 static size_t current_byte = 0;
637 for (size_t i = 0; i < n; ++i) {
638 output[i] = bytes[current_byte++];
639 current_byte %= arraysize(bytes);
640 }
641}
642
avibf0746c2015-12-09 19:53:14643void MockGenerateRandom2(uint8_t* output, size_t n) {
644 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
645 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
646 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29647 static size_t current_byte = 0;
648 for (size_t i = 0; i < n; ++i) {
649 output[i] = bytes[current_byte++];
650 current_byte %= arraysize(bytes);
651 }
652}
653
[email protected]fe2bc6a2009-03-23 16:52:20654std::string MockGetHostName() {
655 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29656}
thakis84dff942015-07-28 20:47:38657#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29658
[email protected]e60e47a2010-07-14 03:37:18659template<typename ParentPool>
660class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31661 public:
[email protected]9e1bdd32011-02-03 21:48:34662 CaptureGroupNameSocketPool(HostResolver* host_resolver,
663 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18664
[email protected]d80a4322009-08-14 07:07:49665 const std::string last_group_name_received() const {
666 return last_group_name_;
667 }
668
dmichaeld6e570d2014-12-18 22:30:57669 int RequestSocket(const std::string& group_name,
670 const void* socket_params,
671 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15672 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57673 ClientSocketHandle* handle,
674 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20675 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31676 last_group_name_ = group_name;
677 return ERR_IO_PENDING;
678 }
dmichaeld6e570d2014-12-18 22:30:57679 void CancelRequest(const std::string& group_name,
680 ClientSocketHandle* handle) override {}
681 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09682 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57683 int id) override {}
684 void CloseIdleSockets() override {}
685 int IdleSocketCount() const override { return 0; }
686 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31687 return 0;
688 }
dmichaeld6e570d2014-12-18 22:30:57689 LoadState GetLoadState(const std::string& group_name,
690 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31691 return LOAD_STATE_IDLE;
692 }
dmichaeld6e570d2014-12-18 22:30:57693 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26694 return base::TimeDelta();
695 }
[email protected]d80a4322009-08-14 07:07:49696
697 private:
[email protected]04e5be32009-06-26 20:00:31698 std::string last_group_name_;
699};
700
[email protected]ab739042011-04-07 15:22:28701typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
702CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13703typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
704CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06705typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11706CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18707typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
708CaptureGroupNameSSLSocketPool;
709
rkaplowd90695c2015-03-25 22:12:41710template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18711CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34712 HostResolver* host_resolver,
713 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21714 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18715
hashimoto0d3e4fb2015-01-09 05:02:50716template <>
[email protected]2df19bb2010-08-25 20:13:46717CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21718 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34719 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41720 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50721}
[email protected]2df19bb2010-08-25 20:13:46722
[email protected]007b3f82013-04-09 08:46:45723template <>
[email protected]e60e47a2010-07-14 03:37:18724CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21725 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34726 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45727 : SSLClientSocketPool(0,
728 0,
[email protected]007b3f82013-04-09 08:46:45729 cert_verifier,
730 NULL,
731 NULL,
[email protected]284303b62013-11-28 15:11:54732 NULL,
eranm6571b2b2014-12-03 15:53:23733 NULL,
[email protected]007b3f82013-04-09 08:46:45734 std::string(),
735 NULL,
736 NULL,
737 NULL,
738 NULL,
739 NULL,
[email protected]8e458552014-08-05 00:02:15740 NULL) {
741}
[email protected]2227c692010-05-04 15:36:11742
[email protected]231d5a32008-09-13 00:45:27743//-----------------------------------------------------------------------------
744
[email protected]79cb5c12011-09-12 13:12:04745// Helper functions for validating that AuthChallengeInfo's are correctly
746// configured for common cases.
747bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
748 if (!auth_challenge)
749 return false;
750 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43751 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04752 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19753 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04754 return true;
755}
756
757bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
758 if (!auth_challenge)
759 return false;
760 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43761 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
762 EXPECT_EQ("MyRealm1", auth_challenge->realm);
763 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
764 return true;
765}
766
767bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
768 if (!auth_challenge)
769 return false;
770 EXPECT_TRUE(auth_challenge->is_proxy);
771 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04772 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19773 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04774 return true;
775}
776
777bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
778 if (!auth_challenge)
779 return false;
780 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43781 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04782 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19783 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04784 return true;
785}
786
thakis84dff942015-07-28 20:47:38787#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04788bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
789 if (!auth_challenge)
790 return false;
791 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43792 EXPECT_EQ("http://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04793 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19794 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04795 return true;
796}
thakis84dff942015-07-28 20:47:38797#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04798
[email protected]448d4ca52012-03-04 04:12:23799} // namespace
800
bncd16676a2016-07-20 16:23:01801TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09802 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16803 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27804}
805
bncd16676a2016-07-20 16:23:01806TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27807 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35808 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
809 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06810 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27811 };
[email protected]31a2bfe2010-02-09 08:03:39812 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
813 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01814 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27815 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
816 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22817 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
818 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47819 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59820
821 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27822}
823
824// Response with no status line.
bncd16676a2016-07-20 16:23:01825TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27826 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35827 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06828 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27829 };
[email protected]31a2bfe2010-02-09 08:03:39830 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
831 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41832 EXPECT_THAT(out.rv, IsOk());
833 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
834 EXPECT_EQ("hello world", out.response_data);
835 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
836 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27837}
838
mmenkea7da6da2016-09-01 21:56:52839// Response with no status line, and a weird port. Should fail by default.
840TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
841 MockRead data_reads[] = {
842 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
843 };
844
845 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
846 session_deps_.socket_factory->AddSocketDataProvider(&data);
847
848 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
849
krasinc06a72a2016-12-21 03:42:46850 HttpRequestInfo request;
mmenkea7da6da2016-09-01 21:56:52851 std::unique_ptr<HttpTransaction> trans(
852 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
853
mmenkea7da6da2016-09-01 21:56:52854 request.method = "GET";
855 request.url = GURL("http://www.example.com:2000/");
856 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20857 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52858 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
859}
860
861// Response with no status line, and a weird port. Option to allow weird ports
862// enabled.
863TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
864 MockRead data_reads[] = {
865 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
866 };
867
868 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
869 session_deps_.socket_factory->AddSocketDataProvider(&data);
870 session_deps_.http_09_on_non_default_ports_enabled = true;
871 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
872
krasinc06a72a2016-12-21 03:42:46873 HttpRequestInfo request;
mmenkea7da6da2016-09-01 21:56:52874 std::unique_ptr<HttpTransaction> trans(
875 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
876
mmenkea7da6da2016-09-01 21:56:52877 request.method = "GET";
878 request.url = GURL("http://www.example.com:2000/");
879 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20880 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52881 EXPECT_THAT(callback.GetResult(rv), IsOk());
882
883 const HttpResponseInfo* info = trans->GetResponseInfo();
884 ASSERT_TRUE(info->headers);
885 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
886
887 // Don't bother to read the body - that's verified elsewhere, important thing
888 // is that the option to allow HTTP/0.9 on non-default ports is respected.
889}
890
[email protected]231d5a32008-09-13 00:45:27891// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01892TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27893 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35894 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06895 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27896 };
[email protected]31a2bfe2010-02-09 08:03:39897 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
898 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01899 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27900 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
901 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22902 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
903 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27904}
905
906// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01907TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27908 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35909 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06910 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27911 };
[email protected]31a2bfe2010-02-09 08:03:39912 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
913 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01914 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27915 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
916 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22917 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
918 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27919}
920
921// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01922TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27923 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35924 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06925 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27926 };
[email protected]31a2bfe2010-02-09 08:03:39927 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
928 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41929 EXPECT_THAT(out.rv, IsOk());
930 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
931 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
932 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
933 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27934}
935
936// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01937TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27938 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35939 MockRead("\n"),
940 MockRead("\n"),
941 MockRead("Q"),
942 MockRead("J"),
943 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06944 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27945 };
[email protected]31a2bfe2010-02-09 08:03:39946 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
947 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01948 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27949 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
950 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22951 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
952 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27953}
954
955// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01956TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27957 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35958 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06959 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27960 };
[email protected]31a2bfe2010-02-09 08:03:39961 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
962 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41963 EXPECT_THAT(out.rv, IsOk());
964 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
965 EXPECT_EQ("HTT", out.response_data);
966 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
967 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52968}
969
[email protected]f9d44aa2008-09-23 23:57:17970// Simulate a 204 response, lacking a Content-Length header, sent over a
971// persistent connection. The response should still terminate since a 204
972// cannot have a response body.
bncd16676a2016-07-20 16:23:01973TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19974 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17975 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35976 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19977 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06978 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17979 };
[email protected]31a2bfe2010-02-09 08:03:39980 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
981 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01982 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17983 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
984 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22985 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
986 int64_t response_size = reads_size - strlen(junk);
987 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17988}
989
[email protected]0877e3d2009-10-17 22:29:57990// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01991TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19992 std::string final_chunk = "0\r\n\r\n";
993 std::string extra_data = "HTTP/1.1 200 OK\r\n";
994 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57995 MockRead data_reads[] = {
996 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
997 MockRead("5\r\nHello\r\n"),
998 MockRead("1\r\n"),
999 MockRead(" \r\n"),
1000 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191001 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061002 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571003 };
[email protected]31a2bfe2010-02-09 08:03:391004 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1005 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011006 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571007 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1008 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221009 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1010 int64_t response_size = reads_size - extra_data.size();
1011 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571012}
1013
[email protected]9fe44f52010-09-23 18:36:001014// Next tests deal with http://crbug.com/56344.
1015
bncd16676a2016-07-20 16:23:011016TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001017 MultipleContentLengthHeadersNoTransferEncoding) {
1018 MockRead data_reads[] = {
1019 MockRead("HTTP/1.1 200 OK\r\n"),
1020 MockRead("Content-Length: 10\r\n"),
1021 MockRead("Content-Length: 5\r\n\r\n"),
1022 };
1023 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1024 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011025 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001026}
1027
bncd16676a2016-07-20 16:23:011028TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041029 DuplicateContentLengthHeadersNoTransferEncoding) {
1030 MockRead data_reads[] = {
1031 MockRead("HTTP/1.1 200 OK\r\n"),
1032 MockRead("Content-Length: 5\r\n"),
1033 MockRead("Content-Length: 5\r\n\r\n"),
1034 MockRead("Hello"),
1035 };
1036 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1037 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011038 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041039 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1040 EXPECT_EQ("Hello", out.response_data);
1041}
1042
bncd16676a2016-07-20 16:23:011043TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041044 ComplexContentLengthHeadersNoTransferEncoding) {
1045 // More than 2 dupes.
1046 {
1047 MockRead data_reads[] = {
1048 MockRead("HTTP/1.1 200 OK\r\n"),
1049 MockRead("Content-Length: 5\r\n"),
1050 MockRead("Content-Length: 5\r\n"),
1051 MockRead("Content-Length: 5\r\n\r\n"),
1052 MockRead("Hello"),
1053 };
1054 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1055 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011056 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041057 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1058 EXPECT_EQ("Hello", out.response_data);
1059 }
1060 // HTTP/1.0
1061 {
1062 MockRead data_reads[] = {
1063 MockRead("HTTP/1.0 200 OK\r\n"),
1064 MockRead("Content-Length: 5\r\n"),
1065 MockRead("Content-Length: 5\r\n"),
1066 MockRead("Content-Length: 5\r\n\r\n"),
1067 MockRead("Hello"),
1068 };
1069 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1070 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011071 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041072 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1073 EXPECT_EQ("Hello", out.response_data);
1074 }
1075 // 2 dupes and one mismatched.
1076 {
1077 MockRead data_reads[] = {
1078 MockRead("HTTP/1.1 200 OK\r\n"),
1079 MockRead("Content-Length: 10\r\n"),
1080 MockRead("Content-Length: 10\r\n"),
1081 MockRead("Content-Length: 5\r\n\r\n"),
1082 };
1083 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1084 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011085 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041086 }
1087}
1088
bncd16676a2016-07-20 16:23:011089TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001090 MultipleContentLengthHeadersTransferEncoding) {
1091 MockRead data_reads[] = {
1092 MockRead("HTTP/1.1 200 OK\r\n"),
1093 MockRead("Content-Length: 666\r\n"),
1094 MockRead("Content-Length: 1337\r\n"),
1095 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1096 MockRead("5\r\nHello\r\n"),
1097 MockRead("1\r\n"),
1098 MockRead(" \r\n"),
1099 MockRead("5\r\nworld\r\n"),
1100 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061101 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001102 };
1103 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1104 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011105 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001106 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1107 EXPECT_EQ("Hello world", out.response_data);
1108}
1109
[email protected]1628fe92011-10-04 23:04:551110// Next tests deal with http://crbug.com/98895.
1111
1112// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011113TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551114 MockRead data_reads[] = {
1115 MockRead("HTTP/1.1 200 OK\r\n"),
1116 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1117 MockRead("Content-Length: 5\r\n\r\n"),
1118 MockRead("Hello"),
1119 };
1120 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1121 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011122 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551123 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1124 EXPECT_EQ("Hello", out.response_data);
1125}
1126
[email protected]54a9c6e52012-03-21 20:10:591127// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011128TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551129 MockRead data_reads[] = {
1130 MockRead("HTTP/1.1 200 OK\r\n"),
1131 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1132 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1133 MockRead("Content-Length: 5\r\n\r\n"),
1134 MockRead("Hello"),
1135 };
1136 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1137 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011138 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591139 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1140 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551141}
1142
1143// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011144TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551145 MockRead data_reads[] = {
1146 MockRead("HTTP/1.1 200 OK\r\n"),
1147 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1148 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1149 MockRead("Content-Length: 5\r\n\r\n"),
1150 MockRead("Hello"),
1151 };
1152 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1153 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011154 EXPECT_THAT(out.rv,
1155 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551156}
1157
[email protected]54a9c6e52012-03-21 20:10:591158// Checks that two identical Location headers result in no error.
1159// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011160TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551161 MockRead data_reads[] = {
1162 MockRead("HTTP/1.1 302 Redirect\r\n"),
1163 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591164 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551165 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061166 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551167 };
1168
1169 HttpRequestInfo request;
1170 request.method = "GET";
1171 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551172
danakj1fd259a02016-04-16 03:17:091173 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161174 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551175
1176 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071177 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551178
[email protected]49639fa2011-12-20 23:22:411179 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551180
tfarina42834112016-09-22 13:38:201181 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011182 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551183
robpercival214763f2016-07-01 23:27:011184 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551185
bnc691fda62016-08-12 00:43:161186 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521187 ASSERT_TRUE(response);
1188 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551189 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1190 std::string url;
1191 EXPECT_TRUE(response->headers->IsRedirect(&url));
1192 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471193 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551194}
1195
[email protected]1628fe92011-10-04 23:04:551196// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011197TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551198 MockRead data_reads[] = {
1199 MockRead("HTTP/1.1 302 Redirect\r\n"),
1200 MockRead("Location: http://good.com/\r\n"),
1201 MockRead("Location: http://evil.com/\r\n"),
1202 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061203 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551204 };
1205 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1206 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011207 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551208}
1209
[email protected]ef0faf2e72009-03-05 23:27:231210// Do a request using the HEAD method. Verify that we don't try to read the
1211// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011212TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421213 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231214 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231215 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231216
danakj1fd259a02016-04-16 03:17:091217 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161218 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091219 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161220 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091221 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1222 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271223
[email protected]ef0faf2e72009-03-05 23:27:231224 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131225 MockWrite("HEAD / HTTP/1.1\r\n"
1226 "Host: www.example.org\r\n"
1227 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231228 };
1229 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231230 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1231 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231232
mmenked39192ee2015-12-09 00:57:231233 // No response body because the test stops reading here.
1234 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231235 };
1236
[email protected]31a2bfe2010-02-09 08:03:391237 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1238 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071239 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231240
[email protected]49639fa2011-12-20 23:22:411241 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231242
tfarina42834112016-09-22 13:38:201243 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011244 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231245
1246 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011247 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231248
bnc691fda62016-08-12 00:43:161249 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521250 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231251
1252 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521253 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231254 EXPECT_EQ(1234, response->headers->GetContentLength());
1255 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471256 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091257 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1258 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231259
1260 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101261 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231262 bool has_server_header = response->headers->EnumerateHeader(
1263 &iter, "Server", &server_header);
1264 EXPECT_TRUE(has_server_header);
1265 EXPECT_EQ("Blah", server_header);
1266
1267 // Reading should give EOF right away, since there is no message body
1268 // (despite non-zero content-length).
1269 std::string response_data;
bnc691fda62016-08-12 00:43:161270 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011271 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231272 EXPECT_EQ("", response_data);
1273}
1274
bncd16676a2016-07-20 16:23:011275TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091276 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521277
1278 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351279 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1280 MockRead("hello"),
1281 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1282 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061283 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521284 };
[email protected]31a2bfe2010-02-09 08:03:391285 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071286 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521287
[email protected]0b0bf032010-09-21 18:08:501288 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521289 "hello", "world"
1290 };
1291
1292 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421293 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521294 request.method = "GET";
bncce36dca22015-04-21 22:11:231295 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521296
bnc691fda62016-08-12 00:43:161297 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271298
[email protected]49639fa2011-12-20 23:22:411299 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521300
tfarina42834112016-09-22 13:38:201301 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011302 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521303
1304 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011305 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521306
bnc691fda62016-08-12 00:43:161307 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521308 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521309
wezca1070932016-05-26 20:30:521310 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251311 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471312 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521313
1314 std::string response_data;
bnc691fda62016-08-12 00:43:161315 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011316 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251317 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521318 }
1319}
1320
bncd16676a2016-07-20 16:23:011321TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091322 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221323 element_readers.push_back(
ricea2deef682016-09-09 08:04:071324 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221325 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271326
[email protected]1c773ea12009-04-28 19:58:421327 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521328 request.method = "POST";
1329 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271330 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521331
shivanishab9a143952016-09-19 17:23:411332 // Check the upload progress returned before initialization is correct.
1333 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1334 EXPECT_EQ(0u, progress.size());
1335 EXPECT_EQ(0u, progress.position());
1336
danakj1fd259a02016-04-16 03:17:091337 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161338 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271339
initial.commit586acc5fe2008-07-26 22:42:521340 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351341 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1342 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1343 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061344 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521345 };
[email protected]31a2bfe2010-02-09 08:03:391346 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071347 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521348
[email protected]49639fa2011-12-20 23:22:411349 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521350
tfarina42834112016-09-22 13:38:201351 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011352 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521353
1354 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011355 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521356
bnc691fda62016-08-12 00:43:161357 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521358 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521359
wezca1070932016-05-26 20:30:521360 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251361 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521362
1363 std::string response_data;
bnc691fda62016-08-12 00:43:161364 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011365 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251366 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521367}
1368
[email protected]3a2d3662009-03-27 03:49:141369// This test is almost the same as Ignores100 above, but the response contains
1370// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571371// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011372TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421373 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141374 request.method = "GET";
1375 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141376
danakj1fd259a02016-04-16 03:17:091377 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161378 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271379
[email protected]3a2d3662009-03-27 03:49:141380 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571381 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1382 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141383 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061384 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141385 };
[email protected]31a2bfe2010-02-09 08:03:391386 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071387 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141388
[email protected]49639fa2011-12-20 23:22:411389 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141390
tfarina42834112016-09-22 13:38:201391 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011392 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141393
1394 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011395 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141396
bnc691fda62016-08-12 00:43:161397 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521398 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141399
wezca1070932016-05-26 20:30:521400 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141401 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1402
1403 std::string response_data;
bnc691fda62016-08-12 00:43:161404 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011405 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141406 EXPECT_EQ("hello world", response_data);
1407}
1408
bncd16676a2016-07-20 16:23:011409TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081410 HttpRequestInfo request;
1411 request.method = "POST";
1412 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081413
danakj1fd259a02016-04-16 03:17:091414 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161415 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081416
1417 MockRead data_reads[] = {
1418 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1419 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381420 };
zmo9528c9f42015-08-04 22:12:081421 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1422 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381423
zmo9528c9f42015-08-04 22:12:081424 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381425
tfarina42834112016-09-22 13:38:201426 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011427 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381428
zmo9528c9f42015-08-04 22:12:081429 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011430 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381431
zmo9528c9f42015-08-04 22:12:081432 std::string response_data;
bnc691fda62016-08-12 00:43:161433 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011434 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081435 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381436}
1437
bncd16676a2016-07-20 16:23:011438TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381439 HttpRequestInfo request;
1440 request.method = "POST";
1441 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381442
danakj1fd259a02016-04-16 03:17:091443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161444 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271445
[email protected]ee9410e72010-01-07 01:42:381446 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061447 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381448 };
[email protected]31a2bfe2010-02-09 08:03:391449 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071450 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381451
[email protected]49639fa2011-12-20 23:22:411452 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381453
tfarina42834112016-09-22 13:38:201454 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381456
1457 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011458 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381459}
1460
[email protected]23e482282013-06-14 16:08:021461void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511462 const MockWrite* write_failure,
1463 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421464 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521465 request.method = "GET";
1466 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521467
vishal.b62985ca92015-04-17 08:45:511468 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071469 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091470 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271471
[email protected]202965992011-12-07 23:04:511472 // Written data for successfully sending both requests.
1473 MockWrite data1_writes[] = {
1474 MockWrite("GET / HTTP/1.1\r\n"
1475 "Host: www.foo.com\r\n"
1476 "Connection: keep-alive\r\n\r\n"),
1477 MockWrite("GET / HTTP/1.1\r\n"
1478 "Host: www.foo.com\r\n"
1479 "Connection: keep-alive\r\n\r\n")
1480 };
1481
1482 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521483 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351484 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1485 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061486 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521487 };
[email protected]202965992011-12-07 23:04:511488
1489 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491490 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511491 data1_writes[1] = *write_failure;
1492 } else {
1493 ASSERT_TRUE(read_failure);
1494 data1_reads[2] = *read_failure;
1495 }
1496
1497 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1498 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071499 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521500
1501 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351502 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1503 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061504 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521505 };
[email protected]31a2bfe2010-02-09 08:03:391506 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071507 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521508
thestig9d3bb0c2015-01-24 00:49:511509 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521510 "hello", "world"
1511 };
1512
mikecironef22f9812016-10-04 03:40:191513 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521514 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411515 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521516
bnc691fda62016-08-12 00:43:161517 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521518
tfarina42834112016-09-22 13:38:201519 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011520 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521521
1522 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011523 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521524
[email protected]58e32bb2013-01-21 18:23:251525 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161526 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251527 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1528 if (i == 0) {
1529 first_socket_log_id = load_timing_info.socket_log_id;
1530 } else {
1531 // The second request should be using a new socket.
1532 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1533 }
1534
bnc691fda62016-08-12 00:43:161535 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521536 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521537
wezca1070932016-05-26 20:30:521538 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471539 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251540 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521541
1542 std::string response_data;
bnc691fda62016-08-12 00:43:161543 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011544 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251545 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521546 }
1547}
[email protected]3d2a59b2008-09-26 19:44:251548
[email protected]a34f61ee2014-03-18 20:59:491549void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1550 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101551 const MockRead* read_failure,
1552 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491553 HttpRequestInfo request;
1554 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101555 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491556
vishal.b62985ca92015-04-17 08:45:511557 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491558 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091559 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491560
[email protected]09356c652014-03-25 15:36:101561 SSLSocketDataProvider ssl1(ASYNC, OK);
1562 SSLSocketDataProvider ssl2(ASYNC, OK);
1563 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361564 ssl1.next_proto = kProtoHTTP2;
1565 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101566 }
1567 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1568 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491569
[email protected]09356c652014-03-25 15:36:101570 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411571 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491572 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411573 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151574 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411575 SpdySerializedFrame spdy_data(
1576 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491577
[email protected]09356c652014-03-25 15:36:101578 // HTTP/1.1 versions of the request and response.
1579 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1580 "Host: www.foo.com\r\n"
1581 "Connection: keep-alive\r\n\r\n";
1582 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1583 const char kHttpData[] = "hello";
1584
1585 std::vector<MockRead> data1_reads;
1586 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491587 if (write_failure) {
1588 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101589 data1_writes.push_back(*write_failure);
1590 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491591 } else {
1592 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101593 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411594 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101595 } else {
1596 data1_writes.push_back(MockWrite(kHttpRequest));
1597 }
1598 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491599 }
1600
[email protected]09356c652014-03-25 15:36:101601 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1602 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491603 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1604
[email protected]09356c652014-03-25 15:36:101605 std::vector<MockRead> data2_reads;
1606 std::vector<MockWrite> data2_writes;
1607
1608 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411609 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101610
bncdf80d44fd2016-07-15 20:27:411611 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1612 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101613 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1614 } else {
1615 data2_writes.push_back(
1616 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1617
1618 data2_reads.push_back(
1619 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1620 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1621 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1622 }
rch8e6c6c42015-05-01 14:05:131623 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1624 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491625 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1626
1627 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591628 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491629 // Wait for the preconnect to complete.
1630 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1631 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101632 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491633
1634 // Make the request.
1635 TestCompletionCallback callback;
1636
bnc691fda62016-08-12 00:43:161637 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491638
tfarina42834112016-09-22 13:38:201639 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011640 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491641
1642 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011643 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491644
1645 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161646 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101647 TestLoadTimingNotReused(
1648 load_timing_info,
1649 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491650
bnc691fda62016-08-12 00:43:161651 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521652 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491653
wezca1070932016-05-26 20:30:521654 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021655 if (response->was_fetched_via_spdy) {
1656 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1657 } else {
1658 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1659 }
[email protected]a34f61ee2014-03-18 20:59:491660
1661 std::string response_data;
bnc691fda62016-08-12 00:43:161662 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011663 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101664 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491665}
1666
bncd16676a2016-07-20 16:23:011667TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061668 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511669 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1670}
1671
bncd16676a2016-07-20 16:23:011672TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061673 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511674 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251675}
1676
bncd16676a2016-07-20 16:23:011677TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061678 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511679 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251680}
1681
[email protected]d58ceea82014-06-04 10:55:541682// Make sure that on a 408 response (Request Timeout), the request is retried,
1683// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011684TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541685 MockRead read_failure(SYNCHRONOUS,
1686 "HTTP/1.1 408 Request Timeout\r\n"
1687 "Connection: Keep-Alive\r\n"
1688 "Content-Length: 6\r\n\r\n"
1689 "Pickle");
1690 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1691}
1692
bncd16676a2016-07-20 16:23:011693TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491694 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101695 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491696}
1697
bncd16676a2016-07-20 16:23:011698TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491699 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101700 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491701}
1702
bncd16676a2016-07-20 16:23:011703TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491704 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101705 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1706}
1707
bncd16676a2016-07-20 16:23:011708TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101709 MockRead read_failure(ASYNC, OK); // EOF
1710 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1711}
1712
[email protected]d58ceea82014-06-04 10:55:541713// Make sure that on a 408 response (Request Timeout), the request is retried,
1714// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011715TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541716 MockRead read_failure(SYNCHRONOUS,
1717 "HTTP/1.1 408 Request Timeout\r\n"
1718 "Connection: Keep-Alive\r\n"
1719 "Content-Length: 6\r\n\r\n"
1720 "Pickle");
1721 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1722 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1723}
1724
bncd16676a2016-07-20 16:23:011725TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101726 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1727 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1728}
1729
bncd16676a2016-07-20 16:23:011730TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101731 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1732 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1733}
1734
bncd16676a2016-07-20 16:23:011735TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101736 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1737 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1738}
1739
bncd16676a2016-07-20 16:23:011740TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101741 MockRead read_failure(ASYNC, OK); // EOF
1742 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491743}
1744
bncd16676a2016-07-20 16:23:011745TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421746 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251747 request.method = "GET";
bncce36dca22015-04-21 22:11:231748 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251749
danakj1fd259a02016-04-16 03:17:091750 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161751 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271752
[email protected]3d2a59b2008-09-26 19:44:251753 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061754 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351755 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1756 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061757 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251758 };
[email protected]31a2bfe2010-02-09 08:03:391759 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071760 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251761
[email protected]49639fa2011-12-20 23:22:411762 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251763
tfarina42834112016-09-22 13:38:201764 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011765 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251766
1767 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011768 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591769
1770 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161771 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591772 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251773}
1774
1775// What do various browsers do when the server closes a non-keepalive
1776// connection without sending any response header or body?
1777//
1778// IE7: error page
1779// Safari 3.1.2 (Windows): error page
1780// Firefox 3.0.1: blank page
1781// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421782// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1783// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011784TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251785 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061786 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351787 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1788 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061789 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251790 };
[email protected]31a2bfe2010-02-09 08:03:391791 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1792 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011793 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251794}
[email protected]1826a402014-01-08 15:40:481795
[email protected]7a5378b2012-11-04 03:25:171796// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1797// tests. There was a bug causing HttpNetworkTransaction to hang in the
1798// destructor in such situations.
1799// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011800TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171801 HttpRequestInfo request;
1802 request.method = "GET";
bncce36dca22015-04-21 22:11:231803 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171804
danakj1fd259a02016-04-16 03:17:091805 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161806 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501807 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171808
1809 MockRead data_reads[] = {
1810 MockRead("HTTP/1.0 200 OK\r\n"),
1811 MockRead("Connection: keep-alive\r\n"),
1812 MockRead("Content-Length: 100\r\n\r\n"),
1813 MockRead("hello"),
1814 MockRead(SYNCHRONOUS, 0),
1815 };
1816 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071817 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171818
1819 TestCompletionCallback callback;
1820
tfarina42834112016-09-22 13:38:201821 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171823
1824 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011825 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171826
1827 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501828 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171829 if (rv == ERR_IO_PENDING)
1830 rv = callback.WaitForResult();
1831 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501832 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011833 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171834
1835 trans.reset();
fdoray92e35a72016-06-10 15:54:551836 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171837 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1838}
1839
bncd16676a2016-07-20 16:23:011840TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171841 HttpRequestInfo request;
1842 request.method = "GET";
bncce36dca22015-04-21 22:11:231843 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171844
danakj1fd259a02016-04-16 03:17:091845 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161846 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501847 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171848
1849 MockRead data_reads[] = {
1850 MockRead("HTTP/1.0 200 OK\r\n"),
1851 MockRead("Connection: keep-alive\r\n"),
1852 MockRead("Content-Length: 100\r\n\r\n"),
1853 MockRead(SYNCHRONOUS, 0),
1854 };
1855 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071856 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171857
1858 TestCompletionCallback callback;
1859
tfarina42834112016-09-22 13:38:201860 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011861 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171862
1863 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011864 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171865
1866 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501867 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171868 if (rv == ERR_IO_PENDING)
1869 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011870 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171871
1872 trans.reset();
fdoray92e35a72016-06-10 15:54:551873 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171874 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1875}
1876
[email protected]0b0bf032010-09-21 18:08:501877// Test that we correctly reuse a keep-alive connection after not explicitly
1878// reading the body.
bncd16676a2016-07-20 16:23:011879TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131880 HttpRequestInfo request;
1881 request.method = "GET";
1882 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:131883
vishal.b62985ca92015-04-17 08:45:511884 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071885 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091886 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271887
mmenkecc2298e2015-12-07 18:20:181888 const char* request_data =
1889 "GET / HTTP/1.1\r\n"
1890 "Host: www.foo.com\r\n"
1891 "Connection: keep-alive\r\n\r\n";
1892 MockWrite data_writes[] = {
1893 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1894 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1895 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1896 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1897 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1898 };
1899
[email protected]0b0bf032010-09-21 18:08:501900 // Note that because all these reads happen in the same
1901 // StaticSocketDataProvider, it shows that the same socket is being reused for
1902 // all transactions.
mmenkecc2298e2015-12-07 18:20:181903 MockRead data_reads[] = {
1904 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1905 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1906 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1907 MockRead(ASYNC, 7,
1908 "HTTP/1.1 302 Found\r\n"
1909 "Content-Length: 0\r\n\r\n"),
1910 MockRead(ASYNC, 9,
1911 "HTTP/1.1 302 Found\r\n"
1912 "Content-Length: 5\r\n\r\n"
1913 "hello"),
1914 MockRead(ASYNC, 11,
1915 "HTTP/1.1 301 Moved Permanently\r\n"
1916 "Content-Length: 0\r\n\r\n"),
1917 MockRead(ASYNC, 13,
1918 "HTTP/1.1 301 Moved Permanently\r\n"
1919 "Content-Length: 5\r\n\r\n"
1920 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131921
mmenkecc2298e2015-12-07 18:20:181922 // In the next two rounds, IsConnectedAndIdle returns false, due to
1923 // the set_busy_before_sync_reads(true) call, while the
1924 // HttpNetworkTransaction is being shut down, but the socket is still
1925 // reuseable. See http://crbug.com/544255.
1926 MockRead(ASYNC, 15,
1927 "HTTP/1.1 200 Hunky-Dory\r\n"
1928 "Content-Length: 5\r\n\r\n"),
1929 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131930
mmenkecc2298e2015-12-07 18:20:181931 MockRead(ASYNC, 18,
1932 "HTTP/1.1 200 Hunky-Dory\r\n"
1933 "Content-Length: 5\r\n\r\n"
1934 "he"),
1935 MockRead(SYNCHRONOUS, 19, "llo"),
1936
1937 // The body of the final request is actually read.
1938 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1939 MockRead(ASYNC, 22, "hello"),
1940 };
1941 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1942 arraysize(data_writes));
1943 data.set_busy_before_sync_reads(true);
1944 session_deps_.socket_factory->AddSocketDataProvider(&data);
1945
1946 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501947 std::string response_lines[kNumUnreadBodies];
1948
mikecironef22f9812016-10-04 03:40:191949 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181950 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411951 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131952
bnc691fda62016-08-12 00:43:161953 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:501954 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131955
tfarina42834112016-09-22 13:38:201956 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011957 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:131958
[email protected]58e32bb2013-01-21 18:23:251959 LoadTimingInfo load_timing_info;
1960 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1961 if (i == 0) {
1962 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1963 first_socket_log_id = load_timing_info.socket_log_id;
1964 } else {
1965 TestLoadTimingReused(load_timing_info);
1966 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1967 }
1968
[email protected]fc31d6a42010-06-24 18:05:131969 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181970 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131971
mmenkecc2298e2015-12-07 18:20:181972 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501973 response_lines[i] = response->headers->GetStatusLine();
1974
mmenkecc2298e2015-12-07 18:20:181975 // Delete the transaction without reading the response bodies. Then spin
1976 // the message loop, so the response bodies are drained.
1977 trans.reset();
1978 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131979 }
[email protected]0b0bf032010-09-21 18:08:501980
1981 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181982 "HTTP/1.1 204 No Content",
1983 "HTTP/1.1 205 Reset Content",
1984 "HTTP/1.1 304 Not Modified",
1985 "HTTP/1.1 302 Found",
1986 "HTTP/1.1 302 Found",
1987 "HTTP/1.1 301 Moved Permanently",
1988 "HTTP/1.1 301 Moved Permanently",
1989 "HTTP/1.1 200 Hunky-Dory",
1990 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:501991 };
1992
mostynb91e0da982015-01-20 19:17:271993 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1994 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501995
1996 for (int i = 0; i < kNumUnreadBodies; ++i)
1997 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1998
[email protected]49639fa2011-12-20 23:22:411999 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162000 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202001 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012002 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162003 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182004 ASSERT_TRUE(response);
2005 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502006 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2007 std::string response_data;
bnc691fda62016-08-12 00:43:162008 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012009 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502010 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132011}
2012
mmenke5f94fda2016-06-02 20:54:132013// Sockets that receive extra data after a response is complete should not be
2014// reused.
bncd16676a2016-07-20 16:23:012015TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132016 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2017 MockWrite data_writes1[] = {
2018 MockWrite("HEAD / HTTP/1.1\r\n"
2019 "Host: www.borked.com\r\n"
2020 "Connection: keep-alive\r\n\r\n"),
2021 };
2022
2023 MockRead data_reads1[] = {
2024 MockRead("HTTP/1.1 200 OK\r\n"
2025 "Connection: keep-alive\r\n"
2026 "Content-Length: 22\r\n\r\n"
2027 "This server is borked."),
2028 };
2029
2030 MockWrite data_writes2[] = {
2031 MockWrite("GET /foo HTTP/1.1\r\n"
2032 "Host: www.borked.com\r\n"
2033 "Connection: keep-alive\r\n\r\n"),
2034 };
2035
2036 MockRead data_reads2[] = {
2037 MockRead("HTTP/1.1 200 OK\r\n"
2038 "Content-Length: 3\r\n\r\n"
2039 "foo"),
2040 };
2041 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2042 data_writes1, arraysize(data_writes1));
2043 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2044 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2045 data_writes2, arraysize(data_writes2));
2046 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2047
2048 TestCompletionCallback callback;
2049 HttpRequestInfo request1;
2050 request1.method = "HEAD";
2051 request1.url = GURL("http://www.borked.com/");
2052
bnc691fda62016-08-12 00:43:162053 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132054 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202055 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012056 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132057
2058 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2059 ASSERT_TRUE(response1);
2060 ASSERT_TRUE(response1->headers);
2061 EXPECT_EQ(200, response1->headers->response_code());
2062 EXPECT_TRUE(response1->headers->IsKeepAlive());
2063
2064 std::string response_data1;
robpercival214763f2016-07-01 23:27:012065 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132066 EXPECT_EQ("", response_data1);
2067 // Deleting the transaction attempts to release the socket back into the
2068 // socket pool.
2069 trans1.reset();
2070
2071 HttpRequestInfo request2;
2072 request2.method = "GET";
2073 request2.url = GURL("http://www.borked.com/foo");
2074
bnc691fda62016-08-12 00:43:162075 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132076 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202077 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012078 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132079
2080 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2081 ASSERT_TRUE(response2);
2082 ASSERT_TRUE(response2->headers);
2083 EXPECT_EQ(200, response2->headers->response_code());
2084
2085 std::string response_data2;
robpercival214763f2016-07-01 23:27:012086 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132087 EXPECT_EQ("foo", response_data2);
2088}
2089
bncd16676a2016-07-20 16:23:012090TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132091 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2092 MockWrite data_writes1[] = {
2093 MockWrite("GET / HTTP/1.1\r\n"
2094 "Host: www.borked.com\r\n"
2095 "Connection: keep-alive\r\n\r\n"),
2096 };
2097
2098 MockRead data_reads1[] = {
2099 MockRead("HTTP/1.1 200 OK\r\n"
2100 "Connection: keep-alive\r\n"
2101 "Content-Length: 22\r\n\r\n"
2102 "This server is borked."
2103 "Bonus data!"),
2104 };
2105
2106 MockWrite data_writes2[] = {
2107 MockWrite("GET /foo HTTP/1.1\r\n"
2108 "Host: www.borked.com\r\n"
2109 "Connection: keep-alive\r\n\r\n"),
2110 };
2111
2112 MockRead data_reads2[] = {
2113 MockRead("HTTP/1.1 200 OK\r\n"
2114 "Content-Length: 3\r\n\r\n"
2115 "foo"),
2116 };
2117 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2118 data_writes1, arraysize(data_writes1));
2119 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2120 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2121 data_writes2, arraysize(data_writes2));
2122 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2123
2124 TestCompletionCallback callback;
2125 HttpRequestInfo request1;
2126 request1.method = "GET";
2127 request1.url = GURL("http://www.borked.com/");
2128
bnc691fda62016-08-12 00:43:162129 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132130 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202131 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012132 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132133
2134 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2135 ASSERT_TRUE(response1);
2136 ASSERT_TRUE(response1->headers);
2137 EXPECT_EQ(200, response1->headers->response_code());
2138 EXPECT_TRUE(response1->headers->IsKeepAlive());
2139
2140 std::string response_data1;
robpercival214763f2016-07-01 23:27:012141 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132142 EXPECT_EQ("This server is borked.", response_data1);
2143 // Deleting the transaction attempts to release the socket back into the
2144 // socket pool.
2145 trans1.reset();
2146
2147 HttpRequestInfo request2;
2148 request2.method = "GET";
2149 request2.url = GURL("http://www.borked.com/foo");
2150
bnc691fda62016-08-12 00:43:162151 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132152 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202153 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012154 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132155
2156 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2157 ASSERT_TRUE(response2);
2158 ASSERT_TRUE(response2->headers);
2159 EXPECT_EQ(200, response2->headers->response_code());
2160
2161 std::string response_data2;
robpercival214763f2016-07-01 23:27:012162 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132163 EXPECT_EQ("foo", response_data2);
2164}
2165
bncd16676a2016-07-20 16:23:012166TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132167 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2168 MockWrite data_writes1[] = {
2169 MockWrite("GET / HTTP/1.1\r\n"
2170 "Host: www.borked.com\r\n"
2171 "Connection: keep-alive\r\n\r\n"),
2172 };
2173
2174 MockRead data_reads1[] = {
2175 MockRead("HTTP/1.1 200 OK\r\n"
2176 "Connection: keep-alive\r\n"
2177 "Transfer-Encoding: chunked\r\n\r\n"),
2178 MockRead("16\r\nThis server is borked.\r\n"),
2179 MockRead("0\r\n\r\nBonus data!"),
2180 };
2181
2182 MockWrite data_writes2[] = {
2183 MockWrite("GET /foo HTTP/1.1\r\n"
2184 "Host: www.borked.com\r\n"
2185 "Connection: keep-alive\r\n\r\n"),
2186 };
2187
2188 MockRead data_reads2[] = {
2189 MockRead("HTTP/1.1 200 OK\r\n"
2190 "Content-Length: 3\r\n\r\n"
2191 "foo"),
2192 };
2193 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2194 data_writes1, arraysize(data_writes1));
2195 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2196 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2197 data_writes2, arraysize(data_writes2));
2198 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2199
2200 TestCompletionCallback callback;
2201 HttpRequestInfo request1;
2202 request1.method = "GET";
2203 request1.url = GURL("http://www.borked.com/");
2204
bnc691fda62016-08-12 00:43:162205 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132206 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202207 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012208 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132209
2210 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2211 ASSERT_TRUE(response1);
2212 ASSERT_TRUE(response1->headers);
2213 EXPECT_EQ(200, response1->headers->response_code());
2214 EXPECT_TRUE(response1->headers->IsKeepAlive());
2215
2216 std::string response_data1;
robpercival214763f2016-07-01 23:27:012217 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132218 EXPECT_EQ("This server is borked.", response_data1);
2219 // Deleting the transaction attempts to release the socket back into the
2220 // socket pool.
2221 trans1.reset();
2222
2223 HttpRequestInfo request2;
2224 request2.method = "GET";
2225 request2.url = GURL("http://www.borked.com/foo");
2226
bnc691fda62016-08-12 00:43:162227 std::unique_ptr<HttpNetworkTransaction> trans2(
mmenke5f94fda2016-06-02 20:54:132228 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202229 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012230 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132231
2232 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2233 ASSERT_TRUE(response2);
2234 ASSERT_TRUE(response2->headers);
2235 EXPECT_EQ(200, response2->headers->response_code());
2236
2237 std::string response_data2;
robpercival214763f2016-07-01 23:27:012238 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132239 EXPECT_EQ("foo", response_data2);
2240}
2241
2242// This is a little different from the others - it tests the case that the
2243// HttpStreamParser doesn't know if there's extra data on a socket or not when
2244// the HttpNetworkTransaction is torn down, because the response body hasn't
2245// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012246TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132247 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2248 MockWrite data_writes1[] = {
2249 MockWrite("GET / HTTP/1.1\r\n"
2250 "Host: www.borked.com\r\n"
2251 "Connection: keep-alive\r\n\r\n"),
2252 };
2253
2254 MockRead data_reads1[] = {
2255 MockRead("HTTP/1.1 200 OK\r\n"
2256 "Connection: keep-alive\r\n"
2257 "Transfer-Encoding: chunked\r\n\r\n"),
2258 MockRead("16\r\nThis server is borked.\r\n"),
2259 MockRead("0\r\n\r\nBonus data!"),
2260 };
2261 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2262 data_writes1, arraysize(data_writes1));
2263 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2264
2265 TestCompletionCallback callback;
2266 HttpRequestInfo request1;
2267 request1.method = "GET";
2268 request1.url = GURL("http://www.borked.com/");
2269
bnc691fda62016-08-12 00:43:162270 std::unique_ptr<HttpNetworkTransaction> trans1(
mmenke5f94fda2016-06-02 20:54:132271 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:202272 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012273 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132274
2275 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2276 ASSERT_TRUE(response1);
2277 ASSERT_TRUE(response1->headers);
2278 EXPECT_EQ(200, response1->headers->response_code());
2279 EXPECT_TRUE(response1->headers->IsKeepAlive());
2280
2281 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2282 // response body.
2283 trans1.reset();
2284
2285 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2286 // socket can't be reused, rather than returning it to the socket pool.
2287 base::RunLoop().RunUntilIdle();
2288
2289 // There should be no idle sockets in the pool.
2290 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2291}
2292
[email protected]038e9a32008-10-08 22:40:162293// Test the request-challenge-retry sequence for basic auth.
2294// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012295TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422296 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162297 request.method = "GET";
bncce36dca22015-04-21 22:11:232298 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162299
vishal.b62985ca92015-04-17 08:45:512300 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072301 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092302 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162303 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272304
[email protected]f9ee6b52008-11-08 06:46:232305 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232306 MockWrite(
2307 "GET / HTTP/1.1\r\n"
2308 "Host: www.example.org\r\n"
2309 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232310 };
2311
[email protected]038e9a32008-10-08 22:40:162312 MockRead data_reads1[] = {
2313 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2314 // Give a couple authenticate options (only the middle one is actually
2315 // supported).
[email protected]22927ad2009-09-21 19:56:192316 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162317 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2318 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2319 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2320 // Large content-length -- won't matter, as connection will be reset.
2321 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062322 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162323 };
2324
2325 // After calling trans->RestartWithAuth(), this is the request we should
2326 // be issuing -- the final header line contains the credentials.
2327 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232328 MockWrite(
2329 "GET / HTTP/1.1\r\n"
2330 "Host: www.example.org\r\n"
2331 "Connection: keep-alive\r\n"
2332 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162333 };
2334
2335 // Lastly, the server responds with the actual content.
2336 MockRead data_reads2[] = {
2337 MockRead("HTTP/1.0 200 OK\r\n"),
2338 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2339 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062340 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162341 };
2342
[email protected]31a2bfe2010-02-09 08:03:392343 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2344 data_writes1, arraysize(data_writes1));
2345 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2346 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072347 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2348 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162349
[email protected]49639fa2011-12-20 23:22:412350 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162351
tfarina42834112016-09-22 13:38:202352 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012353 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162354
2355 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012356 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162357
[email protected]58e32bb2013-01-21 18:23:252358 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162359 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252360 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2361
sclittlefb249892015-09-10 21:33:222362 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162363 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222364 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162365 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192366
bnc691fda62016-08-12 00:43:162367 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522368 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042369 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162370
[email protected]49639fa2011-12-20 23:22:412371 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162372
bnc691fda62016-08-12 00:43:162373 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012374 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162375
2376 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012377 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162378
[email protected]58e32bb2013-01-21 18:23:252379 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162380 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252381 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2382 // The load timing after restart should have a new socket ID, and times after
2383 // those of the first load timing.
2384 EXPECT_LE(load_timing_info1.receive_headers_end,
2385 load_timing_info2.connect_timing.connect_start);
2386 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2387
sclittlefb249892015-09-10 21:33:222388 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162389 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222390 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162391 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192392
bnc691fda62016-08-12 00:43:162393 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522394 ASSERT_TRUE(response);
2395 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162396 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162397}
2398
ttuttled9dbc652015-09-29 20:00:592399// Test the request-challenge-retry sequence for basic auth.
2400// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012401TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592402 HttpRequestInfo request;
2403 request.method = "GET";
2404 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592405
2406 TestNetLog log;
2407 MockHostResolver* resolver = new MockHostResolver();
2408 session_deps_.net_log = &log;
2409 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092410 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162411 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592412
2413 resolver->rules()->ClearRules();
2414 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2415
2416 MockWrite data_writes1[] = {
2417 MockWrite("GET / HTTP/1.1\r\n"
2418 "Host: www.example.org\r\n"
2419 "Connection: keep-alive\r\n\r\n"),
2420 };
2421
2422 MockRead data_reads1[] = {
2423 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2424 // Give a couple authenticate options (only the middle one is actually
2425 // supported).
2426 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2427 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2428 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2429 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2430 // Large content-length -- won't matter, as connection will be reset.
2431 MockRead("Content-Length: 10000\r\n\r\n"),
2432 MockRead(SYNCHRONOUS, ERR_FAILED),
2433 };
2434
2435 // After calling trans->RestartWithAuth(), this is the request we should
2436 // be issuing -- the final header line contains the credentials.
2437 MockWrite data_writes2[] = {
2438 MockWrite("GET / HTTP/1.1\r\n"
2439 "Host: www.example.org\r\n"
2440 "Connection: keep-alive\r\n"
2441 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2442 };
2443
2444 // Lastly, the server responds with the actual content.
2445 MockRead data_reads2[] = {
2446 MockRead("HTTP/1.0 200 OK\r\n"),
2447 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2448 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2449 };
2450
2451 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2452 data_writes1, arraysize(data_writes1));
2453 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2454 data_writes2, arraysize(data_writes2));
2455 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2456 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2457
2458 TestCompletionCallback callback1;
2459
bnc691fda62016-08-12 00:43:162460 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202461 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592462
2463 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162464 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592465 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2466
2467 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162468 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592469 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162470 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592471
bnc691fda62016-08-12 00:43:162472 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592473 ASSERT_TRUE(response);
2474 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2475
2476 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162477 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592478 ASSERT_FALSE(endpoint.address().empty());
2479 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2480
2481 resolver->rules()->ClearRules();
2482 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2483
2484 TestCompletionCallback callback2;
2485
bnc691fda62016-08-12 00:43:162486 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592487 AuthCredentials(kFoo, kBar), callback2.callback())));
2488
2489 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162490 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592491 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2492 // The load timing after restart should have a new socket ID, and times after
2493 // those of the first load timing.
2494 EXPECT_LE(load_timing_info1.receive_headers_end,
2495 load_timing_info2.connect_timing.connect_start);
2496 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2497
2498 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162499 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592500 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162501 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592502
bnc691fda62016-08-12 00:43:162503 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592504 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522505 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592506 EXPECT_EQ(100, response->headers->GetContentLength());
2507
bnc691fda62016-08-12 00:43:162508 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592509 ASSERT_FALSE(endpoint.address().empty());
2510 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2511}
2512
bncd16676a2016-07-20 16:23:012513TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462514 HttpRequestInfo request;
2515 request.method = "GET";
bncce36dca22015-04-21 22:11:232516 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292517 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462518
danakj1fd259a02016-04-16 03:17:092519 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162520 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272521
[email protected]861fcd52009-08-26 02:33:462522 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232523 MockWrite(
2524 "GET / HTTP/1.1\r\n"
2525 "Host: www.example.org\r\n"
2526 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462527 };
2528
2529 MockRead data_reads[] = {
2530 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2531 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2532 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2533 // Large content-length -- won't matter, as connection will be reset.
2534 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062535 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462536 };
2537
[email protected]31a2bfe2010-02-09 08:03:392538 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2539 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072540 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412541 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462542
tfarina42834112016-09-22 13:38:202543 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462545
2546 rv = callback.WaitForResult();
2547 EXPECT_EQ(0, rv);
2548
sclittlefb249892015-09-10 21:33:222549 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162550 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222551 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162552 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192553
bnc691fda62016-08-12 00:43:162554 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522555 ASSERT_TRUE(response);
2556 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462557}
2558
[email protected]2d2697f92009-02-18 21:00:322559// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2560// connection.
bncd16676a2016-07-20 16:23:012561TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182562 // On the second pass, the body read of the auth challenge is synchronous, so
2563 // IsConnectedAndIdle returns false. The socket should still be drained and
2564 // reused. See http://crbug.com/544255.
2565 for (int i = 0; i < 2; ++i) {
2566 HttpRequestInfo request;
2567 request.method = "GET";
2568 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322569
mmenkecc2298e2015-12-07 18:20:182570 TestNetLog log;
2571 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092572 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272573
mmenkecc2298e2015-12-07 18:20:182574 MockWrite data_writes[] = {
2575 MockWrite(ASYNC, 0,
2576 "GET / HTTP/1.1\r\n"
2577 "Host: www.example.org\r\n"
2578 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322579
bnc691fda62016-08-12 00:43:162580 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182581 // be issuing -- the final header line contains the credentials.
2582 MockWrite(ASYNC, 6,
2583 "GET / HTTP/1.1\r\n"
2584 "Host: www.example.org\r\n"
2585 "Connection: keep-alive\r\n"
2586 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2587 };
[email protected]2d2697f92009-02-18 21:00:322588
mmenkecc2298e2015-12-07 18:20:182589 MockRead data_reads[] = {
2590 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2591 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2592 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2593 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2594 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322595
mmenkecc2298e2015-12-07 18:20:182596 // Lastly, the server responds with the actual content.
2597 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2598 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2599 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2600 MockRead(ASYNC, 10, "Hello"),
2601 };
[email protected]2d2697f92009-02-18 21:00:322602
mmenkecc2298e2015-12-07 18:20:182603 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2604 arraysize(data_writes));
2605 data.set_busy_before_sync_reads(true);
2606 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462607
mmenkecc2298e2015-12-07 18:20:182608 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322609
bnc691fda62016-08-12 00:43:162610 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202611 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012612 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322613
mmenkecc2298e2015-12-07 18:20:182614 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162615 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182616 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322617
bnc691fda62016-08-12 00:43:162618 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182619 ASSERT_TRUE(response);
2620 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322621
mmenkecc2298e2015-12-07 18:20:182622 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252623
bnc691fda62016-08-12 00:43:162624 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2625 callback2.callback());
robpercival214763f2016-07-01 23:27:012626 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322627
mmenkecc2298e2015-12-07 18:20:182628 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162629 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182630 TestLoadTimingReused(load_timing_info2);
2631 // The load timing after restart should have the same socket ID, and times
2632 // those of the first load timing.
2633 EXPECT_LE(load_timing_info1.receive_headers_end,
2634 load_timing_info2.send_start);
2635 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322636
bnc691fda62016-08-12 00:43:162637 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182638 ASSERT_TRUE(response);
2639 EXPECT_FALSE(response->auth_challenge);
2640 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322641
mmenkecc2298e2015-12-07 18:20:182642 std::string response_data;
bnc691fda62016-08-12 00:43:162643 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322644
mmenkecc2298e2015-12-07 18:20:182645 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162646 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182647 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162648 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182649 }
[email protected]2d2697f92009-02-18 21:00:322650}
2651
2652// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2653// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012654TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422655 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322656 request.method = "GET";
bncce36dca22015-04-21 22:11:232657 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322658
danakj1fd259a02016-04-16 03:17:092659 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272660
[email protected]2d2697f92009-02-18 21:00:322661 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162662 MockWrite("GET / HTTP/1.1\r\n"
2663 "Host: www.example.org\r\n"
2664 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322665
bnc691fda62016-08-12 00:43:162666 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232667 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162668 MockWrite("GET / HTTP/1.1\r\n"
2669 "Host: www.example.org\r\n"
2670 "Connection: keep-alive\r\n"
2671 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322672 };
2673
[email protected]2d2697f92009-02-18 21:00:322674 MockRead data_reads1[] = {
2675 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2676 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312677 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322678
2679 // Lastly, the server responds with the actual content.
2680 MockRead("HTTP/1.1 200 OK\r\n"),
2681 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502682 MockRead("Content-Length: 5\r\n\r\n"),
2683 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322684 };
2685
[email protected]2d0a4f92011-05-05 16:38:462686 // An incorrect reconnect would cause this to be read.
2687 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062688 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462689 };
2690
[email protected]31a2bfe2010-02-09 08:03:392691 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2692 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462693 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2694 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072695 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2696 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322697
[email protected]49639fa2011-12-20 23:22:412698 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322699
bnc691fda62016-08-12 00:43:162700 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202701 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012702 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322703
2704 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012705 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322706
bnc691fda62016-08-12 00:43:162707 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522708 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042709 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322710
[email protected]49639fa2011-12-20 23:22:412711 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322712
bnc691fda62016-08-12 00:43:162713 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322715
2716 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012717 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322718
bnc691fda62016-08-12 00:43:162719 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522720 ASSERT_TRUE(response);
2721 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502722 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322723}
2724
2725// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2726// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012727TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422728 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322729 request.method = "GET";
bncce36dca22015-04-21 22:11:232730 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322731
danakj1fd259a02016-04-16 03:17:092732 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272733
[email protected]2d2697f92009-02-18 21:00:322734 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162735 MockWrite("GET / HTTP/1.1\r\n"
2736 "Host: www.example.org\r\n"
2737 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322738
bnc691fda62016-08-12 00:43:162739 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232740 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162741 MockWrite("GET / HTTP/1.1\r\n"
2742 "Host: www.example.org\r\n"
2743 "Connection: keep-alive\r\n"
2744 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322745 };
2746
2747 // Respond with 5 kb of response body.
2748 std::string large_body_string("Unauthorized");
2749 large_body_string.append(5 * 1024, ' ');
2750 large_body_string.append("\r\n");
2751
2752 MockRead data_reads1[] = {
2753 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2754 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2755 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2756 // 5134 = 12 + 5 * 1024 + 2
2757 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062758 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322759
2760 // Lastly, the server responds with the actual content.
2761 MockRead("HTTP/1.1 200 OK\r\n"),
2762 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502763 MockRead("Content-Length: 5\r\n\r\n"),
2764 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322765 };
2766
[email protected]2d0a4f92011-05-05 16:38:462767 // An incorrect reconnect would cause this to be read.
2768 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062769 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462770 };
2771
[email protected]31a2bfe2010-02-09 08:03:392772 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2773 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462774 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2775 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072776 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2777 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322778
[email protected]49639fa2011-12-20 23:22:412779 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322780
bnc691fda62016-08-12 00:43:162781 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202782 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322784
2785 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012786 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322787
bnc691fda62016-08-12 00:43:162788 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522789 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042790 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322791
[email protected]49639fa2011-12-20 23:22:412792 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322793
bnc691fda62016-08-12 00:43:162794 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012795 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322796
2797 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012798 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322799
bnc691fda62016-08-12 00:43:162800 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522801 ASSERT_TRUE(response);
2802 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502803 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322804}
2805
2806// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312807// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012808TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312809 HttpRequestInfo request;
2810 request.method = "GET";
bncce36dca22015-04-21 22:11:232811 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312812
danakj1fd259a02016-04-16 03:17:092813 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272814
[email protected]11203f012009-11-12 23:02:312815 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232816 MockWrite(
2817 "GET / HTTP/1.1\r\n"
2818 "Host: www.example.org\r\n"
2819 "Connection: keep-alive\r\n\r\n"),
2820 // This simulates the seemingly successful write to a closed connection
2821 // if the bug is not fixed.
2822 MockWrite(
2823 "GET / HTTP/1.1\r\n"
2824 "Host: www.example.org\r\n"
2825 "Connection: keep-alive\r\n"
2826 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312827 };
2828
2829 MockRead data_reads1[] = {
2830 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2831 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2832 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2833 MockRead("Content-Length: 14\r\n\r\n"),
2834 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062835 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312836 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062837 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312838 };
2839
bnc691fda62016-08-12 00:43:162840 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312841 // be issuing -- the final header line contains the credentials.
2842 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232843 MockWrite(
2844 "GET / HTTP/1.1\r\n"
2845 "Host: www.example.org\r\n"
2846 "Connection: keep-alive\r\n"
2847 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312848 };
2849
2850 // Lastly, the server responds with the actual content.
2851 MockRead data_reads2[] = {
2852 MockRead("HTTP/1.1 200 OK\r\n"),
2853 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502854 MockRead("Content-Length: 5\r\n\r\n"),
2855 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312856 };
2857
[email protected]31a2bfe2010-02-09 08:03:392858 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2859 data_writes1, arraysize(data_writes1));
2860 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2861 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072862 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2863 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312864
[email protected]49639fa2011-12-20 23:22:412865 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312866
bnc691fda62016-08-12 00:43:162867 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202868 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012869 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312870
2871 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012872 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312873
bnc691fda62016-08-12 00:43:162874 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522875 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042876 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312877
[email protected]49639fa2011-12-20 23:22:412878 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312879
bnc691fda62016-08-12 00:43:162880 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312882
2883 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012884 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312885
bnc691fda62016-08-12 00:43:162886 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522887 ASSERT_TRUE(response);
2888 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502889 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312890}
2891
[email protected]394816e92010-08-03 07:38:592892// Test the request-challenge-retry sequence for basic auth, over a connection
2893// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012894TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:012895 HttpRequestInfo request;
2896 request.method = "GET";
bncce36dca22015-04-21 22:11:232897 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012898 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292899 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012900
2901 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032902 session_deps_.proxy_service =
2903 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512904 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012905 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012907
2908 // Since we have proxy, should try to establish tunnel.
2909 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542910 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172911 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542912 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012913 };
2914
mmenkee71e15332015-10-07 16:39:542915 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012916 // connection.
2917 MockRead data_reads1[] = {
2918 // No credentials.
2919 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2920 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542921 };
ttuttle34f63b52015-03-05 04:33:012922
mmenkee71e15332015-10-07 16:39:542923 // Since the first connection couldn't be reused, need to establish another
2924 // once given credentials.
2925 MockWrite data_writes2[] = {
2926 // After calling trans->RestartWithAuth(), this is the request we should
2927 // be issuing -- the final header line contains the credentials.
2928 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172929 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542930 "Proxy-Connection: keep-alive\r\n"
2931 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2932
2933 MockWrite("GET / HTTP/1.1\r\n"
2934 "Host: www.example.org\r\n"
2935 "Connection: keep-alive\r\n\r\n"),
2936 };
2937
2938 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012939 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2940
2941 MockRead("HTTP/1.1 200 OK\r\n"),
2942 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2943 MockRead("Content-Length: 5\r\n\r\n"),
2944 MockRead(SYNCHRONOUS, "hello"),
2945 };
2946
2947 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2948 data_writes1, arraysize(data_writes1));
2949 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542950 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2951 data_writes2, arraysize(data_writes2));
2952 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012953 SSLSocketDataProvider ssl(ASYNC, OK);
2954 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2955
2956 TestCompletionCallback callback1;
2957
bnc691fda62016-08-12 00:43:162958 std::unique_ptr<HttpNetworkTransaction> trans(
ttuttle34f63b52015-03-05 04:33:012959 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2960
2961 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:012962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012963
2964 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012965 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:462966 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012967 log.GetEntries(&entries);
2968 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002969 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2970 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012971 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:002972 entries, pos,
2973 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2974 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:012975
2976 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522977 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012978 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522979 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:012980 EXPECT_EQ(407, response->headers->response_code());
2981 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2982 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2983
2984 LoadTimingInfo load_timing_info;
2985 // CONNECT requests and responses are handled at the connect job level, so
2986 // the transaction does not yet have a connection.
2987 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2988
2989 TestCompletionCallback callback2;
2990
2991 rv =
2992 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012993 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:012994
2995 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012996 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:012997
2998 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522999 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013000
3001 EXPECT_TRUE(response->headers->IsKeepAlive());
3002 EXPECT_EQ(200, response->headers->response_code());
3003 EXPECT_EQ(5, response->headers->GetContentLength());
3004 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3005
3006 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523007 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013008
3009 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3010 TestLoadTimingNotReusedWithPac(load_timing_info,
3011 CONNECT_TIMING_HAS_SSL_TIMES);
3012
3013 trans.reset();
3014 session->CloseAllConnections();
3015}
3016
3017// Test the request-challenge-retry sequence for basic auth, over a connection
3018// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013019TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593020 HttpRequestInfo request;
3021 request.method = "GET";
bncce36dca22015-04-21 22:11:233022 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593023 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293024 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593025
[email protected]cb9bf6ca2011-01-28 13:15:273026 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033027 session_deps_.proxy_service =
3028 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513029 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073030 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273032
[email protected]394816e92010-08-03 07:38:593033 // Since we have proxy, should try to establish tunnel.
3034 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543035 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173036 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543037 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113038 };
3039
mmenkee71e15332015-10-07 16:39:543040 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083041 // connection.
3042 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543043 // No credentials.
3044 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3045 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3046 MockRead("Proxy-Connection: close\r\n\r\n"),
3047 };
mmenkee0b5c882015-08-26 20:29:113048
mmenkee71e15332015-10-07 16:39:543049 MockWrite data_writes2[] = {
3050 // After calling trans->RestartWithAuth(), this is the request we should
3051 // be issuing -- the final header line contains the credentials.
3052 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173053 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543054 "Proxy-Connection: keep-alive\r\n"
3055 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083056
mmenkee71e15332015-10-07 16:39:543057 MockWrite("GET / HTTP/1.1\r\n"
3058 "Host: www.example.org\r\n"
3059 "Connection: keep-alive\r\n\r\n"),
3060 };
3061
3062 MockRead data_reads2[] = {
3063 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3064
3065 MockRead("HTTP/1.1 200 OK\r\n"),
3066 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3067 MockRead("Content-Length: 5\r\n\r\n"),
3068 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593069 };
3070
3071 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3072 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073073 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543074 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3075 data_writes2, arraysize(data_writes2));
3076 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063077 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073078 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593079
[email protected]49639fa2011-12-20 23:22:413080 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593081
bnc691fda62016-08-12 00:43:163082 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:503083 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503084
[email protected]49639fa2011-12-20 23:22:413085 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013086 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593087
3088 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013089 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463090 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403091 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593092 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003093 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3094 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593095 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403096 entries, pos,
mikecirone8b85c432016-09-08 19:11:003097 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3098 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593099
3100 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523101 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013102 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523103 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593104 EXPECT_EQ(407, response->headers->response_code());
3105 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043106 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593107
[email protected]029c83b62013-01-24 05:28:203108 LoadTimingInfo load_timing_info;
3109 // CONNECT requests and responses are handled at the connect job level, so
3110 // the transaction does not yet have a connection.
3111 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3112
[email protected]49639fa2011-12-20 23:22:413113 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593114
[email protected]49639fa2011-12-20 23:22:413115 rv = trans->RestartWithAuth(
3116 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013117 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593118
3119 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013120 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593121
3122 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523123 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593124
3125 EXPECT_TRUE(response->headers->IsKeepAlive());
3126 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503127 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593128 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3129
3130 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523131 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503132
[email protected]029c83b62013-01-24 05:28:203133 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3134 TestLoadTimingNotReusedWithPac(load_timing_info,
3135 CONNECT_TIMING_HAS_SSL_TIMES);
3136
[email protected]0b0bf032010-09-21 18:08:503137 trans.reset();
[email protected]102e27c2011-02-23 01:01:313138 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593139}
3140
[email protected]11203f012009-11-12 23:02:313141// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013142// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013143TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233144 // On the second pass, the body read of the auth challenge is synchronous, so
3145 // IsConnectedAndIdle returns false. The socket should still be drained and
3146 // reused. See http://crbug.com/544255.
3147 for (int i = 0; i < 2; ++i) {
3148 HttpRequestInfo request;
3149 request.method = "GET";
3150 request.url = GURL("https://www.example.org/");
3151 // Ensure that proxy authentication is attempted even
3152 // when the no authentication data flag is set.
3153 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013154
mmenked39192ee2015-12-09 00:57:233155 // Configure against proxy server "myproxy:70".
3156 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3157 BoundTestNetLog log;
3158 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093159 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013160
bnc691fda62016-08-12 00:43:163161 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013162
mmenked39192ee2015-12-09 00:57:233163 // Since we have proxy, should try to establish tunnel.
3164 MockWrite data_writes1[] = {
3165 MockWrite(ASYNC, 0,
3166 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3167 "Host: www.example.org:443\r\n"
3168 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013169
bnc691fda62016-08-12 00:43:163170 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233171 // be issuing -- the final header line contains the credentials.
3172 MockWrite(ASYNC, 3,
3173 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3174 "Host: www.example.org:443\r\n"
3175 "Proxy-Connection: keep-alive\r\n"
3176 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3177 };
ttuttle34f63b52015-03-05 04:33:013178
mmenked39192ee2015-12-09 00:57:233179 // The proxy responds to the connect with a 407, using a persistent
3180 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3181 MockRead data_reads1[] = {
3182 // No credentials.
3183 MockRead(ASYNC, 1,
3184 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3185 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3186 "Proxy-Connection: keep-alive\r\n"
3187 "Content-Length: 10\r\n\r\n"),
3188 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013189
mmenked39192ee2015-12-09 00:57:233190 // Wrong credentials (wrong password).
3191 MockRead(ASYNC, 4,
3192 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3193 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3194 "Proxy-Connection: keep-alive\r\n"
3195 "Content-Length: 10\r\n\r\n"),
3196 // No response body because the test stops reading here.
3197 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3198 };
ttuttle34f63b52015-03-05 04:33:013199
mmenked39192ee2015-12-09 00:57:233200 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3201 arraysize(data_writes1));
3202 data1.set_busy_before_sync_reads(true);
3203 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013204
mmenked39192ee2015-12-09 00:57:233205 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013206
bnc691fda62016-08-12 00:43:163207 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013208 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013209
mmenked39192ee2015-12-09 00:57:233210 TestNetLogEntry::List entries;
3211 log.GetEntries(&entries);
3212 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003213 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3214 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233215 ExpectLogContainsSomewhere(
3216 entries, pos,
mikecirone8b85c432016-09-08 19:11:003217 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3218 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013219
bnc691fda62016-08-12 00:43:163220 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233221 ASSERT_TRUE(response);
3222 ASSERT_TRUE(response->headers);
3223 EXPECT_TRUE(response->headers->IsKeepAlive());
3224 EXPECT_EQ(407, response->headers->response_code());
3225 EXPECT_EQ(10, response->headers->GetContentLength());
3226 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3227 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013228
mmenked39192ee2015-12-09 00:57:233229 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013230
mmenked39192ee2015-12-09 00:57:233231 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163232 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3233 callback2.callback());
robpercival214763f2016-07-01 23:27:013234 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013235
bnc691fda62016-08-12 00:43:163236 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233237 ASSERT_TRUE(response);
3238 ASSERT_TRUE(response->headers);
3239 EXPECT_TRUE(response->headers->IsKeepAlive());
3240 EXPECT_EQ(407, response->headers->response_code());
3241 EXPECT_EQ(10, response->headers->GetContentLength());
3242 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3243 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013244
mmenked39192ee2015-12-09 00:57:233245 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3246 // out of scope.
3247 session->CloseAllConnections();
3248 }
ttuttle34f63b52015-03-05 04:33:013249}
3250
3251// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3252// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013253TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233254 // On the second pass, the body read of the auth challenge is synchronous, so
3255 // IsConnectedAndIdle returns false. The socket should still be drained and
3256 // reused. See http://crbug.com/544255.
3257 for (int i = 0; i < 2; ++i) {
3258 HttpRequestInfo request;
3259 request.method = "GET";
3260 request.url = GURL("https://www.example.org/");
3261 // Ensure that proxy authentication is attempted even
3262 // when the no authentication data flag is set.
3263 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3264
3265 // Configure against proxy server "myproxy:70".
3266 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3267 BoundTestNetLog log;
3268 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093269 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233270
bnc691fda62016-08-12 00:43:163271 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233272
3273 // Since we have proxy, should try to establish tunnel.
3274 MockWrite data_writes1[] = {
3275 MockWrite(ASYNC, 0,
3276 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3277 "Host: www.example.org:443\r\n"
3278 "Proxy-Connection: keep-alive\r\n\r\n"),
3279
bnc691fda62016-08-12 00:43:163280 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233281 // be issuing -- the final header line contains the credentials.
3282 MockWrite(ASYNC, 3,
3283 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3284 "Host: www.example.org:443\r\n"
3285 "Proxy-Connection: keep-alive\r\n"
3286 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3287 };
3288
3289 // The proxy responds to the connect with a 407, using a persistent
3290 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3291 MockRead data_reads1[] = {
3292 // No credentials.
3293 MockRead(ASYNC, 1,
3294 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3295 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3296 "Content-Length: 10\r\n\r\n"),
3297 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3298
3299 // Wrong credentials (wrong password).
3300 MockRead(ASYNC, 4,
3301 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3302 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3303 "Content-Length: 10\r\n\r\n"),
3304 // No response body because the test stops reading here.
3305 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3306 };
3307
3308 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3309 arraysize(data_writes1));
3310 data1.set_busy_before_sync_reads(true);
3311 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3312
3313 TestCompletionCallback callback1;
3314
bnc691fda62016-08-12 00:43:163315 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013316 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233317
3318 TestNetLogEntry::List entries;
3319 log.GetEntries(&entries);
3320 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003321 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3322 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233323 ExpectLogContainsSomewhere(
3324 entries, pos,
mikecirone8b85c432016-09-08 19:11:003325 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3326 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233327
bnc691fda62016-08-12 00:43:163328 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233329 ASSERT_TRUE(response);
3330 ASSERT_TRUE(response->headers);
3331 EXPECT_TRUE(response->headers->IsKeepAlive());
3332 EXPECT_EQ(407, response->headers->response_code());
3333 EXPECT_EQ(10, response->headers->GetContentLength());
3334 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3335 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3336
3337 TestCompletionCallback callback2;
3338
3339 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163340 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3341 callback2.callback());
robpercival214763f2016-07-01 23:27:013342 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233343
bnc691fda62016-08-12 00:43:163344 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233345 ASSERT_TRUE(response);
3346 ASSERT_TRUE(response->headers);
3347 EXPECT_TRUE(response->headers->IsKeepAlive());
3348 EXPECT_EQ(407, response->headers->response_code());
3349 EXPECT_EQ(10, response->headers->GetContentLength());
3350 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3351 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3352
3353 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3354 // out of scope.
3355 session->CloseAllConnections();
3356 }
3357}
3358
3359// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3360// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3361// the case the server sends extra data on the original socket, so it can't be
3362// reused.
bncd16676a2016-07-20 16:23:013363TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273364 HttpRequestInfo request;
3365 request.method = "GET";
bncce36dca22015-04-21 22:11:233366 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273367 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293368 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273369
[email protected]2d2697f92009-02-18 21:00:323370 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233371 session_deps_.proxy_service =
3372 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513373 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073374 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093375 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323376
[email protected]2d2697f92009-02-18 21:00:323377 // Since we have proxy, should try to establish tunnel.
3378 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233379 MockWrite(ASYNC, 0,
3380 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173381 "Host: www.example.org:443\r\n"
3382 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233383 };
[email protected]2d2697f92009-02-18 21:00:323384
mmenked39192ee2015-12-09 00:57:233385 // The proxy responds to the connect with a 407, using a persistent, but sends
3386 // extra data, so the socket cannot be reused.
3387 MockRead data_reads1[] = {
3388 // No credentials.
3389 MockRead(ASYNC, 1,
3390 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3391 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3392 "Content-Length: 10\r\n\r\n"),
3393 MockRead(SYNCHRONOUS, 2, "0123456789"),
3394 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3395 };
3396
3397 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233398 // After calling trans->RestartWithAuth(), this is the request we should
3399 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233400 MockWrite(ASYNC, 0,
3401 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173402 "Host: www.example.org:443\r\n"
3403 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233404 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3405
3406 MockWrite(ASYNC, 2,
3407 "GET / HTTP/1.1\r\n"
3408 "Host: www.example.org\r\n"
3409 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323410 };
3411
mmenked39192ee2015-12-09 00:57:233412 MockRead data_reads2[] = {
3413 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323414
mmenked39192ee2015-12-09 00:57:233415 MockRead(ASYNC, 3,
3416 "HTTP/1.1 200 OK\r\n"
3417 "Content-Type: text/html; charset=iso-8859-1\r\n"
3418 "Content-Length: 5\r\n\r\n"),
3419 // No response body because the test stops reading here.
3420 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323421 };
3422
mmenked39192ee2015-12-09 00:57:233423 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3424 arraysize(data_writes1));
3425 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073426 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233427 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3428 arraysize(data_writes2));
3429 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3430 SSLSocketDataProvider ssl(ASYNC, OK);
3431 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323432
[email protected]49639fa2011-12-20 23:22:413433 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323434
bnc691fda62016-08-12 00:43:163435 std::unique_ptr<HttpNetworkTransaction> trans(
mmenked39192ee2015-12-09 00:57:233436 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:323437
mmenked39192ee2015-12-09 00:57:233438 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013439 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233440
mmenke43758e62015-05-04 21:09:463441 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403442 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393443 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003444 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3445 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393446 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403447 entries, pos,
mikecirone8b85c432016-09-08 19:11:003448 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3449 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323450
[email protected]1c773ea12009-04-28 19:58:423451 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243452 ASSERT_TRUE(response);
3453 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323454 EXPECT_TRUE(response->headers->IsKeepAlive());
3455 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423456 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043457 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323458
mmenked39192ee2015-12-09 00:57:233459 LoadTimingInfo load_timing_info;
3460 // CONNECT requests and responses are handled at the connect job level, so
3461 // the transaction does not yet have a connection.
3462 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3463
[email protected]49639fa2011-12-20 23:22:413464 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323465
mmenked39192ee2015-12-09 00:57:233466 rv =
3467 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013468 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323469
[email protected]2d2697f92009-02-18 21:00:323470 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233471 EXPECT_EQ(200, response->headers->response_code());
3472 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423473 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133474
mmenked39192ee2015-12-09 00:57:233475 // The password prompt info should not be set.
3476 EXPECT_FALSE(response->auth_challenge);
3477
3478 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3479 TestLoadTimingNotReusedWithPac(load_timing_info,
3480 CONNECT_TIMING_HAS_SSL_TIMES);
3481
3482 trans.reset();
[email protected]102e27c2011-02-23 01:01:313483 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323484}
3485
mmenkee71e15332015-10-07 16:39:543486// Test the case a proxy closes a socket while the challenge body is being
3487// drained.
bncd16676a2016-07-20 16:23:013488TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543489 HttpRequestInfo request;
3490 request.method = "GET";
3491 request.url = GURL("https://www.example.org/");
3492 // Ensure that proxy authentication is attempted even
3493 // when the no authentication data flag is set.
3494 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3495
3496 // Configure against proxy server "myproxy:70".
3497 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093498 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543499
bnc691fda62016-08-12 00:43:163500 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543501
3502 // Since we have proxy, should try to establish tunnel.
3503 MockWrite data_writes1[] = {
3504 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173505 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543506 "Proxy-Connection: keep-alive\r\n\r\n"),
3507 };
3508
3509 // The proxy responds to the connect with a 407, using a persistent
3510 // connection.
3511 MockRead data_reads1[] = {
3512 // No credentials.
3513 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3514 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3515 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3516 // Server hands up in the middle of the body.
3517 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3518 };
3519
3520 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163521 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543522 // be issuing -- the final header line contains the credentials.
3523 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173524 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543525 "Proxy-Connection: keep-alive\r\n"
3526 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3527
3528 MockWrite("GET / HTTP/1.1\r\n"
3529 "Host: www.example.org\r\n"
3530 "Connection: keep-alive\r\n\r\n"),
3531 };
3532
3533 MockRead data_reads2[] = {
3534 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3535
3536 MockRead("HTTP/1.1 200 OK\r\n"),
3537 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3538 MockRead("Content-Length: 5\r\n\r\n"),
3539 MockRead(SYNCHRONOUS, "hello"),
3540 };
3541
3542 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3543 data_writes1, arraysize(data_writes1));
3544 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3545 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3546 data_writes2, arraysize(data_writes2));
3547 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3548 SSLSocketDataProvider ssl(ASYNC, OK);
3549 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3550
3551 TestCompletionCallback callback;
3552
tfarina42834112016-09-22 13:38:203553 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013554 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543555
bnc691fda62016-08-12 00:43:163556 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543557 ASSERT_TRUE(response);
3558 ASSERT_TRUE(response->headers);
3559 EXPECT_TRUE(response->headers->IsKeepAlive());
3560 EXPECT_EQ(407, response->headers->response_code());
3561 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3562
bnc691fda62016-08-12 00:43:163563 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013564 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543565
bnc691fda62016-08-12 00:43:163566 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543567 ASSERT_TRUE(response);
3568 ASSERT_TRUE(response->headers);
3569 EXPECT_TRUE(response->headers->IsKeepAlive());
3570 EXPECT_EQ(200, response->headers->response_code());
3571 std::string body;
bnc691fda62016-08-12 00:43:163572 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543573 EXPECT_EQ("hello", body);
3574}
3575
[email protected]a8e9b162009-03-12 00:06:443576// Test that we don't read the response body when we fail to establish a tunnel,
3577// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013578TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273579 HttpRequestInfo request;
3580 request.method = "GET";
bncce36dca22015-04-21 22:11:233581 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273582
[email protected]a8e9b162009-03-12 00:06:443583 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033584 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443585
danakj1fd259a02016-04-16 03:17:093586 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443587
bnc691fda62016-08-12 00:43:163588 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443589
[email protected]a8e9b162009-03-12 00:06:443590 // Since we have proxy, should try to establish tunnel.
3591 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173592 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3593 "Host: www.example.org:443\r\n"
3594 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443595 };
3596
3597 // The proxy responds to the connect with a 407.
3598 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243599 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3600 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3601 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233602 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243603 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443604 };
3605
[email protected]31a2bfe2010-02-09 08:03:393606 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3607 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073608 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443609
[email protected]49639fa2011-12-20 23:22:413610 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443611
tfarina42834112016-09-22 13:38:203612 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443614
3615 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013616 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443617
bnc691fda62016-08-12 00:43:163618 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243619 ASSERT_TRUE(response);
3620 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443621 EXPECT_TRUE(response->headers->IsKeepAlive());
3622 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423623 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443624
3625 std::string response_data;
bnc691fda62016-08-12 00:43:163626 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013627 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183628
3629 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313630 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443631}
3632
ttuttle7933c112015-01-06 00:55:243633// Test that we don't pass extraneous headers from the proxy's response to the
3634// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013635TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243636 HttpRequestInfo request;
3637 request.method = "GET";
bncce36dca22015-04-21 22:11:233638 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243639
3640 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033641 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243642
danakj1fd259a02016-04-16 03:17:093643 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243644
bnc691fda62016-08-12 00:43:163645 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243646
3647 // Since we have proxy, should try to establish tunnel.
3648 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173649 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3650 "Host: www.example.org:443\r\n"
3651 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243652 };
3653
3654 // The proxy responds to the connect with a 407.
3655 MockRead data_reads[] = {
3656 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3657 MockRead("X-Foo: bar\r\n"),
3658 MockRead("Set-Cookie: foo=bar\r\n"),
3659 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3660 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233661 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243662 };
3663
3664 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3665 arraysize(data_writes));
3666 session_deps_.socket_factory->AddSocketDataProvider(&data);
3667
3668 TestCompletionCallback callback;
3669
tfarina42834112016-09-22 13:38:203670 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013671 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243672
3673 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013674 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243675
bnc691fda62016-08-12 00:43:163676 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243677 ASSERT_TRUE(response);
3678 ASSERT_TRUE(response->headers);
3679 EXPECT_TRUE(response->headers->IsKeepAlive());
3680 EXPECT_EQ(407, response->headers->response_code());
3681 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3682 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3683 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3684
3685 std::string response_data;
bnc691fda62016-08-12 00:43:163686 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013687 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243688
3689 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3690 session->CloseAllConnections();
3691}
3692
[email protected]8fdbcd22010-05-05 02:54:523693// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3694// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013695TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523696 HttpRequestInfo request;
3697 request.method = "GET";
bncce36dca22015-04-21 22:11:233698 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523699
[email protected]cb9bf6ca2011-01-28 13:15:273700 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093701 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163702 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273703
[email protected]8fdbcd22010-05-05 02:54:523704 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233705 MockWrite(
3706 "GET / HTTP/1.1\r\n"
3707 "Host: www.example.org\r\n"
3708 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523709 };
3710
3711 MockRead data_reads1[] = {
3712 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3713 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3714 // Large content-length -- won't matter, as connection will be reset.
3715 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063716 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523717 };
3718
3719 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3720 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073721 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523722
[email protected]49639fa2011-12-20 23:22:413723 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523724
tfarina42834112016-09-22 13:38:203725 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013726 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523727
3728 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013729 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523730}
3731
[email protected]7a67a8152010-11-05 18:31:103732// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3733// through a non-authenticating proxy. The request should fail with
3734// ERR_UNEXPECTED_PROXY_AUTH.
3735// Note that it is impossible to detect if an HTTP server returns a 407 through
3736// a non-authenticating proxy - there is nothing to indicate whether the
3737// response came from the proxy or the server, so it is treated as if the proxy
3738// issued the challenge.
bncd16676a2016-07-20 16:23:013739TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273740 HttpRequestInfo request;
3741 request.method = "GET";
bncce36dca22015-04-21 22:11:233742 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273743
rdsmith82957ad2015-09-16 19:42:033744 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513745 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073746 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093747 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103748
[email protected]7a67a8152010-11-05 18:31:103749 // Since we have proxy, should try to establish tunnel.
3750 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173751 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3752 "Host: www.example.org:443\r\n"
3753 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103754
rsleevidb16bb02015-11-12 23:47:173755 MockWrite("GET / HTTP/1.1\r\n"
3756 "Host: www.example.org\r\n"
3757 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103758 };
3759
3760 MockRead data_reads1[] = {
3761 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3762
3763 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3764 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3765 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063766 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103767 };
3768
3769 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3770 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073771 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063772 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103774
[email protected]49639fa2011-12-20 23:22:413775 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103776
bnc691fda62016-08-12 00:43:163777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103778
bnc691fda62016-08-12 00:43:163779 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103781
3782 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013783 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463784 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403785 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103786 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003787 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3788 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103789 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403790 entries, pos,
mikecirone8b85c432016-09-08 19:11:003791 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3792 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103793}
[email protected]2df19bb2010-08-25 20:13:463794
mmenke2a1781d2015-10-07 19:25:333795// Test a proxy auth scheme that allows default credentials and a proxy server
3796// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013797TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333798 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3799 HttpRequestInfo request;
3800 request.method = "GET";
3801 request.url = GURL("https://www.example.org/");
3802
3803 // Configure against proxy server "myproxy:70".
3804 session_deps_.proxy_service =
3805 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3806
danakj1fd259a02016-04-16 03:17:093807 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333808 new HttpAuthHandlerMock::Factory());
3809 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093810 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333811 mock_handler->set_allows_default_credentials(true);
3812 auth_handler_factory->AddMockHandler(mock_handler.release(),
3813 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483814 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333815
3816 // Add NetLog just so can verify load timing information gets a NetLog ID.
3817 NetLog net_log;
3818 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093819 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333820
3821 // Since we have proxy, should try to establish tunnel.
3822 MockWrite data_writes1[] = {
3823 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173824 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333825 "Proxy-Connection: keep-alive\r\n\r\n"),
3826 };
3827
3828 // The proxy responds to the connect with a 407, using a non-persistent
3829 // connection.
3830 MockRead data_reads1[] = {
3831 // No credentials.
3832 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3833 MockRead("Proxy-Authenticate: Mock\r\n"),
3834 MockRead("Proxy-Connection: close\r\n\r\n"),
3835 };
3836
3837 // Since the first connection couldn't be reused, need to establish another
3838 // once given credentials.
3839 MockWrite data_writes2[] = {
3840 // After calling trans->RestartWithAuth(), this is the request we should
3841 // be issuing -- the final header line contains the credentials.
3842 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173843 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333844 "Proxy-Connection: keep-alive\r\n"
3845 "Proxy-Authorization: auth_token\r\n\r\n"),
3846
3847 MockWrite("GET / HTTP/1.1\r\n"
3848 "Host: www.example.org\r\n"
3849 "Connection: keep-alive\r\n\r\n"),
3850 };
3851
3852 MockRead data_reads2[] = {
3853 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3854
3855 MockRead("HTTP/1.1 200 OK\r\n"),
3856 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3857 MockRead("Content-Length: 5\r\n\r\n"),
3858 MockRead(SYNCHRONOUS, "hello"),
3859 };
3860
3861 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3862 data_writes1, arraysize(data_writes1));
3863 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3864 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3865 data_writes2, arraysize(data_writes2));
3866 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3867 SSLSocketDataProvider ssl(ASYNC, OK);
3868 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3869
bnc691fda62016-08-12 00:43:163870 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333871 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3872
3873 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203874 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013875 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333876
3877 const HttpResponseInfo* response = trans->GetResponseInfo();
3878 ASSERT_TRUE(response);
3879 ASSERT_TRUE(response->headers);
3880 EXPECT_FALSE(response->headers->IsKeepAlive());
3881 EXPECT_EQ(407, response->headers->response_code());
3882 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3883 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523884 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333885
3886 LoadTimingInfo load_timing_info;
3887 // CONNECT requests and responses are handled at the connect job level, so
3888 // the transaction does not yet have a connection.
3889 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3890
3891 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013892 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333893 response = trans->GetResponseInfo();
3894 ASSERT_TRUE(response);
3895 ASSERT_TRUE(response->headers);
3896 EXPECT_TRUE(response->headers->IsKeepAlive());
3897 EXPECT_EQ(200, response->headers->response_code());
3898 EXPECT_EQ(5, response->headers->GetContentLength());
3899 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3900
3901 // The password prompt info should not be set.
3902 EXPECT_FALSE(response->auth_challenge);
3903
3904 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3905 TestLoadTimingNotReusedWithPac(load_timing_info,
3906 CONNECT_TIMING_HAS_SSL_TIMES);
3907
3908 trans.reset();
3909 session->CloseAllConnections();
3910}
3911
3912// Test a proxy auth scheme that allows default credentials and a proxy server
3913// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:013914TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333915 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3916 HttpRequestInfo request;
3917 request.method = "GET";
3918 request.url = GURL("https://www.example.org/");
3919
3920 // Configure against proxy server "myproxy:70".
3921 session_deps_.proxy_service =
3922 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3923
danakj1fd259a02016-04-16 03:17:093924 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333925 new HttpAuthHandlerMock::Factory());
3926 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093927 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333928 mock_handler->set_allows_default_credentials(true);
3929 auth_handler_factory->AddMockHandler(mock_handler.release(),
3930 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483931 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333932
3933 // Add NetLog just so can verify load timing information gets a NetLog ID.
3934 NetLog net_log;
3935 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093936 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333937
3938 // Should try to establish tunnel.
3939 MockWrite data_writes1[] = {
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\r\n"),
3943
3944 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173945 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333946 "Proxy-Connection: keep-alive\r\n"
3947 "Proxy-Authorization: auth_token\r\n\r\n"),
3948 };
3949
3950 // The proxy responds to the connect with a 407, using a non-persistent
3951 // connection.
3952 MockRead data_reads1[] = {
3953 // No credentials.
3954 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3955 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3956 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3957 };
3958
3959 // Since the first connection was closed, need to establish another once given
3960 // credentials.
3961 MockWrite data_writes2[] = {
3962 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173963 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333964 "Proxy-Connection: keep-alive\r\n"
3965 "Proxy-Authorization: auth_token\r\n\r\n"),
3966
3967 MockWrite("GET / HTTP/1.1\r\n"
3968 "Host: www.example.org\r\n"
3969 "Connection: keep-alive\r\n\r\n"),
3970 };
3971
3972 MockRead data_reads2[] = {
3973 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3974
3975 MockRead("HTTP/1.1 200 OK\r\n"),
3976 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3977 MockRead("Content-Length: 5\r\n\r\n"),
3978 MockRead(SYNCHRONOUS, "hello"),
3979 };
3980
3981 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3982 data_writes1, arraysize(data_writes1));
3983 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3984 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3985 data_writes2, arraysize(data_writes2));
3986 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3987 SSLSocketDataProvider ssl(ASYNC, OK);
3988 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3989
bnc691fda62016-08-12 00:43:163990 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333991 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3992
3993 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203994 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013995 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333996
3997 const HttpResponseInfo* response = trans->GetResponseInfo();
3998 ASSERT_TRUE(response);
3999 ASSERT_TRUE(response->headers);
4000 EXPECT_TRUE(response->headers->IsKeepAlive());
4001 EXPECT_EQ(407, response->headers->response_code());
4002 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4003 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4004 EXPECT_FALSE(response->auth_challenge);
4005
4006 LoadTimingInfo load_timing_info;
4007 // CONNECT requests and responses are handled at the connect job level, so
4008 // the transaction does not yet have a connection.
4009 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4010
4011 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014012 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334013
4014 response = trans->GetResponseInfo();
4015 ASSERT_TRUE(response);
4016 ASSERT_TRUE(response->headers);
4017 EXPECT_TRUE(response->headers->IsKeepAlive());
4018 EXPECT_EQ(200, response->headers->response_code());
4019 EXPECT_EQ(5, response->headers->GetContentLength());
4020 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4021
4022 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524023 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334024
4025 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4026 TestLoadTimingNotReusedWithPac(load_timing_info,
4027 CONNECT_TIMING_HAS_SSL_TIMES);
4028
4029 trans.reset();
4030 session->CloseAllConnections();
4031}
4032
4033// Test a proxy auth scheme that allows default credentials and a proxy server
4034// that hangs up when credentials are initially sent, and hangs up again when
4035// they are retried.
bncd16676a2016-07-20 16:23:014036TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334037 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4038 HttpRequestInfo request;
4039 request.method = "GET";
4040 request.url = GURL("https://www.example.org/");
4041
4042 // Configure against proxy server "myproxy:70".
4043 session_deps_.proxy_service =
4044 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4045
danakj1fd259a02016-04-16 03:17:094046 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334047 new HttpAuthHandlerMock::Factory());
4048 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094049 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334050 mock_handler->set_allows_default_credentials(true);
4051 auth_handler_factory->AddMockHandler(mock_handler.release(),
4052 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484053 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334054
4055 // Add NetLog just so can verify load timing information gets a NetLog ID.
4056 NetLog net_log;
4057 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094058 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334059
4060 // Should try to establish tunnel.
4061 MockWrite data_writes1[] = {
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\r\n"),
4065
4066 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174067 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334068 "Proxy-Connection: keep-alive\r\n"
4069 "Proxy-Authorization: auth_token\r\n\r\n"),
4070 };
4071
4072 // The proxy responds to the connect with a 407, and then hangs up after the
4073 // second request is sent.
4074 MockRead data_reads1[] = {
4075 // No credentials.
4076 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4077 MockRead("Content-Length: 0\r\n"),
4078 MockRead("Proxy-Connection: keep-alive\r\n"),
4079 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4080 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4081 };
4082
4083 // HttpNetworkTransaction sees a reused connection that was closed with
4084 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4085 // request.
4086 MockWrite data_writes2[] = {
4087 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174088 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334089 "Proxy-Connection: keep-alive\r\n\r\n"),
4090 };
4091
4092 // The proxy, having had more than enough of us, just hangs up.
4093 MockRead data_reads2[] = {
4094 // No credentials.
4095 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4096 };
4097
4098 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4099 data_writes1, arraysize(data_writes1));
4100 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4101 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4102 data_writes2, arraysize(data_writes2));
4103 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4104
bnc691fda62016-08-12 00:43:164105 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334106 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4107
4108 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204109 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014110 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334111
4112 const HttpResponseInfo* response = trans->GetResponseInfo();
4113 ASSERT_TRUE(response);
4114 ASSERT_TRUE(response->headers);
4115 EXPECT_TRUE(response->headers->IsKeepAlive());
4116 EXPECT_EQ(407, response->headers->response_code());
4117 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4118 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4119 EXPECT_FALSE(response->auth_challenge);
4120
4121 LoadTimingInfo load_timing_info;
4122 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4123
4124 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014125 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334126
4127 trans.reset();
4128 session->CloseAllConnections();
4129}
4130
4131// Test a proxy auth scheme that allows default credentials and a proxy server
4132// that hangs up when credentials are initially sent, and sends a challenge
4133// again they are retried.
bncd16676a2016-07-20 16:23:014134TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334135 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4136 HttpRequestInfo request;
4137 request.method = "GET";
4138 request.url = GURL("https://www.example.org/");
4139
4140 // Configure against proxy server "myproxy:70".
4141 session_deps_.proxy_service =
4142 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4143
danakj1fd259a02016-04-16 03:17:094144 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334145 new HttpAuthHandlerMock::Factory());
4146 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094147 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334148 mock_handler->set_allows_default_credentials(true);
4149 auth_handler_factory->AddMockHandler(mock_handler.release(),
4150 HttpAuth::AUTH_PROXY);
4151 // Add another handler for the second challenge. It supports default
4152 // credentials, but they shouldn't be used, since they were already tried.
4153 mock_handler.reset(new HttpAuthHandlerMock());
4154 mock_handler->set_allows_default_credentials(true);
4155 auth_handler_factory->AddMockHandler(mock_handler.release(),
4156 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484157 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334158
4159 // Add NetLog just so can verify load timing information gets a NetLog ID.
4160 NetLog net_log;
4161 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094162 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334163
4164 // Should try to establish tunnel.
4165 MockWrite data_writes1[] = {
4166 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174167 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334168 "Proxy-Connection: keep-alive\r\n\r\n"),
4169 };
4170
4171 // The proxy responds to the connect with a 407, using a non-persistent
4172 // connection.
4173 MockRead data_reads1[] = {
4174 // No credentials.
4175 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4176 MockRead("Proxy-Authenticate: Mock\r\n"),
4177 MockRead("Proxy-Connection: close\r\n\r\n"),
4178 };
4179
4180 // Since the first connection was closed, need to establish another once given
4181 // credentials.
4182 MockWrite data_writes2[] = {
4183 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174184 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334185 "Proxy-Connection: keep-alive\r\n"
4186 "Proxy-Authorization: auth_token\r\n\r\n"),
4187 };
4188
4189 MockRead data_reads2[] = {
4190 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4191 MockRead("Proxy-Authenticate: Mock\r\n"),
4192 MockRead("Proxy-Connection: close\r\n\r\n"),
4193 };
4194
4195 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4196 data_writes1, arraysize(data_writes1));
4197 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4198 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4199 data_writes2, arraysize(data_writes2));
4200 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4201 SSLSocketDataProvider ssl(ASYNC, OK);
4202 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4203
bnc691fda62016-08-12 00:43:164204 std::unique_ptr<HttpNetworkTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334205 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4206
4207 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204208 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014209 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334210
4211 const HttpResponseInfo* response = trans->GetResponseInfo();
4212 ASSERT_TRUE(response);
4213 ASSERT_TRUE(response->headers);
4214 EXPECT_EQ(407, response->headers->response_code());
4215 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4216 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4217 EXPECT_FALSE(response->auth_challenge);
4218
4219 LoadTimingInfo load_timing_info;
4220 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4221
4222 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014223 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334224 response = trans->GetResponseInfo();
4225 ASSERT_TRUE(response);
4226 ASSERT_TRUE(response->headers);
4227 EXPECT_EQ(407, response->headers->response_code());
4228 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4229 EXPECT_TRUE(response->auth_challenge);
4230
4231 trans.reset();
4232 session->CloseAllConnections();
4233}
4234
asankae2257db2016-10-11 22:03:164235// A more nuanced test than GenerateAuthToken test which asserts that
4236// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4237// unnecessarily invalidated, and that if the server co-operates, the
4238// authentication handshake can continue with the same scheme but with a
4239// different identity.
4240TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4241 HttpRequestInfo request;
4242 request.method = "GET";
4243 request.url = GURL("http://www.example.org/");
4244
4245 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
4246 new HttpAuthHandlerMock::Factory());
4247 auth_handler_factory->set_do_init_from_challenge(true);
4248
4249 // First handler. Uses default credentials, but barfs at generate auth token.
4250 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
4251 mock_handler->set_allows_default_credentials(true);
4252 mock_handler->set_allows_explicit_credentials(true);
4253 mock_handler->set_connection_based(true);
4254 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4255 auth_handler_factory->AddMockHandler(mock_handler.release(),
4256 HttpAuth::AUTH_SERVER);
4257
4258 // Add another handler for the second challenge. It supports default
4259 // credentials, but they shouldn't be used, since they were already tried.
4260 mock_handler.reset(new HttpAuthHandlerMock());
4261 mock_handler->set_allows_default_credentials(true);
4262 mock_handler->set_allows_explicit_credentials(true);
4263 mock_handler->set_connection_based(true);
4264 auth_handler_factory->AddMockHandler(mock_handler.release(),
4265 HttpAuth::AUTH_SERVER);
4266 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4267
4268 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4269
4270 MockWrite data_writes1[] = {
4271 MockWrite("GET / HTTP/1.1\r\n"
4272 "Host: www.example.org\r\n"
4273 "Connection: keep-alive\r\n\r\n"),
4274 };
4275
4276 MockRead data_reads1[] = {
4277 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4278 "WWW-Authenticate: Mock\r\n"
4279 "Connection: keep-alive\r\n\r\n"),
4280 };
4281
4282 // Identical to data_writes1[]. The AuthHandler encounters a
4283 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4284 // transaction procceds without an authorization header.
4285 MockWrite data_writes2[] = {
4286 MockWrite("GET / HTTP/1.1\r\n"
4287 "Host: www.example.org\r\n"
4288 "Connection: keep-alive\r\n\r\n"),
4289 };
4290
4291 MockRead data_reads2[] = {
4292 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4293 "WWW-Authenticate: Mock\r\n"
4294 "Connection: keep-alive\r\n\r\n"),
4295 };
4296
4297 MockWrite data_writes3[] = {
4298 MockWrite("GET / HTTP/1.1\r\n"
4299 "Host: www.example.org\r\n"
4300 "Connection: keep-alive\r\n"
4301 "Authorization: auth_token\r\n\r\n"),
4302 };
4303
4304 MockRead data_reads3[] = {
4305 MockRead("HTTP/1.1 200 OK\r\n"
4306 "Content-Length: 5\r\n"
4307 "Content-Type: text/plain\r\n"
4308 "Connection: keep-alive\r\n\r\n"
4309 "Hello"),
4310 };
4311
4312 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4313 data_writes1, arraysize(data_writes1));
4314 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4315
4316 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4317 data_writes2, arraysize(data_writes2));
4318 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4319
4320 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4321 data_writes3, arraysize(data_writes3));
4322 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4323
4324 std::unique_ptr<HttpNetworkTransaction> trans(
4325 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4326
4327 TestCompletionCallback callback;
4328 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4329 EXPECT_THAT(callback.GetResult(rv), IsOk());
4330
4331 const HttpResponseInfo* response = trans->GetResponseInfo();
4332 ASSERT_TRUE(response);
4333 ASSERT_TRUE(response->headers);
4334 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4335
4336 // The following three tests assert that an authentication challenge was
4337 // received and that the stack is ready to respond to the challenge using
4338 // ambient credentials.
4339 EXPECT_EQ(401, response->headers->response_code());
4340 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4341 EXPECT_FALSE(response->auth_challenge);
4342
4343 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4344 EXPECT_THAT(callback.GetResult(rv), IsOk());
4345 response = trans->GetResponseInfo();
4346 ASSERT_TRUE(response);
4347 ASSERT_TRUE(response->headers);
4348
4349 // The following three tests assert that an authentication challenge was
4350 // received and that the stack needs explicit credentials before it is ready
4351 // to respond to the challenge.
4352 EXPECT_EQ(401, response->headers->response_code());
4353 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4354 EXPECT_TRUE(response->auth_challenge);
4355
4356 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4357 EXPECT_THAT(callback.GetResult(rv), IsOk());
4358 response = trans->GetResponseInfo();
4359 ASSERT_TRUE(response);
4360 ASSERT_TRUE(response->headers);
4361 EXPECT_EQ(200, response->headers->response_code());
4362
4363 trans.reset();
4364 session->CloseAllConnections();
4365}
4366
[email protected]029c83b62013-01-24 05:28:204367// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014368TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204369 HttpRequestInfo request1;
4370 request1.method = "GET";
bncce36dca22015-04-21 22:11:234371 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204372
4373 HttpRequestInfo request2;
4374 request2.method = "GET";
bncce36dca22015-04-21 22:11:234375 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204376
4377 // Configure against proxy server "myproxy:70".
brettwc1213d92016-11-12 03:41:134378 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514379 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074380 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094381 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204382
4383 // Since we have proxy, should try to establish tunnel.
4384 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174385 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4386 "Host: www.example.org:443\r\n"
4387 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204388
rsleevidb16bb02015-11-12 23:47:174389 MockWrite("GET /1 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
rsleevidb16bb02015-11-12 23:47:174393 MockWrite("GET /2 HTTP/1.1\r\n"
4394 "Host: www.example.org\r\n"
4395 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204396 };
4397
4398 // The proxy responds to the connect with a 407, using a persistent
4399 // connection.
4400 MockRead data_reads1[] = {
4401 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4402
4403 MockRead("HTTP/1.1 200 OK\r\n"),
4404 MockRead("Content-Length: 1\r\n\r\n"),
4405 MockRead(SYNCHRONOUS, "1"),
4406
4407 MockRead("HTTP/1.1 200 OK\r\n"),
4408 MockRead("Content-Length: 2\r\n\r\n"),
4409 MockRead(SYNCHRONOUS, "22"),
4410 };
4411
4412 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4413 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074414 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204415 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074416 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204417
4418 TestCompletionCallback callback1;
bnc691fda62016-08-12 00:43:164419 std::unique_ptr<HttpNetworkTransaction> trans1(
[email protected]90499482013-06-01 00:39:504420 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204421
4422 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014423 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204424
4425 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014426 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204427
4428 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524429 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474430 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524431 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204432 EXPECT_EQ(1, response1->headers->GetContentLength());
4433
4434 LoadTimingInfo load_timing_info1;
4435 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4436 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4437
4438 trans1.reset();
4439
4440 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:164441 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:504442 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204443
4444 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014445 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204446
4447 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014448 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204449
4450 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524451 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474452 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524453 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204454 EXPECT_EQ(2, response2->headers->GetContentLength());
4455
4456 LoadTimingInfo load_timing_info2;
4457 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4458 TestLoadTimingReused(load_timing_info2);
4459
4460 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4461
4462 trans2.reset();
4463 session->CloseAllConnections();
4464}
4465
4466// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014467TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204468 HttpRequestInfo request1;
4469 request1.method = "GET";
bncce36dca22015-04-21 22:11:234470 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204471
4472 HttpRequestInfo request2;
4473 request2.method = "GET";
bncce36dca22015-04-21 22:11:234474 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204475
4476 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034477 session_deps_.proxy_service =
4478 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514479 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074480 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094481 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204482
4483 // Since we have proxy, should try to establish tunnel.
4484 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174485 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4486 "Host: www.example.org:443\r\n"
4487 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204488
rsleevidb16bb02015-11-12 23:47:174489 MockWrite("GET /1 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
rsleevidb16bb02015-11-12 23:47:174493 MockWrite("GET /2 HTTP/1.1\r\n"
4494 "Host: www.example.org\r\n"
4495 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204496 };
4497
4498 // The proxy responds to the connect with a 407, using a persistent
4499 // connection.
4500 MockRead data_reads1[] = {
4501 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4502
4503 MockRead("HTTP/1.1 200 OK\r\n"),
4504 MockRead("Content-Length: 1\r\n\r\n"),
4505 MockRead(SYNCHRONOUS, "1"),
4506
4507 MockRead("HTTP/1.1 200 OK\r\n"),
4508 MockRead("Content-Length: 2\r\n\r\n"),
4509 MockRead(SYNCHRONOUS, "22"),
4510 };
4511
4512 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4513 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074514 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204515 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074516 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204517
4518 TestCompletionCallback callback1;
bnc691fda62016-08-12 00:43:164519 std::unique_ptr<HttpNetworkTransaction> trans1(
[email protected]90499482013-06-01 00:39:504520 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204521
4522 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014523 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204524
4525 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014526 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204527
4528 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524529 ASSERT_TRUE(response1);
4530 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204531 EXPECT_EQ(1, response1->headers->GetContentLength());
4532
4533 LoadTimingInfo load_timing_info1;
4534 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4535 TestLoadTimingNotReusedWithPac(load_timing_info1,
4536 CONNECT_TIMING_HAS_SSL_TIMES);
4537
4538 trans1.reset();
4539
4540 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:164541 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:504542 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204543
4544 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014545 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204546
4547 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014548 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204549
4550 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524551 ASSERT_TRUE(response2);
4552 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204553 EXPECT_EQ(2, response2->headers->GetContentLength());
4554
4555 LoadTimingInfo load_timing_info2;
4556 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4557 TestLoadTimingReusedWithPac(load_timing_info2);
4558
4559 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4560
4561 trans2.reset();
4562 session->CloseAllConnections();
4563}
4564
[email protected]2df19bb2010-08-25 20:13:464565// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014566TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274567 HttpRequestInfo request;
4568 request.method = "GET";
bncce36dca22015-04-21 22:11:234569 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274570
[email protected]2df19bb2010-08-25 20:13:464571 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034572 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514573 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074574 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094575 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464576
[email protected]2df19bb2010-08-25 20:13:464577 // Since we have proxy, should use full url
4578 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234579 MockWrite(
4580 "GET http://www.example.org/ HTTP/1.1\r\n"
4581 "Host: www.example.org\r\n"
4582 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464583 };
4584
4585 MockRead data_reads1[] = {
4586 MockRead("HTTP/1.1 200 OK\r\n"),
4587 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4588 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064589 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464590 };
4591
4592 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4593 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074594 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064595 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074596 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464597
[email protected]49639fa2011-12-20 23:22:414598 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464599
bnc691fda62016-08-12 00:43:164600 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504601
bnc691fda62016-08-12 00:43:164602 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014603 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464604
4605 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014606 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464607
[email protected]58e32bb2013-01-21 18:23:254608 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164609 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254610 TestLoadTimingNotReused(load_timing_info,
4611 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4612
bnc691fda62016-08-12 00:43:164613 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524614 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464615
tbansal2ecbbc72016-10-06 17:15:474616 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464617 EXPECT_TRUE(response->headers->IsKeepAlive());
4618 EXPECT_EQ(200, response->headers->response_code());
4619 EXPECT_EQ(100, response->headers->GetContentLength());
4620 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4621
4622 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524623 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464624}
4625
[email protected]7642b5ae2010-09-01 20:55:174626// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014627TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274628 HttpRequestInfo request;
4629 request.method = "GET";
bncce36dca22015-04-21 22:11:234630 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274631
[email protected]7642b5ae2010-09-01 20:55:174632 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034633 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514634 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074635 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094636 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174637
bncce36dca22015-04-21 22:11:234638 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414639 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454640 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414641 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174642
bnc42331402016-07-25 13:36:154643 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414644 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174645 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414646 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174647 };
4648
rch8e6c6c42015-05-01 14:05:134649 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4650 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074651 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174652
[email protected]8ddf8322012-02-23 18:08:064653 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364654 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074655 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174656
[email protected]49639fa2011-12-20 23:22:414657 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174658
bnc691fda62016-08-12 00:43:164659 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504660
bnc691fda62016-08-12 00:43:164661 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014662 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:174663
4664 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014665 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:174666
[email protected]58e32bb2013-01-21 18:23:254667 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164668 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254669 TestLoadTimingNotReused(load_timing_info,
4670 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4671
bnc691fda62016-08-12 00:43:164672 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524673 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:474674 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:524675 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024676 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174677
4678 std::string response_data;
bnc691fda62016-08-12 00:43:164679 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234680 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174681}
4682
[email protected]1c173852014-06-19 12:51:504683// Verifies that a session which races and wins against the owning transaction
4684// (completing prior to host resolution), doesn't fail the transaction.
4685// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:014686TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:504687 HttpRequestInfo request;
4688 request.method = "GET";
bncce36dca22015-04-21 22:11:234689 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504690
4691 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034692 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514693 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504694 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094695 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504696
bncce36dca22015-04-21 22:11:234697 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:414698 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454699 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414700 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:504701
bnc42331402016-07-25 13:36:154702 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414703 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:504704 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414705 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504706 };
4707
rch8e6c6c42015-05-01 14:05:134708 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4709 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504710 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4711
4712 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364713 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:504714 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4715
4716 TestCompletionCallback callback1;
4717
bnc691fda62016-08-12 00:43:164718 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:504719
4720 // Stall the hostname resolution begun by the transaction.
4721 session_deps_.host_resolver->set_synchronous_mode(false);
4722 session_deps_.host_resolver->set_ondemand_mode(true);
4723
bnc691fda62016-08-12 00:43:164724 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014725 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:504726
4727 // Race a session to the proxy, which completes first.
4728 session_deps_.host_resolver->set_ondemand_mode(false);
4729 SpdySessionKey key(
4730 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4731 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424732 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504733
4734 // Unstall the resolution begun by the transaction.
4735 session_deps_.host_resolver->set_ondemand_mode(true);
4736 session_deps_.host_resolver->ResolveAllPending();
4737
4738 EXPECT_FALSE(callback1.have_result());
4739 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014740 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:504741
bnc691fda62016-08-12 00:43:164742 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524743 ASSERT_TRUE(response);
4744 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024745 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504746
4747 std::string response_data;
bnc691fda62016-08-12 00:43:164748 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:504749 EXPECT_EQ(kUploadData, response_data);
4750}
4751
[email protected]dc7bd1c52010-11-12 00:01:134752// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014753TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274754 HttpRequestInfo request;
4755 request.method = "GET";
bncce36dca22015-04-21 22:11:234756 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274757
[email protected]79cb5c12011-09-12 13:12:044758 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034759 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514760 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074761 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134763
[email protected]dc7bd1c52010-11-12 00:01:134764 // The first request will be a bare GET, the second request will be a
4765 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:454766 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:414767 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:494768 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384769 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134770 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464771 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134772 };
bncdf80d44fd2016-07-15 20:27:414773 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4774 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
4775 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134776 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414777 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134778 };
4779
4780 // The first response is a 407 proxy authentication challenge, and the second
4781 // response will be a 200 response since the second request includes a valid
4782 // Authorization header.
4783 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464784 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134785 };
bnc42331402016-07-25 13:36:154786 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:234787 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:414788 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4789 SpdySerializedFrame body_authentication(
4790 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:154791 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:414792 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134793 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414794 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:464795 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:414796 CreateMockRead(resp_data, 4),
4797 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:134798 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134799 };
4800
rch8e6c6c42015-05-01 14:05:134801 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4802 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074803 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134804
[email protected]8ddf8322012-02-23 18:08:064805 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364806 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074807 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134808
[email protected]49639fa2011-12-20 23:22:414809 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134810
bnc691fda62016-08-12 00:43:164811 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:134812
bnc691fda62016-08-12 00:43:164813 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134815
4816 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014817 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134818
bnc691fda62016-08-12 00:43:164819 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134820
wezca1070932016-05-26 20:30:524821 ASSERT_TRUE(response);
4822 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134823 EXPECT_EQ(407, response->headers->response_code());
4824 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434825 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134826
[email protected]49639fa2011-12-20 23:22:414827 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134828
bnc691fda62016-08-12 00:43:164829 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:014830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134831
4832 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014833 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134834
bnc691fda62016-08-12 00:43:164835 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134836
wezca1070932016-05-26 20:30:524837 ASSERT_TRUE(response_restart);
4838 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134839 EXPECT_EQ(200, response_restart->headers->response_code());
4840 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524841 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134842}
4843
[email protected]d9da5fe2010-10-13 22:37:164844// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:014845TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274846 HttpRequestInfo request;
4847 request.method = "GET";
bncce36dca22015-04-21 22:11:234848 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274849
[email protected]d9da5fe2010-10-13 22:37:164850 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034851 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514852 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074853 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094854 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164855
bnc691fda62016-08-12 00:43:164856 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164857
bncce36dca22015-04-21 22:11:234858 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414859 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234860 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4861 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164862
bncce36dca22015-04-21 22:11:234863 const char get[] =
4864 "GET / HTTP/1.1\r\n"
4865 "Host: www.example.org\r\n"
4866 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414867 SpdySerializedFrame wrapped_get(
4868 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:154869 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164870 const char resp[] = "HTTP/1.1 200 OK\r\n"
4871 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414872 SpdySerializedFrame wrapped_get_resp(
4873 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
4874 SpdySerializedFrame wrapped_body(
4875 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
4876 SpdySerializedFrame window_update(
4877 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:044878
4879 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414880 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4881 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044882 };
4883
[email protected]d9da5fe2010-10-13 22:37:164884 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414885 CreateMockRead(conn_resp, 1, ASYNC),
4886 CreateMockRead(wrapped_get_resp, 3, ASYNC),
4887 CreateMockRead(wrapped_body, 4, ASYNC),
4888 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134889 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164890 };
4891
rch8e6c6c42015-05-01 14:05:134892 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4893 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074894 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164895
[email protected]8ddf8322012-02-23 18:08:064896 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364897 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074898 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064899 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074900 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164901
[email protected]49639fa2011-12-20 23:22:414902 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164903
bnc691fda62016-08-12 00:43:164904 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014905 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164906
4907 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014908 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164909
[email protected]58e32bb2013-01-21 18:23:254910 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164911 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254912 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4913
bnc691fda62016-08-12 00:43:164914 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524915 ASSERT_TRUE(response);
4916 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:164917 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4918
4919 std::string response_data;
bnc691fda62016-08-12 00:43:164920 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:164921 EXPECT_EQ("1234567890", response_data);
4922}
4923
4924// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:014925TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
4926 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:384927
[email protected]cb9bf6ca2011-01-28 13:15:274928 HttpRequestInfo request;
4929 request.method = "GET";
bncce36dca22015-04-21 22:11:234930 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274931
[email protected]d9da5fe2010-10-13 22:37:164932 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034933 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514934 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074935 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094936 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164937
bnc691fda62016-08-12 00:43:164938 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164939
bncce36dca22015-04-21 22:11:234940 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414941 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234942 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4943 // fetch https://www.example.org/ via SPDY
4944 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:414945 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:494946 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414947 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:154948 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414949 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:154950 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414951 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024952 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:414953 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
4954 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:024955 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:414956 SpdySerializedFrame window_update_get_resp(
4957 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
4958 SpdySerializedFrame window_update_body(
4959 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:044960
4961 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414962 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4963 CreateMockWrite(window_update_get_resp, 6),
4964 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:044965 };
4966
[email protected]d9da5fe2010-10-13 22:37:164967 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414968 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:094969 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:414970 CreateMockRead(wrapped_get_resp, 4, ASYNC),
4971 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134972 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164973 };
4974
rch32320842015-05-16 15:57:094975 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4976 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074977 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164978
[email protected]8ddf8322012-02-23 18:08:064979 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364980 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074981 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064982 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364983 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074984 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164985
[email protected]49639fa2011-12-20 23:22:414986 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164987
bnc691fda62016-08-12 00:43:164988 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014989 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:164990
rch32320842015-05-16 15:57:094991 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:554992 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:094993 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:594994 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:164995 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014996 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:164997
[email protected]58e32bb2013-01-21 18:23:254998 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164999 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255000 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5001
bnc691fda62016-08-12 00:43:165002 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525003 ASSERT_TRUE(response);
5004 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025005 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165006
5007 std::string response_data;
bnc691fda62016-08-12 00:43:165008 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235009 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165010}
5011
5012// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015013TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275014 HttpRequestInfo request;
5015 request.method = "GET";
bncce36dca22015-04-21 22:11:235016 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275017
[email protected]d9da5fe2010-10-13 22:37:165018 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035019 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515020 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075021 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095022 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165023
bnc691fda62016-08-12 00:43:165024 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165025
bncce36dca22015-04-21 22:11:235026 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415027 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235028 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415029 SpdySerializedFrame get(
[email protected]c10b20852013-05-15 21:29:205030 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165031
5032 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415033 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165034 };
5035
bnc42331402016-07-25 13:36:155036 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415037 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165038 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415039 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165040 };
5041
rch8e6c6c42015-05-01 14:05:135042 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5043 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075044 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165045
[email protected]8ddf8322012-02-23 18:08:065046 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365047 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075048 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065049 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365050 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075051 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165052
[email protected]49639fa2011-12-20 23:22:415053 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165054
bnc691fda62016-08-12 00:43:165055 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015056 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165057
5058 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015059 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165060
ttuttle960fcbf2016-04-19 13:26:325061 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165062}
5063
[email protected]f6c63db52013-02-02 00:35:225064// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5065// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015066TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225067 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5068 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035069 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515070 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075071 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095072 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505073 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225074
5075 HttpRequestInfo request1;
5076 request1.method = "GET";
bncce36dca22015-04-21 22:11:235077 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225078 request1.load_flags = 0;
5079
5080 HttpRequestInfo request2;
5081 request2.method = "GET";
bncce36dca22015-04-21 22:11:235082 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225083 request2.load_flags = 0;
5084
bncce36dca22015-04-21 22:11:235085 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415086 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235087 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155088 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225089
bncce36dca22015-04-21 22:11:235090 // Fetch https://www.example.org/ via HTTP.
5091 const char get1[] =
5092 "GET / HTTP/1.1\r\n"
5093 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225094 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415095 SpdySerializedFrame wrapped_get1(
5096 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225097 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5098 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415099 SpdySerializedFrame wrapped_get_resp1(
5100 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5101 SpdySerializedFrame wrapped_body1(
5102 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5103 SpdySerializedFrame window_update(
5104 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225105
bncce36dca22015-04-21 22:11:235106 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295107 SpdyHeaderBlock connect2_block;
5108 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnca9b9e222016-07-11 20:10:405109 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155110 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5111 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395112
bnc42331402016-07-25 13:36:155113 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225114
bncce36dca22015-04-21 22:11:235115 // Fetch https://mail.example.org/ via HTTP.
5116 const char get2[] =
5117 "GET / HTTP/1.1\r\n"
5118 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225119 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415120 SpdySerializedFrame wrapped_get2(
5121 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225122 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5123 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415124 SpdySerializedFrame wrapped_get_resp2(
5125 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5126 SpdySerializedFrame wrapped_body2(
5127 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225128
5129 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415130 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5131 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225132 };
5133
5134 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415135 CreateMockRead(conn_resp1, 1, ASYNC),
5136 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5137 CreateMockRead(wrapped_body1, 4, ASYNC),
5138 CreateMockRead(conn_resp2, 6, ASYNC),
5139 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5140 CreateMockRead(wrapped_body2, 9, ASYNC),
5141 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225142 };
5143
mmenke11eb5152015-06-09 14:50:505144 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5145 arraysize(spdy_writes));
5146 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225147
5148 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365149 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505150 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225151 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505152 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225153 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505154 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225155
5156 TestCompletionCallback callback;
5157
bnc691fda62016-08-12 00:43:165158 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205159 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015160 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225161
5162 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165163 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225164 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5165
bnc691fda62016-08-12 00:43:165166 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525167 ASSERT_TRUE(response);
5168 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225169 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5170
5171 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295172 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165173 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505174 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225175
bnc691fda62016-08-12 00:43:165176 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205177 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015178 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225179
5180 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165181 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225182 // Even though the SPDY connection is reused, a new tunnelled connection has
5183 // to be created, so the socket's load timing looks like a fresh connection.
5184 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5185
5186 // The requests should have different IDs, since they each are using their own
5187 // separate stream.
5188 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5189
bnc691fda62016-08-12 00:43:165190 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505191 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225192}
5193
5194// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5195// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015196TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225197 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5198 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035199 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515200 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075201 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095202 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505203 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225204
5205 HttpRequestInfo request1;
5206 request1.method = "GET";
bncce36dca22015-04-21 22:11:235207 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225208 request1.load_flags = 0;
5209
5210 HttpRequestInfo request2;
5211 request2.method = "GET";
bncce36dca22015-04-21 22:11:235212 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225213 request2.load_flags = 0;
5214
bncce36dca22015-04-21 22:11:235215 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415216 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235217 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155218 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225219
bncce36dca22015-04-21 22:11:235220 // Fetch https://www.example.org/ via HTTP.
5221 const char get1[] =
5222 "GET / HTTP/1.1\r\n"
5223 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225224 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415225 SpdySerializedFrame wrapped_get1(
5226 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225227 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5228 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415229 SpdySerializedFrame wrapped_get_resp1(
5230 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5231 SpdySerializedFrame wrapped_body1(
5232 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5233 SpdySerializedFrame window_update(
5234 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225235
bncce36dca22015-04-21 22:11:235236 // Fetch https://www.example.org/2 via HTTP.
5237 const char get2[] =
5238 "GET /2 HTTP/1.1\r\n"
5239 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225240 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415241 SpdySerializedFrame wrapped_get2(
5242 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225243 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5244 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415245 SpdySerializedFrame wrapped_get_resp2(
5246 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5247 SpdySerializedFrame wrapped_body2(
5248 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225249
5250 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415251 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5252 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225253 };
5254
5255 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415256 CreateMockRead(conn_resp1, 1, ASYNC),
5257 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465258 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415259 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465260 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415261 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225262 };
5263
mmenke11eb5152015-06-09 14:50:505264 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5265 arraysize(spdy_writes));
5266 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225267
5268 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365269 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505270 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225271 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505272 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225273
5274 TestCompletionCallback callback;
5275
bnc691fda62016-08-12 00:43:165276 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:505277 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:205278 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015279 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225280
5281 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015282 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225283
5284 LoadTimingInfo load_timing_info;
5285 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5286 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5287
5288 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525289 ASSERT_TRUE(response);
5290 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225291 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5292
5293 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295294 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505295 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225296 trans.reset();
5297
bnc691fda62016-08-12 00:43:165298 std::unique_ptr<HttpNetworkTransaction> trans2(
[email protected]90499482013-06-01 00:39:505299 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:205300 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015301 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225302
[email protected]f6c63db52013-02-02 00:35:225303 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015304 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225305
5306 LoadTimingInfo load_timing_info2;
5307 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5308 TestLoadTimingReused(load_timing_info2);
5309
5310 // The requests should have the same ID.
5311 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5312
[email protected]90499482013-06-01 00:39:505313 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225314}
5315
5316// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5317// Proxy to different servers.
bncd16676a2016-07-20 16:23:015318TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225319 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035320 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515321 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075322 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095323 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505324 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225325
5326 HttpRequestInfo request1;
5327 request1.method = "GET";
bncce36dca22015-04-21 22:11:235328 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225329 request1.load_flags = 0;
5330
5331 HttpRequestInfo request2;
5332 request2.method = "GET";
bncce36dca22015-04-21 22:11:235333 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225334 request2.load_flags = 0;
5335
bncce36dca22015-04-21 22:11:235336 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265337 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235338 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415339 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155340 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5341 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415342 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385343 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225344
bncce36dca22015-04-21 22:11:235345 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265346 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235347 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415348 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155349 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5350 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415351 SpdySerializedFrame body2(
5352 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225353
5354 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415355 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225356 };
5357
5358 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415359 CreateMockRead(get_resp1, 1, ASYNC),
5360 CreateMockRead(body1, 2, ASYNC),
5361 CreateMockRead(get_resp2, 4, ASYNC),
5362 CreateMockRead(body2, 5, ASYNC),
5363 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225364 };
5365
mmenke11eb5152015-06-09 14:50:505366 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5367 arraysize(spdy_writes));
5368 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225369
5370 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365371 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225373
5374 TestCompletionCallback callback;
5375
bnc691fda62016-08-12 00:43:165376 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:505377 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:205378 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015379 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225380
5381 LoadTimingInfo load_timing_info;
5382 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5383 TestLoadTimingNotReused(load_timing_info,
5384 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5385
5386 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525387 ASSERT_TRUE(response);
5388 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025389 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225390
5391 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295392 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505393 rv = trans->Read(buf.get(), 256, callback.callback());
5394 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225395 // Delete the first request, so the second one can reuse the socket.
5396 trans.reset();
5397
bnc691fda62016-08-12 00:43:165398 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205399 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015400 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225401
5402 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165403 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225404 TestLoadTimingReused(load_timing_info2);
5405
5406 // The requests should have the same ID.
5407 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5408
bnc691fda62016-08-12 00:43:165409 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505410 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225411}
5412
[email protected]2df19bb2010-08-25 20:13:465413// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015414TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465415 HttpRequestInfo request;
5416 request.method = "GET";
bncce36dca22015-04-21 22:11:235417 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465418 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295419 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465420
[email protected]79cb5c12011-09-12 13:12:045421 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035422 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515423 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075424 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095425 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275426
[email protected]2df19bb2010-08-25 20:13:465427 // Since we have proxy, should use full url
5428 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165429 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5430 "Host: www.example.org\r\n"
5431 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465432
bnc691fda62016-08-12 00:43:165433 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235434 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165435 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5436 "Host: www.example.org\r\n"
5437 "Proxy-Connection: keep-alive\r\n"
5438 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465439 };
5440
5441 // The proxy responds to the GET with a 407, using a persistent
5442 // connection.
5443 MockRead data_reads1[] = {
5444 // No credentials.
5445 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5446 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5447 MockRead("Proxy-Connection: keep-alive\r\n"),
5448 MockRead("Content-Length: 0\r\n\r\n"),
5449
5450 MockRead("HTTP/1.1 200 OK\r\n"),
5451 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5452 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065453 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465454 };
5455
5456 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5457 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075458 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065459 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075460 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465461
[email protected]49639fa2011-12-20 23:22:415462 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465463
bnc691fda62016-08-12 00:43:165464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505465
bnc691fda62016-08-12 00:43:165466 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465468
5469 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015470 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465471
[email protected]58e32bb2013-01-21 18:23:255472 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165473 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255474 TestLoadTimingNotReused(load_timing_info,
5475 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5476
bnc691fda62016-08-12 00:43:165477 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525478 ASSERT_TRUE(response);
5479 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465480 EXPECT_EQ(407, response->headers->response_code());
5481 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435482 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465483
[email protected]49639fa2011-12-20 23:22:415484 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465485
bnc691fda62016-08-12 00:43:165486 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015487 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465488
5489 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015490 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465491
[email protected]58e32bb2013-01-21 18:23:255492 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165493 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255494 // Retrying with HTTP AUTH is considered to be reusing a socket.
5495 TestLoadTimingReused(load_timing_info);
5496
bnc691fda62016-08-12 00:43:165497 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525498 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465499
5500 EXPECT_TRUE(response->headers->IsKeepAlive());
5501 EXPECT_EQ(200, response->headers->response_code());
5502 EXPECT_EQ(100, response->headers->GetContentLength());
5503 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5504
5505 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525506 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465507}
5508
[email protected]23e482282013-06-14 16:08:025509void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085510 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425511 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085512 request.method = "GET";
bncce36dca22015-04-21 22:11:235513 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085514
[email protected]cb9bf6ca2011-01-28 13:15:275515 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035516 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095517 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275518
[email protected]c744cf22009-02-27 07:28:085519 // Since we have proxy, should try to establish tunnel.
5520 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175521 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5522 "Host: www.example.org:443\r\n"
5523 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085524 };
5525
5526 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235527 status, MockRead("Content-Length: 10\r\n\r\n"),
5528 // No response body because the test stops reading here.
5529 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085530 };
5531
[email protected]31a2bfe2010-02-09 08:03:395532 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5533 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075534 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085535
[email protected]49639fa2011-12-20 23:22:415536 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085537
bnc691fda62016-08-12 00:43:165538 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505539
tfarina42834112016-09-22 13:38:205540 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015541 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085542
5543 rv = callback.WaitForResult();
5544 EXPECT_EQ(expected_status, rv);
5545}
5546
[email protected]23e482282013-06-14 16:08:025547void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235548 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085549 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425550 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085551}
5552
bncd16676a2016-07-20 16:23:015553TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085554 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5555}
5556
bncd16676a2016-07-20 16:23:015557TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085558 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5559}
5560
bncd16676a2016-07-20 16:23:015561TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085562 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5563}
5564
bncd16676a2016-07-20 16:23:015565TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085566 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5567}
5568
bncd16676a2016-07-20 16:23:015569TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085570 ConnectStatusHelper(
5571 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5572}
5573
bncd16676a2016-07-20 16:23:015574TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085575 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5576}
5577
bncd16676a2016-07-20 16:23:015578TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085579 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5580}
5581
bncd16676a2016-07-20 16:23:015582TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085583 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5584}
5585
bncd16676a2016-07-20 16:23:015586TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085587 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5588}
5589
bncd16676a2016-07-20 16:23:015590TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085591 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5592}
5593
bncd16676a2016-07-20 16:23:015594TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085595 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5596}
5597
bncd16676a2016-07-20 16:23:015598TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085599 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5600}
5601
bncd16676a2016-07-20 16:23:015602TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085603 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5604}
5605
bncd16676a2016-07-20 16:23:015606TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085607 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5608}
5609
bncd16676a2016-07-20 16:23:015610TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085611 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5612}
5613
bncd16676a2016-07-20 16:23:015614TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085615 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5616}
5617
bncd16676a2016-07-20 16:23:015618TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375619 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5620}
5621
bncd16676a2016-07-20 16:23:015622TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085623 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5624}
5625
bncd16676a2016-07-20 16:23:015626TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085627 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5628}
5629
bncd16676a2016-07-20 16:23:015630TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085631 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5632}
5633
bncd16676a2016-07-20 16:23:015634TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085635 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5636}
5637
bncd16676a2016-07-20 16:23:015638TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085639 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5640}
5641
bncd16676a2016-07-20 16:23:015642TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085643 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5644}
5645
bncd16676a2016-07-20 16:23:015646TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085647 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5648}
5649
bncd16676a2016-07-20 16:23:015650TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085651 ConnectStatusHelperWithExpectedStatus(
5652 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545653 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085654}
5655
bncd16676a2016-07-20 16:23:015656TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085657 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5658}
5659
bncd16676a2016-07-20 16:23:015660TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085661 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5662}
5663
bncd16676a2016-07-20 16:23:015664TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085665 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5666}
5667
bncd16676a2016-07-20 16:23:015668TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085669 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5670}
5671
bncd16676a2016-07-20 16:23:015672TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085673 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5674}
5675
bncd16676a2016-07-20 16:23:015676TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085677 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5678}
5679
bncd16676a2016-07-20 16:23:015680TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085681 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5682}
5683
bncd16676a2016-07-20 16:23:015684TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085685 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5686}
5687
bncd16676a2016-07-20 16:23:015688TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085689 ConnectStatusHelper(
5690 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5691}
5692
bncd16676a2016-07-20 16:23:015693TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085694 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5695}
5696
bncd16676a2016-07-20 16:23:015697TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085698 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5699}
5700
bncd16676a2016-07-20 16:23:015701TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085702 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5703}
5704
bncd16676a2016-07-20 16:23:015705TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085706 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5707}
5708
bncd16676a2016-07-20 16:23:015709TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085710 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5711}
5712
bncd16676a2016-07-20 16:23:015713TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085714 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5715}
5716
bncd16676a2016-07-20 16:23:015717TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085718 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5719}
5720
[email protected]038e9a32008-10-08 22:40:165721// Test the flow when both the proxy server AND origin server require
5722// authentication. Again, this uses basic auth for both since that is
5723// the simplest to mock.
bncd16676a2016-07-20 16:23:015724TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275725 HttpRequestInfo request;
5726 request.method = "GET";
bncce36dca22015-04-21 22:11:235727 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275728
[email protected]038e9a32008-10-08 22:40:165729 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035730 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095731 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075732
bnc691fda62016-08-12 00:43:165733 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:165734
[email protected]f9ee6b52008-11-08 06:46:235735 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235736 MockWrite(
5737 "GET http://www.example.org/ HTTP/1.1\r\n"
5738 "Host: www.example.org\r\n"
5739 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235740 };
5741
[email protected]038e9a32008-10-08 22:40:165742 MockRead data_reads1[] = {
5743 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5744 // Give a couple authenticate options (only the middle one is actually
5745 // supported).
[email protected]22927ad2009-09-21 19:56:195746 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165747 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5748 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5749 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5750 // Large content-length -- won't matter, as connection will be reset.
5751 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065752 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165753 };
5754
bnc691fda62016-08-12 00:43:165755 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:165756 // request we should be issuing -- the final header line contains the
5757 // proxy's credentials.
5758 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235759 MockWrite(
5760 "GET http://www.example.org/ HTTP/1.1\r\n"
5761 "Host: www.example.org\r\n"
5762 "Proxy-Connection: keep-alive\r\n"
5763 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165764 };
5765
5766 // Now the proxy server lets the request pass through to origin server.
5767 // The origin server responds with a 401.
5768 MockRead data_reads2[] = {
5769 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5770 // Note: We are using the same realm-name as the proxy server. This is
5771 // completely valid, as realms are unique across hosts.
5772 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5773 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5774 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065775 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165776 };
5777
bnc691fda62016-08-12 00:43:165778 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:165779 // the credentials for both the proxy and origin server.
5780 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235781 MockWrite(
5782 "GET http://www.example.org/ HTTP/1.1\r\n"
5783 "Host: www.example.org\r\n"
5784 "Proxy-Connection: keep-alive\r\n"
5785 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5786 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165787 };
5788
5789 // Lastly we get the desired content.
5790 MockRead data_reads3[] = {
5791 MockRead("HTTP/1.0 200 OK\r\n"),
5792 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5793 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065794 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165795 };
5796
[email protected]31a2bfe2010-02-09 08:03:395797 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5798 data_writes1, arraysize(data_writes1));
5799 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5800 data_writes2, arraysize(data_writes2));
5801 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5802 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075803 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5804 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5805 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165806
[email protected]49639fa2011-12-20 23:22:415807 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165808
tfarina42834112016-09-22 13:38:205809 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165811
5812 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015813 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165814
bnc691fda62016-08-12 00:43:165815 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525816 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045817 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165818
[email protected]49639fa2011-12-20 23:22:415819 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165820
bnc691fda62016-08-12 00:43:165821 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165823
5824 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015825 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165826
bnc691fda62016-08-12 00:43:165827 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525828 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045829 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165830
[email protected]49639fa2011-12-20 23:22:415831 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165832
bnc691fda62016-08-12 00:43:165833 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5834 callback3.callback());
robpercival214763f2016-07-01 23:27:015835 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165836
5837 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015838 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165839
bnc691fda62016-08-12 00:43:165840 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525841 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165842 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165843}
[email protected]4ddaf2502008-10-23 18:26:195844
[email protected]ea9dc9a2009-09-05 00:43:325845// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5846// can't hook into its internals to cause it to generate predictable NTLM
5847// authorization headers.
5848#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295849// The NTLM authentication unit tests were generated by capturing the HTTP
5850// requests and responses using Fiddler 2 and inspecting the generated random
5851// bytes in the debugger.
5852
5853// Enter the correct password and authenticate successfully.
bncd16676a2016-07-20 16:23:015854TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425855 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245856 request.method = "GET";
5857 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545858
5859 // Ensure load is not disrupted by flags which suppress behaviour specific
5860 // to other auth schemes.
5861 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245862
[email protected]cb9bf6ca2011-01-28 13:15:275863 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5864 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095865 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275866
[email protected]3f918782009-02-28 01:29:245867 MockWrite data_writes1[] = {
5868 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5869 "Host: 172.22.68.17\r\n"
5870 "Connection: keep-alive\r\n\r\n"),
5871 };
5872
5873 MockRead data_reads1[] = {
5874 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045875 // Negotiate and NTLM are often requested together. However, we only want
5876 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5877 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245878 MockRead("WWW-Authenticate: NTLM\r\n"),
5879 MockRead("Connection: close\r\n"),
5880 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365881 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245882 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065883 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245884 };
5885
5886 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165887 // After restarting with a null identity, this is the
5888 // request we should be issuing -- the final header line contains a Type
5889 // 1 message.
5890 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5891 "Host: 172.22.68.17\r\n"
5892 "Connection: keep-alive\r\n"
5893 "Authorization: NTLM "
5894 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245895
bnc691fda62016-08-12 00:43:165896 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5897 // (the credentials for the origin server). The second request continues
5898 // on the same connection.
5899 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5900 "Host: 172.22.68.17\r\n"
5901 "Connection: keep-alive\r\n"
5902 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5903 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5904 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5905 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5906 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245907 };
5908
5909 MockRead data_reads2[] = {
5910 // The origin server responds with a Type 2 message.
5911 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5912 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295913 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245914 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5915 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5916 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5917 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5918 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5919 "BtAAAAAAA=\r\n"),
5920 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365921 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245922 MockRead("You are not authorized to view this page\r\n"),
5923
5924 // Lastly we get the desired content.
5925 MockRead("HTTP/1.1 200 OK\r\n"),
5926 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5927 MockRead("Content-Length: 13\r\n\r\n"),
5928 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065929 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245930 };
5931
[email protected]31a2bfe2010-02-09 08:03:395932 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5933 data_writes1, arraysize(data_writes1));
5934 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5935 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075936 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5937 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245938
[email protected]49639fa2011-12-20 23:22:415939 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245940
bnc691fda62016-08-12 00:43:165941 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505942
tfarina42834112016-09-22 13:38:205943 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245945
5946 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015947 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245948
bnc691fda62016-08-12 00:43:165949 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:225950
bnc691fda62016-08-12 00:43:165951 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525952 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045953 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245954
[email protected]49639fa2011-12-20 23:22:415955 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255956
bnc691fda62016-08-12 00:43:165957 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
5958 callback2.callback());
robpercival214763f2016-07-01 23:27:015959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:255960
5961 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015962 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:255963
bnc691fda62016-08-12 00:43:165964 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:255965
bnc691fda62016-08-12 00:43:165966 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525967 ASSERT_TRUE(response);
5968 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:255969
[email protected]49639fa2011-12-20 23:22:415970 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245971
bnc691fda62016-08-12 00:43:165972 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:015973 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:245974
[email protected]0757e7702009-03-27 04:00:225975 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015976 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:245977
bnc691fda62016-08-12 00:43:165978 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525979 ASSERT_TRUE(response);
5980 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:245981 EXPECT_EQ(13, response->headers->GetContentLength());
5982}
5983
[email protected]385a4672009-03-11 22:21:295984// Enter a wrong password, and then the correct one.
bncd16676a2016-07-20 16:23:015985TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425986 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295987 request.method = "GET";
5988 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:295989
[email protected]cb9bf6ca2011-01-28 13:15:275990 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5991 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095992 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275993
[email protected]385a4672009-03-11 22:21:295994 MockWrite data_writes1[] = {
5995 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5996 "Host: 172.22.68.17\r\n"
5997 "Connection: keep-alive\r\n\r\n"),
5998 };
5999
6000 MockRead data_reads1[] = {
6001 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046002 // Negotiate and NTLM are often requested together. However, we only want
6003 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6004 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296005 MockRead("WWW-Authenticate: NTLM\r\n"),
6006 MockRead("Connection: close\r\n"),
6007 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366008 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296009 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066010 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296011 };
6012
6013 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166014 // After restarting with a null identity, this is the
6015 // request we should be issuing -- the final header line contains a Type
6016 // 1 message.
6017 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6018 "Host: 172.22.68.17\r\n"
6019 "Connection: keep-alive\r\n"
6020 "Authorization: NTLM "
6021 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296022
bnc691fda62016-08-12 00:43:166023 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6024 // (the credentials for the origin server). The second request continues
6025 // on the same connection.
6026 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6027 "Host: 172.22.68.17\r\n"
6028 "Connection: keep-alive\r\n"
6029 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6030 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6031 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
6032 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
6033 "4Ww7b7E=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296034 };
6035
6036 MockRead data_reads2[] = {
6037 // The origin server responds with a Type 2 message.
6038 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6039 MockRead("WWW-Authenticate: NTLM "
6040 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
6041 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6042 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6043 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6044 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6045 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6046 "BtAAAAAAA=\r\n"),
6047 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366048 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296049 MockRead("You are not authorized to view this page\r\n"),
6050
6051 // Wrong password.
6052 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:296053 MockRead("WWW-Authenticate: NTLM\r\n"),
6054 MockRead("Connection: close\r\n"),
6055 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366056 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296057 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:066058 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:296059 };
6060
6061 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166062 // After restarting with a null identity, this is the
6063 // request we should be issuing -- the final header line contains a Type
6064 // 1 message.
6065 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6066 "Host: 172.22.68.17\r\n"
6067 "Connection: keep-alive\r\n"
6068 "Authorization: NTLM "
6069 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296070
bnc691fda62016-08-12 00:43:166071 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6072 // (the credentials for the origin server). The second request continues
6073 // on the same connection.
6074 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6075 "Host: 172.22.68.17\r\n"
6076 "Connection: keep-alive\r\n"
6077 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6078 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6079 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6080 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6081 "+4MUm7c=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296082 };
6083
6084 MockRead data_reads3[] = {
6085 // The origin server responds with a Type 2 message.
6086 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6087 MockRead("WWW-Authenticate: NTLM "
6088 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6089 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6090 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6091 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6092 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6093 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6094 "BtAAAAAAA=\r\n"),
6095 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366096 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296097 MockRead("You are not authorized to view this page\r\n"),
6098
6099 // Lastly we get the desired content.
6100 MockRead("HTTP/1.1 200 OK\r\n"),
6101 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6102 MockRead("Content-Length: 13\r\n\r\n"),
6103 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066104 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296105 };
6106
[email protected]31a2bfe2010-02-09 08:03:396107 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6108 data_writes1, arraysize(data_writes1));
6109 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6110 data_writes2, arraysize(data_writes2));
6111 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6112 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076113 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6114 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6115 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296116
[email protected]49639fa2011-12-20 23:22:416117 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296118
bnc691fda62016-08-12 00:43:166119 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506120
tfarina42834112016-09-22 13:38:206121 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016122 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296123
6124 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016125 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296126
bnc691fda62016-08-12 00:43:166127 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296128
bnc691fda62016-08-12 00:43:166129 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526130 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046131 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296132
[email protected]49639fa2011-12-20 23:22:416133 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296134
[email protected]0757e7702009-03-27 04:00:226135 // Enter the wrong password.
bnc691fda62016-08-12 00:43:166136 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
6137 callback2.callback());
robpercival214763f2016-07-01 23:27:016138 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296139
[email protected]10af5fe72011-01-31 16:17:256140 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016141 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296142
bnc691fda62016-08-12 00:43:166143 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416144 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166145 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016146 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256147 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016148 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166149 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226150
bnc691fda62016-08-12 00:43:166151 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526152 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046153 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226154
[email protected]49639fa2011-12-20 23:22:416155 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226156
6157 // Now enter the right password.
bnc691fda62016-08-12 00:43:166158 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6159 callback4.callback());
robpercival214763f2016-07-01 23:27:016160 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256161
6162 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016163 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256164
bnc691fda62016-08-12 00:43:166165 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256166
[email protected]49639fa2011-12-20 23:22:416167 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256168
6169 // One more roundtrip
bnc691fda62016-08-12 00:43:166170 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016171 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226172
6173 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016174 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226175
bnc691fda62016-08-12 00:43:166176 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526177 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296178 EXPECT_EQ(13, response->headers->GetContentLength());
6179}
[email protected]ea9dc9a2009-09-05 00:43:326180#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296181
[email protected]4ddaf2502008-10-23 18:26:196182// Test reading a server response which has only headers, and no body.
6183// After some maximum number of bytes is consumed, the transaction should
6184// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016185TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426186 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196187 request.method = "GET";
bncce36dca22015-04-21 22:11:236188 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196189
danakj1fd259a02016-04-16 03:17:096190 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166191 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276192
[email protected]b75b7b2f2009-10-06 00:54:536193 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436194 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536195 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196196
6197 MockRead data_reads[] = {
6198 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066199 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196200 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066201 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196202 };
[email protected]31a2bfe2010-02-09 08:03:396203 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076204 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196205
[email protected]49639fa2011-12-20 23:22:416206 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196207
tfarina42834112016-09-22 13:38:206208 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016209 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196210
6211 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016212 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196213}
[email protected]f4e426b2008-11-05 00:24:496214
6215// Make sure that we don't try to reuse a TCPClientSocket when failing to
6216// establish tunnel.
6217// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016218TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276219 HttpRequestInfo request;
6220 request.method = "GET";
bncce36dca22015-04-21 22:11:236221 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276222
[email protected]f4e426b2008-11-05 00:24:496223 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036224 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016225
danakj1fd259a02016-04-16 03:17:096226 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496227
bnc691fda62016-08-12 00:43:166228 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:506229 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:496230
[email protected]f4e426b2008-11-05 00:24:496231 // Since we have proxy, should try to establish tunnel.
6232 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176233 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6234 "Host: www.example.org:443\r\n"
6235 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496236 };
6237
[email protected]77848d12008-11-14 00:00:226238 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496239 // connection. Usually a proxy would return 501 (not implemented),
6240 // or 200 (tunnel established).
6241 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236242 MockRead("HTTP/1.1 404 Not Found\r\n"),
6243 MockRead("Content-Length: 10\r\n\r\n"),
6244 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496245 };
6246
[email protected]31a2bfe2010-02-09 08:03:396247 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6248 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076249 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496250
[email protected]49639fa2011-12-20 23:22:416251 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496252
tfarina42834112016-09-22 13:38:206253 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496255
6256 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016257 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496258
[email protected]b4404c02009-04-10 16:38:526259 // Empty the current queue. This is necessary because idle sockets are
6260 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556261 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526262
[email protected]f4e426b2008-11-05 00:24:496263 // We now check to make sure the TCPClientSocket was not added back to
6264 // the pool.
[email protected]90499482013-06-01 00:39:506265 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496266 trans.reset();
fdoray92e35a72016-06-10 15:54:556267 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496268 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506269 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496270}
[email protected]372d34a2008-11-05 21:30:516271
[email protected]1b157c02009-04-21 01:55:406272// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016273TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426274 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406275 request.method = "GET";
bncce36dca22015-04-21 22:11:236276 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406277
danakj1fd259a02016-04-16 03:17:096278 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276279
bnc691fda62016-08-12 00:43:166280 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276281
[email protected]1b157c02009-04-21 01:55:406282 MockRead data_reads[] = {
6283 // A part of the response body is received with the response headers.
6284 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6285 // The rest of the response body is received in two parts.
6286 MockRead("lo"),
6287 MockRead(" world"),
6288 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066289 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406290 };
6291
[email protected]31a2bfe2010-02-09 08:03:396292 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076293 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406294
[email protected]49639fa2011-12-20 23:22:416295 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406296
tfarina42834112016-09-22 13:38:206297 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016298 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406299
6300 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016301 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406302
bnc691fda62016-08-12 00:43:166303 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526304 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406305
wezca1070932016-05-26 20:30:526306 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406307 std::string status_line = response->headers->GetStatusLine();
6308 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6309
[email protected]90499482013-06-01 00:39:506310 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406311
6312 std::string response_data;
bnc691fda62016-08-12 00:43:166313 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016314 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406315 EXPECT_EQ("hello world", response_data);
6316
6317 // Empty the current queue. This is necessary because idle sockets are
6318 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556319 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406320
6321 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506322 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406323}
6324
[email protected]76a505b2010-08-25 06:23:006325// Make sure that we recycle a SSL socket after reading all of the response
6326// body.
bncd16676a2016-07-20 16:23:016327TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006328 HttpRequestInfo request;
6329 request.method = "GET";
bncce36dca22015-04-21 22:11:236330 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006331
6332 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236333 MockWrite(
6334 "GET / HTTP/1.1\r\n"
6335 "Host: www.example.org\r\n"
6336 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006337 };
6338
6339 MockRead data_reads[] = {
6340 MockRead("HTTP/1.1 200 OK\r\n"),
6341 MockRead("Content-Length: 11\r\n\r\n"),
6342 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066343 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006344 };
6345
[email protected]8ddf8322012-02-23 18:08:066346 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076347 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006348
6349 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6350 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076351 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006352
[email protected]49639fa2011-12-20 23:22:416353 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006354
danakj1fd259a02016-04-16 03:17:096355 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166356 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006357
tfarina42834112016-09-22 13:38:206358 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006359
robpercival214763f2016-07-01 23:27:016360 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6361 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006362
bnc691fda62016-08-12 00:43:166363 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526364 ASSERT_TRUE(response);
6365 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006366 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6367
[email protected]90499482013-06-01 00:39:506368 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006369
6370 std::string response_data;
bnc691fda62016-08-12 00:43:166371 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016372 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006373 EXPECT_EQ("hello world", response_data);
6374
6375 // Empty the current queue. This is necessary because idle sockets are
6376 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556377 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006378
6379 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506380 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006381}
6382
6383// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6384// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016385TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006386 HttpRequestInfo request;
6387 request.method = "GET";
bncce36dca22015-04-21 22:11:236388 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006389
6390 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236391 MockWrite(
6392 "GET / HTTP/1.1\r\n"
6393 "Host: www.example.org\r\n"
6394 "Connection: keep-alive\r\n\r\n"),
6395 MockWrite(
6396 "GET / HTTP/1.1\r\n"
6397 "Host: www.example.org\r\n"
6398 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006399 };
6400
6401 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426402 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6403 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006404
[email protected]8ddf8322012-02-23 18:08:066405 SSLSocketDataProvider ssl(ASYNC, OK);
6406 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076407 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6408 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006409
6410 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6411 data_writes, arraysize(data_writes));
6412 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6413 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076414 session_deps_.socket_factory->AddSocketDataProvider(&data);
6415 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006416
[email protected]49639fa2011-12-20 23:22:416417 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006418
danakj1fd259a02016-04-16 03:17:096419 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166420 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:506421 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006422
tfarina42834112016-09-22 13:38:206423 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006424
robpercival214763f2016-07-01 23:27:016425 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6426 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006427
6428 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526429 ASSERT_TRUE(response);
6430 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006431 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6432
[email protected]90499482013-06-01 00:39:506433 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006434
6435 std::string response_data;
6436 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016437 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006438 EXPECT_EQ("hello world", response_data);
6439
6440 // Empty the current queue. This is necessary because idle sockets are
6441 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556442 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006443
6444 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506445 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006446
6447 // Now start the second transaction, which should reuse the previous socket.
6448
[email protected]90499482013-06-01 00:39:506449 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006450
tfarina42834112016-09-22 13:38:206451 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006452
robpercival214763f2016-07-01 23:27:016453 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6454 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006455
6456 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526457 ASSERT_TRUE(response);
6458 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006459 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6460
[email protected]90499482013-06-01 00:39:506461 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006462
6463 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016464 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006465 EXPECT_EQ("hello world", response_data);
6466
6467 // Empty the current queue. This is necessary because idle sockets are
6468 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556469 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006470
6471 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506472 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006473}
6474
maksim.sisov0adf8592016-07-15 06:25:566475// Grab a socket, use it, and put it back into the pool. Then, make
6476// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016477TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566478 HttpRequestInfo request;
6479 request.method = "GET";
6480 request.url = GURL("http://www.example.org/");
6481 request.load_flags = 0;
6482
6483 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6484
bnc691fda62016-08-12 00:43:166485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566486
6487 MockRead data_reads[] = {
6488 // A part of the response body is received with the response headers.
6489 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6490 // The rest of the response body is received in two parts.
6491 MockRead("lo"), MockRead(" world"),
6492 MockRead("junk"), // Should not be read!!
6493 MockRead(SYNCHRONOUS, OK),
6494 };
6495
6496 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6497 session_deps_.socket_factory->AddSocketDataProvider(&data);
6498
6499 TestCompletionCallback callback;
6500
tfarina42834112016-09-22 13:38:206501 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566502 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6503
6504 EXPECT_THAT(callback.GetResult(rv), IsOk());
6505
bnc691fda62016-08-12 00:43:166506 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566507 ASSERT_TRUE(response);
6508 EXPECT_TRUE(response->headers);
6509 std::string status_line = response->headers->GetStatusLine();
6510 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6511
6512 // Make memory critical notification and ensure the transaction still has been
6513 // operating right.
6514 base::MemoryPressureListener::NotifyMemoryPressure(
6515 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6516 base::RunLoop().RunUntilIdle();
6517
6518 // Socket should not be flushed as long as it is not idle.
6519 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6520
6521 std::string response_data;
bnc691fda62016-08-12 00:43:166522 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566523 EXPECT_THAT(rv, IsOk());
6524 EXPECT_EQ("hello world", response_data);
6525
6526 // Empty the current queue. This is necessary because idle sockets are
6527 // added to the connection pool asynchronously with a PostTask.
6528 base::RunLoop().RunUntilIdle();
6529
6530 // We now check to make sure the socket was added back to the pool.
6531 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6532
6533 // Idle sockets should be flushed now.
6534 base::MemoryPressureListener::NotifyMemoryPressure(
6535 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6536 base::RunLoop().RunUntilIdle();
6537
6538 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6539}
6540
6541// Grab an SSL socket, use it, and put it back into the pool. Then, make
6542// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016543TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566544 HttpRequestInfo request;
6545 request.method = "GET";
6546 request.url = GURL("https://www.example.org/");
6547 request.load_flags = 0;
6548
6549 MockWrite data_writes[] = {
6550 MockWrite("GET / HTTP/1.1\r\n"
6551 "Host: www.example.org\r\n"
6552 "Connection: keep-alive\r\n\r\n"),
6553 };
6554
6555 MockRead data_reads[] = {
6556 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6557 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6558
6559 SSLSocketDataProvider ssl(ASYNC, OK);
6560 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6561
6562 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6563 arraysize(data_writes));
6564 session_deps_.socket_factory->AddSocketDataProvider(&data);
6565
6566 TestCompletionCallback callback;
6567
6568 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166569 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566570
6571 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:206572 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566573
6574 EXPECT_THAT(callback.GetResult(rv), IsOk());
6575
bnc691fda62016-08-12 00:43:166576 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566577 ASSERT_TRUE(response);
6578 ASSERT_TRUE(response->headers);
6579 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6580
6581 // Make memory critical notification and ensure the transaction still has been
6582 // operating right.
6583 base::MemoryPressureListener::NotifyMemoryPressure(
6584 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6585 base::RunLoop().RunUntilIdle();
6586
6587 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6588
6589 std::string response_data;
bnc691fda62016-08-12 00:43:166590 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566591 EXPECT_THAT(rv, IsOk());
6592 EXPECT_EQ("hello world", response_data);
6593
6594 // Empty the current queue. This is necessary because idle sockets are
6595 // added to the connection pool asynchronously with a PostTask.
6596 base::RunLoop().RunUntilIdle();
6597
6598 // We now check to make sure the socket was added back to the pool.
6599 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6600
6601 // Make memory notification once again and ensure idle socket is closed.
6602 base::MemoryPressureListener::NotifyMemoryPressure(
6603 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6604 base::RunLoop().RunUntilIdle();
6605
6606 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6607}
6608
[email protected]b4404c02009-04-10 16:38:526609// Make sure that we recycle a socket after a zero-length response.
6610// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016611TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426612 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526613 request.method = "GET";
bncce36dca22015-04-21 22:11:236614 request.url = GURL(
6615 "http://www.example.org/csi?v=3&s=web&action=&"
6616 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6617 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6618 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526619
danakj1fd259a02016-04-16 03:17:096620 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276621
[email protected]b4404c02009-04-10 16:38:526622 MockRead data_reads[] = {
6623 MockRead("HTTP/1.1 204 No Content\r\n"
6624 "Content-Length: 0\r\n"
6625 "Content-Type: text/html\r\n\r\n"),
6626 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066627 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526628 };
6629
[email protected]31a2bfe2010-02-09 08:03:396630 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076631 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526632
mmenkecc2298e2015-12-07 18:20:186633 // Transaction must be created after the MockReads, so it's destroyed before
6634 // them.
bnc691fda62016-08-12 00:43:166635 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186636
[email protected]49639fa2011-12-20 23:22:416637 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526638
tfarina42834112016-09-22 13:38:206639 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016640 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526641
6642 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016643 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526644
bnc691fda62016-08-12 00:43:166645 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526646 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526647
wezca1070932016-05-26 20:30:526648 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526649 std::string status_line = response->headers->GetStatusLine();
6650 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6651
[email protected]90499482013-06-01 00:39:506652 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526653
6654 std::string response_data;
bnc691fda62016-08-12 00:43:166655 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016656 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526657 EXPECT_EQ("", response_data);
6658
6659 // Empty the current queue. This is necessary because idle sockets are
6660 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556661 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526662
6663 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506664 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526665}
6666
bncd16676a2016-07-20 16:23:016667TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096668 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226669 element_readers.push_back(
ricea2deef682016-09-09 08:04:076670 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226671 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276672
[email protected]1c773ea12009-04-28 19:58:426673 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516674 // Transaction 1: a GET request that succeeds. The socket is recycled
6675 // after use.
6676 request[0].method = "GET";
6677 request[0].url = GURL("http://www.google.com/");
6678 request[0].load_flags = 0;
6679 // Transaction 2: a POST request. Reuses the socket kept alive from
6680 // transaction 1. The first attempts fails when writing the POST data.
6681 // This causes the transaction to retry with a new socket. The second
6682 // attempt succeeds.
6683 request[1].method = "POST";
6684 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276685 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516686 request[1].load_flags = 0;
6687
danakj1fd259a02016-04-16 03:17:096688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516689
6690 // The first socket is used for transaction 1 and the first attempt of
6691 // transaction 2.
6692
6693 // The response of transaction 1.
6694 MockRead data_reads1[] = {
6695 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6696 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066697 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516698 };
6699 // The mock write results of transaction 1 and the first attempt of
6700 // transaction 2.
6701 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066702 MockWrite(SYNCHRONOUS, 64), // GET
6703 MockWrite(SYNCHRONOUS, 93), // POST
6704 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516705 };
[email protected]31a2bfe2010-02-09 08:03:396706 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6707 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516708
6709 // The second socket is used for the second attempt of transaction 2.
6710
6711 // The response of transaction 2.
6712 MockRead data_reads2[] = {
6713 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6714 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066715 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516716 };
6717 // The mock write results of the second attempt of transaction 2.
6718 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066719 MockWrite(SYNCHRONOUS, 93), // POST
6720 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516721 };
[email protected]31a2bfe2010-02-09 08:03:396722 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6723 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516724
[email protected]bb88e1d32013-05-03 23:11:076725 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6726 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516727
thestig9d3bb0c2015-01-24 00:49:516728 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516729 "hello world", "welcome"
6730 };
6731
6732 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:166733 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:516734
[email protected]49639fa2011-12-20 23:22:416735 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516736
tfarina42834112016-09-22 13:38:206737 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016738 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:516739
6740 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016741 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516742
bnc691fda62016-08-12 00:43:166743 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526744 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516745
wezca1070932016-05-26 20:30:526746 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516747 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6748
6749 std::string response_data;
bnc691fda62016-08-12 00:43:166750 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016751 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:516752 EXPECT_EQ(kExpectedResponseData[i], response_data);
6753 }
6754}
[email protected]f9ee6b52008-11-08 06:46:236755
6756// Test the request-challenge-retry sequence for basic auth when there is
6757// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166758// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:016759TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426760 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236761 request.method = "GET";
bncce36dca22015-04-21 22:11:236762 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416763 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296764
danakj1fd259a02016-04-16 03:17:096765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166766 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276767
[email protected]a97cca42009-08-14 01:00:296768 // The password contains an escaped character -- for this test to pass it
6769 // will need to be unescaped by HttpNetworkTransaction.
6770 EXPECT_EQ("b%40r", request.url.password());
6771
[email protected]f9ee6b52008-11-08 06:46:236772 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236773 MockWrite(
6774 "GET / HTTP/1.1\r\n"
6775 "Host: www.example.org\r\n"
6776 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236777 };
6778
6779 MockRead data_reads1[] = {
6780 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6781 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6782 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066783 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236784 };
6785
[email protected]2262e3a2012-05-22 16:08:166786 // After the challenge above, the transaction will be restarted using the
6787 // identity from the url (foo, b@r) to answer the challenge.
6788 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236789 MockWrite(
6790 "GET / HTTP/1.1\r\n"
6791 "Host: www.example.org\r\n"
6792 "Connection: keep-alive\r\n"
6793 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166794 };
6795
6796 MockRead data_reads2[] = {
6797 MockRead("HTTP/1.0 200 OK\r\n"),
6798 MockRead("Content-Length: 100\r\n\r\n"),
6799 MockRead(SYNCHRONOUS, OK),
6800 };
6801
[email protected]31a2bfe2010-02-09 08:03:396802 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6803 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166804 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6805 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076806 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6807 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236808
[email protected]49639fa2011-12-20 23:22:416809 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:206810 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:236812 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016813 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166814 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166815
6816 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166817 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166819 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016820 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166821 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226822
bnc691fda62016-08-12 00:43:166823 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526824 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166825
6826 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526827 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166828
6829 EXPECT_EQ(100, response->headers->GetContentLength());
6830
6831 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556832 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166833}
6834
6835// Test the request-challenge-retry sequence for basic auth when there is an
6836// incorrect identity in the URL. The identity from the URL should be used only
6837// once.
bncd16676a2016-07-20 16:23:016838TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166839 HttpRequestInfo request;
6840 request.method = "GET";
6841 // Note: the URL has a username:password in it. The password "baz" is
6842 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236843 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166844
6845 request.load_flags = LOAD_NORMAL;
6846
danakj1fd259a02016-04-16 03:17:096847 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166848 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:166849
6850 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236851 MockWrite(
6852 "GET / HTTP/1.1\r\n"
6853 "Host: www.example.org\r\n"
6854 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166855 };
6856
6857 MockRead data_reads1[] = {
6858 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6859 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6860 MockRead("Content-Length: 10\r\n\r\n"),
6861 MockRead(SYNCHRONOUS, ERR_FAILED),
6862 };
6863
6864 // After the challenge above, the transaction will be restarted using the
6865 // identity from the url (foo, baz) to answer the challenge.
6866 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236867 MockWrite(
6868 "GET / HTTP/1.1\r\n"
6869 "Host: www.example.org\r\n"
6870 "Connection: keep-alive\r\n"
6871 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166872 };
6873
6874 MockRead data_reads2[] = {
6875 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6876 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6877 MockRead("Content-Length: 10\r\n\r\n"),
6878 MockRead(SYNCHRONOUS, ERR_FAILED),
6879 };
6880
6881 // After the challenge above, the transaction will be restarted using the
6882 // identity supplied by the user (foo, bar) to answer the challenge.
6883 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236884 MockWrite(
6885 "GET / HTTP/1.1\r\n"
6886 "Host: www.example.org\r\n"
6887 "Connection: keep-alive\r\n"
6888 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166889 };
6890
6891 MockRead data_reads3[] = {
6892 MockRead("HTTP/1.0 200 OK\r\n"),
6893 MockRead("Content-Length: 100\r\n\r\n"),
6894 MockRead(SYNCHRONOUS, OK),
6895 };
6896
6897 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6898 data_writes1, arraysize(data_writes1));
6899 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6900 data_writes2, arraysize(data_writes2));
6901 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6902 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076903 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6904 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6905 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166906
6907 TestCompletionCallback callback1;
6908
tfarina42834112016-09-22 13:38:206909 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016910 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166911
6912 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016913 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:166914
bnc691fda62016-08-12 00:43:166915 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166916 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:166917 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:016918 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166919 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016920 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166921 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166922
bnc691fda62016-08-12 00:43:166923 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526924 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166925 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6926
6927 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166928 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:016929 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:166930 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016931 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166932 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:166933
bnc691fda62016-08-12 00:43:166934 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526935 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166936
6937 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526938 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166939
6940 EXPECT_EQ(100, response->headers->GetContentLength());
6941
[email protected]ea9dc9a2009-09-05 00:43:326942 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556943 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326944}
6945
[email protected]2217aa22013-10-11 03:03:546946
6947// Test the request-challenge-retry sequence for basic auth when there is a
6948// correct identity in the URL, but its use is being suppressed. The identity
6949// from the URL should never be used.
bncd16676a2016-07-20 16:23:016950TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:546951 HttpRequestInfo request;
6952 request.method = "GET";
bncce36dca22015-04-21 22:11:236953 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546954 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6955
danakj1fd259a02016-04-16 03:17:096956 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166957 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:546958
6959 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236960 MockWrite(
6961 "GET / HTTP/1.1\r\n"
6962 "Host: www.example.org\r\n"
6963 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546964 };
6965
6966 MockRead data_reads1[] = {
6967 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6968 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6969 MockRead("Content-Length: 10\r\n\r\n"),
6970 MockRead(SYNCHRONOUS, ERR_FAILED),
6971 };
6972
6973 // After the challenge above, the transaction will be restarted using the
6974 // identity supplied by the user, not the one in the URL, to answer the
6975 // challenge.
6976 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236977 MockWrite(
6978 "GET / HTTP/1.1\r\n"
6979 "Host: www.example.org\r\n"
6980 "Connection: keep-alive\r\n"
6981 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546982 };
6983
6984 MockRead data_reads3[] = {
6985 MockRead("HTTP/1.0 200 OK\r\n"),
6986 MockRead("Content-Length: 100\r\n\r\n"),
6987 MockRead(SYNCHRONOUS, OK),
6988 };
6989
6990 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6991 data_writes1, arraysize(data_writes1));
6992 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6993 data_writes3, arraysize(data_writes3));
6994 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6995 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6996
6997 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:206998 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016999 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547000 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017001 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167002 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547003
bnc691fda62016-08-12 00:43:167004 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527005 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547006 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7007
7008 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167009 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017010 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547011 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017012 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167013 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547014
bnc691fda62016-08-12 00:43:167015 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527016 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547017
7018 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527019 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547020 EXPECT_EQ(100, response->headers->GetContentLength());
7021
7022 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557023 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547024}
7025
[email protected]f9ee6b52008-11-08 06:46:237026// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017027TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237029
7030 // Transaction 1: authenticate (foo, bar) on MyRealm1
7031 {
[email protected]1c773ea12009-04-28 19:58:427032 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237033 request.method = "GET";
bncce36dca22015-04-21 22:11:237034 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237035
bnc691fda62016-08-12 00:43:167036 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277037
[email protected]f9ee6b52008-11-08 06:46:237038 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237039 MockWrite(
7040 "GET /x/y/z HTTP/1.1\r\n"
7041 "Host: www.example.org\r\n"
7042 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237043 };
7044
7045 MockRead data_reads1[] = {
7046 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7047 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7048 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067049 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237050 };
7051
7052 // Resend with authorization (username=foo, password=bar)
7053 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237054 MockWrite(
7055 "GET /x/y/z HTTP/1.1\r\n"
7056 "Host: www.example.org\r\n"
7057 "Connection: keep-alive\r\n"
7058 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237059 };
7060
7061 // Sever accepts the authorization.
7062 MockRead data_reads2[] = {
7063 MockRead("HTTP/1.0 200 OK\r\n"),
7064 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067065 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237066 };
7067
[email protected]31a2bfe2010-02-09 08:03:397068 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7069 data_writes1, arraysize(data_writes1));
7070 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7071 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077072 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7073 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237074
[email protected]49639fa2011-12-20 23:22:417075 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237076
tfarina42834112016-09-22 13:38:207077 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017078 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237079
7080 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017081 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237082
bnc691fda62016-08-12 00:43:167083 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527084 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047085 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237086
[email protected]49639fa2011-12-20 23:22:417087 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237088
bnc691fda62016-08-12 00:43:167089 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7090 callback2.callback());
robpercival214763f2016-07-01 23:27:017091 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237092
7093 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017094 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237095
bnc691fda62016-08-12 00:43:167096 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527097 ASSERT_TRUE(response);
7098 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237099 EXPECT_EQ(100, response->headers->GetContentLength());
7100 }
7101
7102 // ------------------------------------------------------------------------
7103
7104 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7105 {
[email protected]1c773ea12009-04-28 19:58:427106 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237107 request.method = "GET";
7108 // Note that Transaction 1 was at /x/y/z, so this is in the same
7109 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237110 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237111
bnc691fda62016-08-12 00:43:167112 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277113
[email protected]f9ee6b52008-11-08 06:46:237114 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237115 MockWrite(
7116 "GET /x/y/a/b HTTP/1.1\r\n"
7117 "Host: www.example.org\r\n"
7118 "Connection: keep-alive\r\n"
7119 // Send preemptive authorization for MyRealm1
7120 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237121 };
7122
7123 // The server didn't like the preemptive authorization, and
7124 // challenges us for a different realm (MyRealm2).
7125 MockRead data_reads1[] = {
7126 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7127 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7128 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067129 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237130 };
7131
7132 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7133 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237134 MockWrite(
7135 "GET /x/y/a/b HTTP/1.1\r\n"
7136 "Host: www.example.org\r\n"
7137 "Connection: keep-alive\r\n"
7138 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237139 };
7140
7141 // Sever accepts the authorization.
7142 MockRead data_reads2[] = {
7143 MockRead("HTTP/1.0 200 OK\r\n"),
7144 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067145 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237146 };
7147
[email protected]31a2bfe2010-02-09 08:03:397148 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7149 data_writes1, arraysize(data_writes1));
7150 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7151 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077152 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7153 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237154
[email protected]49639fa2011-12-20 23:22:417155 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237156
tfarina42834112016-09-22 13:38:207157 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237159
7160 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017161 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237162
bnc691fda62016-08-12 00:43:167163 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527164 ASSERT_TRUE(response);
7165 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047166 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437167 EXPECT_EQ("http://www.example.org",
7168 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047169 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197170 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237171
[email protected]49639fa2011-12-20 23:22:417172 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237173
bnc691fda62016-08-12 00:43:167174 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7175 callback2.callback());
robpercival214763f2016-07-01 23:27:017176 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237177
7178 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017179 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237180
bnc691fda62016-08-12 00:43:167181 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527182 ASSERT_TRUE(response);
7183 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237184 EXPECT_EQ(100, response->headers->GetContentLength());
7185 }
7186
7187 // ------------------------------------------------------------------------
7188
7189 // Transaction 3: Resend a request in MyRealm's protection space --
7190 // succeed with preemptive authorization.
7191 {
[email protected]1c773ea12009-04-28 19:58:427192 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237193 request.method = "GET";
bncce36dca22015-04-21 22:11:237194 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237195
bnc691fda62016-08-12 00:43:167196 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277197
[email protected]f9ee6b52008-11-08 06:46:237198 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237199 MockWrite(
7200 "GET /x/y/z2 HTTP/1.1\r\n"
7201 "Host: www.example.org\r\n"
7202 "Connection: keep-alive\r\n"
7203 // The authorization for MyRealm1 gets sent preemptively
7204 // (since the url is in the same protection space)
7205 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237206 };
7207
7208 // Sever accepts the preemptive authorization
7209 MockRead data_reads1[] = {
7210 MockRead("HTTP/1.0 200 OK\r\n"),
7211 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067212 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237213 };
7214
[email protected]31a2bfe2010-02-09 08:03:397215 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7216 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077217 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237218
[email protected]49639fa2011-12-20 23:22:417219 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237220
tfarina42834112016-09-22 13:38:207221 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017222 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237223
7224 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017225 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237226
bnc691fda62016-08-12 00:43:167227 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527228 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237229
wezca1070932016-05-26 20:30:527230 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237231 EXPECT_EQ(100, response->headers->GetContentLength());
7232 }
7233
7234 // ------------------------------------------------------------------------
7235
7236 // Transaction 4: request another URL in MyRealm (however the
7237 // url is not known to belong to the protection space, so no pre-auth).
7238 {
[email protected]1c773ea12009-04-28 19:58:427239 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237240 request.method = "GET";
bncce36dca22015-04-21 22:11:237241 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237242
bnc691fda62016-08-12 00:43:167243 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277244
[email protected]f9ee6b52008-11-08 06:46:237245 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237246 MockWrite(
7247 "GET /x/1 HTTP/1.1\r\n"
7248 "Host: www.example.org\r\n"
7249 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237250 };
7251
7252 MockRead data_reads1[] = {
7253 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7254 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7255 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067256 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237257 };
7258
7259 // Resend with authorization from MyRealm's cache.
7260 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237261 MockWrite(
7262 "GET /x/1 HTTP/1.1\r\n"
7263 "Host: www.example.org\r\n"
7264 "Connection: keep-alive\r\n"
7265 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237266 };
7267
7268 // Sever accepts the authorization.
7269 MockRead data_reads2[] = {
7270 MockRead("HTTP/1.0 200 OK\r\n"),
7271 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067272 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237273 };
7274
[email protected]31a2bfe2010-02-09 08:03:397275 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7276 data_writes1, arraysize(data_writes1));
7277 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7278 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077279 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7280 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237281
[email protected]49639fa2011-12-20 23:22:417282 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237283
tfarina42834112016-09-22 13:38:207284 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017285 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237286
7287 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017288 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237289
bnc691fda62016-08-12 00:43:167290 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417291 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167292 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017293 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227294 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017295 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167296 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227297
bnc691fda62016-08-12 00:43:167298 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527299 ASSERT_TRUE(response);
7300 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237301 EXPECT_EQ(100, response->headers->GetContentLength());
7302 }
7303
7304 // ------------------------------------------------------------------------
7305
7306 // Transaction 5: request a URL in MyRealm, but the server rejects the
7307 // cached identity. Should invalidate and re-prompt.
7308 {
[email protected]1c773ea12009-04-28 19:58:427309 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237310 request.method = "GET";
bncce36dca22015-04-21 22:11:237311 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237312
bnc691fda62016-08-12 00:43:167313 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277314
[email protected]f9ee6b52008-11-08 06:46:237315 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237316 MockWrite(
7317 "GET /p/q/t HTTP/1.1\r\n"
7318 "Host: www.example.org\r\n"
7319 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237320 };
7321
7322 MockRead data_reads1[] = {
7323 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7324 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7325 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067326 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237327 };
7328
7329 // Resend with authorization from cache for MyRealm.
7330 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237331 MockWrite(
7332 "GET /p/q/t HTTP/1.1\r\n"
7333 "Host: www.example.org\r\n"
7334 "Connection: keep-alive\r\n"
7335 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237336 };
7337
7338 // Sever rejects the authorization.
7339 MockRead data_reads2[] = {
7340 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7341 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7342 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067343 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237344 };
7345
7346 // At this point we should prompt for new credentials for MyRealm.
7347 // Restart with username=foo3, password=foo4.
7348 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237349 MockWrite(
7350 "GET /p/q/t HTTP/1.1\r\n"
7351 "Host: www.example.org\r\n"
7352 "Connection: keep-alive\r\n"
7353 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237354 };
7355
7356 // Sever accepts the authorization.
7357 MockRead data_reads3[] = {
7358 MockRead("HTTP/1.0 200 OK\r\n"),
7359 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067360 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237361 };
7362
[email protected]31a2bfe2010-02-09 08:03:397363 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7364 data_writes1, arraysize(data_writes1));
7365 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7366 data_writes2, arraysize(data_writes2));
7367 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7368 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077369 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7370 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7371 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237372
[email protected]49639fa2011-12-20 23:22:417373 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237374
tfarina42834112016-09-22 13:38:207375 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017376 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237377
7378 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017379 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237380
bnc691fda62016-08-12 00:43:167381 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417382 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167383 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017384 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227385 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017386 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167387 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227388
bnc691fda62016-08-12 00:43:167389 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527390 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047391 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237392
[email protected]49639fa2011-12-20 23:22:417393 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237394
bnc691fda62016-08-12 00:43:167395 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7396 callback3.callback());
robpercival214763f2016-07-01 23:27:017397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237398
[email protected]0757e7702009-03-27 04:00:227399 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017400 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237401
bnc691fda62016-08-12 00:43:167402 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527403 ASSERT_TRUE(response);
7404 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237405 EXPECT_EQ(100, response->headers->GetContentLength());
7406 }
7407}
[email protected]89ceba9a2009-03-21 03:46:067408
[email protected]3c32c5f2010-05-18 15:18:127409// Tests that nonce count increments when multiple auth attempts
7410// are started with the same nonce.
bncd16676a2016-07-20 16:23:017411TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447412 HttpAuthHandlerDigest::Factory* digest_factory =
7413 new HttpAuthHandlerDigest::Factory();
7414 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7415 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7416 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077417 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097418 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127419
7420 // Transaction 1: authenticate (foo, bar) on MyRealm1
7421 {
[email protected]3c32c5f2010-05-18 15:18:127422 HttpRequestInfo request;
7423 request.method = "GET";
bncce36dca22015-04-21 22:11:237424 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127425
bnc691fda62016-08-12 00:43:167426 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277427
[email protected]3c32c5f2010-05-18 15:18:127428 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237429 MockWrite(
7430 "GET /x/y/z HTTP/1.1\r\n"
7431 "Host: www.example.org\r\n"
7432 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127433 };
7434
7435 MockRead data_reads1[] = {
7436 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7437 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7438 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067439 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127440 };
7441
7442 // Resend with authorization (username=foo, password=bar)
7443 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237444 MockWrite(
7445 "GET /x/y/z HTTP/1.1\r\n"
7446 "Host: www.example.org\r\n"
7447 "Connection: keep-alive\r\n"
7448 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7449 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7450 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7451 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127452 };
7453
7454 // Sever accepts the authorization.
7455 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087456 MockRead("HTTP/1.0 200 OK\r\n"),
7457 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127458 };
7459
7460 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7461 data_writes1, arraysize(data_writes1));
7462 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7463 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077464 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7465 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127466
[email protected]49639fa2011-12-20 23:22:417467 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127468
tfarina42834112016-09-22 13:38:207469 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127471
7472 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017473 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127474
bnc691fda62016-08-12 00:43:167475 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527476 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047477 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127478
[email protected]49639fa2011-12-20 23:22:417479 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127480
bnc691fda62016-08-12 00:43:167481 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7482 callback2.callback());
robpercival214763f2016-07-01 23:27:017483 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127484
7485 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017486 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127487
bnc691fda62016-08-12 00:43:167488 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527489 ASSERT_TRUE(response);
7490 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127491 }
7492
7493 // ------------------------------------------------------------------------
7494
7495 // Transaction 2: Request another resource in digestive's protection space.
7496 // This will preemptively add an Authorization header which should have an
7497 // "nc" value of 2 (as compared to 1 in the first use.
7498 {
[email protected]3c32c5f2010-05-18 15:18:127499 HttpRequestInfo request;
7500 request.method = "GET";
7501 // Note that Transaction 1 was at /x/y/z, so this is in the same
7502 // protection space as digest.
bncce36dca22015-04-21 22:11:237503 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127504
bnc691fda62016-08-12 00:43:167505 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277506
[email protected]3c32c5f2010-05-18 15:18:127507 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237508 MockWrite(
7509 "GET /x/y/a/b HTTP/1.1\r\n"
7510 "Host: www.example.org\r\n"
7511 "Connection: keep-alive\r\n"
7512 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7513 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7514 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7515 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127516 };
7517
7518 // Sever accepts the authorization.
7519 MockRead data_reads1[] = {
7520 MockRead("HTTP/1.0 200 OK\r\n"),
7521 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067522 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127523 };
7524
7525 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7526 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077527 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127528
[email protected]49639fa2011-12-20 23:22:417529 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127530
tfarina42834112016-09-22 13:38:207531 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017532 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127533
7534 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017535 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127536
bnc691fda62016-08-12 00:43:167537 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527538 ASSERT_TRUE(response);
7539 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127540 }
7541}
7542
[email protected]89ceba9a2009-03-21 03:46:067543// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017544TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067545 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097546 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167547 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067548
7549 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167550 trans.read_buf_ = new IOBuffer(15);
7551 trans.read_buf_len_ = 15;
7552 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067553
7554 // Setup state in response_
bnc691fda62016-08-12 00:43:167555 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577556 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087557 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577558 response->response_time = base::Time::Now();
7559 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067560
7561 { // Setup state for response_.vary_data
7562 HttpRequestInfo request;
7563 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7564 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277565 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437566 request.extra_headers.SetHeader("Foo", "1");
7567 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507568 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067569 }
7570
7571 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167572 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067573
7574 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167575 EXPECT_FALSE(trans.read_buf_);
7576 EXPECT_EQ(0, trans.read_buf_len_);
7577 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527578 EXPECT_FALSE(response->auth_challenge);
7579 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047580 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087581 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577582 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067583}
7584
[email protected]bacff652009-03-31 17:50:337585// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017586TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337587 HttpRequestInfo request;
7588 request.method = "GET";
bncce36dca22015-04-21 22:11:237589 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337590
danakj1fd259a02016-04-16 03:17:097591 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167592 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277593
[email protected]bacff652009-03-31 17:50:337594 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237595 MockWrite(
7596 "GET / HTTP/1.1\r\n"
7597 "Host: www.example.org\r\n"
7598 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337599 };
7600
7601 MockRead data_reads[] = {
7602 MockRead("HTTP/1.0 200 OK\r\n"),
7603 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7604 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067605 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337606 };
7607
[email protected]5ecc992a42009-11-11 01:41:597608 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397609 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7610 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067611 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7612 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337613
[email protected]bb88e1d32013-05-03 23:11:077614 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7615 session_deps_.socket_factory->AddSocketDataProvider(&data);
7616 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7617 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337618
[email protected]49639fa2011-12-20 23:22:417619 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337620
tfarina42834112016-09-22 13:38:207621 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017622 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337623
7624 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017625 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337626
bnc691fda62016-08-12 00:43:167627 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017628 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337629
7630 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017631 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337632
bnc691fda62016-08-12 00:43:167633 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337634
wezca1070932016-05-26 20:30:527635 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337636 EXPECT_EQ(100, response->headers->GetContentLength());
7637}
7638
7639// Test HTTPS connections to a site with a bad certificate, going through a
7640// proxy
bncd16676a2016-07-20 16:23:017641TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037642 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337643
7644 HttpRequestInfo request;
7645 request.method = "GET";
bncce36dca22015-04-21 22:11:237646 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337647
7648 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177649 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7650 "Host: www.example.org:443\r\n"
7651 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337652 };
7653
7654 MockRead proxy_reads[] = {
7655 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067656 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337657 };
7658
7659 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177660 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7661 "Host: www.example.org:443\r\n"
7662 "Proxy-Connection: keep-alive\r\n\r\n"),
7663 MockWrite("GET / HTTP/1.1\r\n"
7664 "Host: www.example.org\r\n"
7665 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337666 };
7667
7668 MockRead data_reads[] = {
7669 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7670 MockRead("HTTP/1.0 200 OK\r\n"),
7671 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7672 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067673 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337674 };
7675
[email protected]31a2bfe2010-02-09 08:03:397676 StaticSocketDataProvider ssl_bad_certificate(
7677 proxy_reads, arraysize(proxy_reads),
7678 proxy_writes, arraysize(proxy_writes));
7679 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7680 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067681 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7682 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337683
[email protected]bb88e1d32013-05-03 23:11:077684 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7685 session_deps_.socket_factory->AddSocketDataProvider(&data);
7686 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7687 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337688
[email protected]49639fa2011-12-20 23:22:417689 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337690
7691 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077692 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337693
danakj1fd259a02016-04-16 03:17:097694 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167695 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:337696
tfarina42834112016-09-22 13:38:207697 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017698 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337699
7700 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017701 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337702
bnc691fda62016-08-12 00:43:167703 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017704 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337705
7706 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017707 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337708
bnc691fda62016-08-12 00:43:167709 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337710
wezca1070932016-05-26 20:30:527711 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337712 EXPECT_EQ(100, response->headers->GetContentLength());
7713 }
7714}
7715
[email protected]2df19bb2010-08-25 20:13:467716
7717// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:017718TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037719 session_deps_.proxy_service =
7720 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517721 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077722 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467723
7724 HttpRequestInfo request;
7725 request.method = "GET";
bncce36dca22015-04-21 22:11:237726 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467727
7728 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177729 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7730 "Host: www.example.org:443\r\n"
7731 "Proxy-Connection: keep-alive\r\n\r\n"),
7732 MockWrite("GET / HTTP/1.1\r\n"
7733 "Host: www.example.org\r\n"
7734 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467735 };
7736
7737 MockRead data_reads[] = {
7738 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7739 MockRead("HTTP/1.1 200 OK\r\n"),
7740 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7741 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067742 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467743 };
7744
7745 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7746 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067747 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7748 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467749
[email protected]bb88e1d32013-05-03 23:11:077750 session_deps_.socket_factory->AddSocketDataProvider(&data);
7751 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7752 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467753
[email protected]49639fa2011-12-20 23:22:417754 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467755
danakj1fd259a02016-04-16 03:17:097756 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167757 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:467758
tfarina42834112016-09-22 13:38:207759 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:467761
7762 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017763 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167764 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:467765
wezca1070932016-05-26 20:30:527766 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467767
tbansal2ecbbc72016-10-06 17:15:477768 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:467769 EXPECT_TRUE(response->headers->IsKeepAlive());
7770 EXPECT_EQ(200, response->headers->response_code());
7771 EXPECT_EQ(100, response->headers->GetContentLength());
7772 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207773
7774 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167775 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207776 TestLoadTimingNotReusedWithPac(load_timing_info,
7777 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467778}
7779
[email protected]511f6f52010-12-17 03:58:297780// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017781TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037782 session_deps_.proxy_service =
7783 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517784 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077785 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297786
7787 HttpRequestInfo request;
7788 request.method = "GET";
bncce36dca22015-04-21 22:11:237789 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297790
7791 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177792 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7793 "Host: www.example.org:443\r\n"
7794 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297795 };
7796
7797 MockRead data_reads[] = {
7798 MockRead("HTTP/1.1 302 Redirect\r\n"),
7799 MockRead("Location: http://login.example.com/\r\n"),
7800 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067801 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297802 };
7803
7804 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7805 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067806 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297807
[email protected]bb88e1d32013-05-03 23:11:077808 session_deps_.socket_factory->AddSocketDataProvider(&data);
7809 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297810
[email protected]49639fa2011-12-20 23:22:417811 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297812
danakj1fd259a02016-04-16 03:17:097813 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297815
tfarina42834112016-09-22 13:38:207816 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297818
7819 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017820 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167821 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297822
wezca1070932016-05-26 20:30:527823 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297824
7825 EXPECT_EQ(302, response->headers->response_code());
7826 std::string url;
7827 EXPECT_TRUE(response->headers->IsRedirect(&url));
7828 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207829
7830 // In the case of redirects from proxies, HttpNetworkTransaction returns
7831 // timing for the proxy connection instead of the connection to the host,
7832 // and no send / receive times.
7833 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7834 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:167835 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:207836
7837 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:197838 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207839
7840 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7841 EXPECT_LE(load_timing_info.proxy_resolve_start,
7842 load_timing_info.proxy_resolve_end);
7843 EXPECT_LE(load_timing_info.proxy_resolve_end,
7844 load_timing_info.connect_timing.connect_start);
7845 ExpectConnectTimingHasTimes(
7846 load_timing_info.connect_timing,
7847 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7848
7849 EXPECT_TRUE(load_timing_info.send_start.is_null());
7850 EXPECT_TRUE(load_timing_info.send_end.is_null());
7851 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297852}
7853
7854// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:017855TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037856 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297857
7858 HttpRequestInfo request;
7859 request.method = "GET";
bncce36dca22015-04-21 22:11:237860 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297861
bncdf80d44fd2016-07-15 20:27:417862 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237863 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417864 SpdySerializedFrame goaway(
[email protected]c10b20852013-05-15 21:29:207865 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297866 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417867 CreateMockWrite(conn, 0, SYNCHRONOUS),
7868 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297869 };
7870
7871 static const char* const kExtraHeaders[] = {
7872 "location",
7873 "http://login.example.com/",
7874 };
bnc42331402016-07-25 13:36:157875 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237876 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297877 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417878 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297879 };
7880
rch8e6c6c42015-05-01 14:05:137881 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7882 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067883 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367884 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297885
[email protected]bb88e1d32013-05-03 23:11:077886 session_deps_.socket_factory->AddSocketDataProvider(&data);
7887 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297888
[email protected]49639fa2011-12-20 23:22:417889 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297890
danakj1fd259a02016-04-16 03:17:097891 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167892 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297893
tfarina42834112016-09-22 13:38:207894 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297896
7897 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017898 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167899 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:297900
wezca1070932016-05-26 20:30:527901 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297902
7903 EXPECT_EQ(302, response->headers->response_code());
7904 std::string url;
7905 EXPECT_TRUE(response->headers->IsRedirect(&url));
7906 EXPECT_EQ("http://login.example.com/", url);
7907}
7908
[email protected]4eddbc732012-08-09 05:40:177909// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017910TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037911 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297912
7913 HttpRequestInfo request;
7914 request.method = "GET";
bncce36dca22015-04-21 22:11:237915 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297916
7917 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177918 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7919 "Host: www.example.org:443\r\n"
7920 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297921 };
7922
7923 MockRead data_reads[] = {
7924 MockRead("HTTP/1.1 404 Not Found\r\n"),
7925 MockRead("Content-Length: 23\r\n\r\n"),
7926 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067927 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297928 };
7929
7930 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7931 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067932 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297933
[email protected]bb88e1d32013-05-03 23:11:077934 session_deps_.socket_factory->AddSocketDataProvider(&data);
7935 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297936
[email protected]49639fa2011-12-20 23:22:417937 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297938
danakj1fd259a02016-04-16 03:17:097939 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167940 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297941
tfarina42834112016-09-22 13:38:207942 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017943 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297944
7945 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017946 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:297947
ttuttle960fcbf2016-04-19 13:26:327948 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297949}
7950
[email protected]4eddbc732012-08-09 05:40:177951// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:017952TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037953 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297954
7955 HttpRequestInfo request;
7956 request.method = "GET";
bncce36dca22015-04-21 22:11:237957 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297958
bncdf80d44fd2016-07-15 20:27:417959 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237960 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:417961 SpdySerializedFrame rst(
[email protected]c10b20852013-05-15 21:29:207962 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297963 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:417964 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:297965 };
7966
7967 static const char* const kExtraHeaders[] = {
7968 "location",
7969 "http://login.example.com/",
7970 };
bnc42331402016-07-25 13:36:157971 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:237972 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:417973 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:557974 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297975 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:417976 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:137977 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297978 };
7979
rch8e6c6c42015-05-01 14:05:137980 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7981 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067982 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:367983 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:297984
[email protected]bb88e1d32013-05-03 23:11:077985 session_deps_.socket_factory->AddSocketDataProvider(&data);
7986 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297987
[email protected]49639fa2011-12-20 23:22:417988 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297989
danakj1fd259a02016-04-16 03:17:097990 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167991 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:297992
tfarina42834112016-09-22 13:38:207993 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:297995
7996 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017997 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:297998
ttuttle960fcbf2016-04-19 13:26:327999 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298000}
8001
[email protected]0c5fb722012-02-28 11:50:358002// Test the request-challenge-retry sequence for basic auth, through
8003// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018004TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358005 HttpRequestInfo request;
8006 request.method = "GET";
bncce36dca22015-04-21 22:11:238007 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358008 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298009 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358010
8011 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038012 session_deps_.proxy_service =
8013 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518014 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078015 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098016 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358017
8018 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418019 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238020 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418021 SpdySerializedFrame rst(
[email protected]c10b20852013-05-15 21:29:208022 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388023 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358024
bnc691fda62016-08-12 00:43:168025 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358026 // be issuing -- the final header line contains the credentials.
8027 const char* const kAuthCredentials[] = {
8028 "proxy-authorization", "Basic Zm9vOmJhcg==",
8029 };
bncdf80d44fd2016-07-15 20:27:418030 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348031 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238032 HostPortPair("www.example.org", 443)));
8033 // fetch https://www.example.org/ via HTTP
8034 const char get[] =
8035 "GET / HTTP/1.1\r\n"
8036 "Host: www.example.org\r\n"
8037 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418038 SpdySerializedFrame wrapped_get(
8039 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358040
8041 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418042 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8043 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358044 };
8045
8046 // The proxy responds to the connect with a 407, using a persistent
8047 // connection.
thestig9d3bb0c2015-01-24 00:49:518048 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358049 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358050 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8051 };
bnc42331402016-07-25 13:36:158052 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418053 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358054
bnc42331402016-07-25 13:36:158055 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358056 const char resp[] = "HTTP/1.1 200 OK\r\n"
8057 "Content-Length: 5\r\n\r\n";
8058
bncdf80d44fd2016-07-15 20:27:418059 SpdySerializedFrame wrapped_get_resp(
8060 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8061 SpdySerializedFrame wrapped_body(
8062 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358063 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418064 CreateMockRead(conn_auth_resp, 1, ASYNC),
8065 CreateMockRead(conn_resp, 4, ASYNC),
8066 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8067 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138068 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358069 };
8070
rch8e6c6c42015-05-01 14:05:138071 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8072 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078073 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358074 // Negotiate SPDY to the proxy
8075 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368076 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078077 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358078 // Vanilla SSL to the server
8079 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078080 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358081
8082 TestCompletionCallback callback1;
8083
bnc691fda62016-08-12 00:43:168084 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508085 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:358086
8087 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018088 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358089
8090 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018091 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468092 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358093 log.GetEntries(&entries);
8094 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008095 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8096 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358097 ExpectLogContainsSomewhere(
8098 entries, pos,
mikecirone8b85c432016-09-08 19:11:008099 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8100 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358101
8102 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528103 ASSERT_TRUE(response);
8104 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358105 EXPECT_EQ(407, response->headers->response_code());
8106 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528107 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438108 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358109
8110 TestCompletionCallback callback2;
8111
8112 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8113 callback2.callback());
robpercival214763f2016-07-01 23:27:018114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358115
8116 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018117 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358118
8119 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528120 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358121
8122 EXPECT_TRUE(response->headers->IsKeepAlive());
8123 EXPECT_EQ(200, response->headers->response_code());
8124 EXPECT_EQ(5, response->headers->GetContentLength());
8125 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8126
8127 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528128 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358129
[email protected]029c83b62013-01-24 05:28:208130 LoadTimingInfo load_timing_info;
8131 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8132 TestLoadTimingNotReusedWithPac(load_timing_info,
8133 CONNECT_TIMING_HAS_SSL_TIMES);
8134
[email protected]0c5fb722012-02-28 11:50:358135 trans.reset();
8136 session->CloseAllConnections();
8137}
8138
[email protected]7c6f7ba2012-04-03 04:09:298139// Test that an explicitly trusted SPDY proxy can push a resource from an
8140// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018141TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158142 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098143 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158144 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8145 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298146 HttpRequestInfo request;
8147 HttpRequestInfo push_request;
8148
[email protected]7c6f7ba2012-04-03 04:09:298149 request.method = "GET";
bncce36dca22015-04-21 22:11:238150 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298151 push_request.method = "GET";
8152 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8153
tbansal28e68f82016-02-04 02:56:158154 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038155 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158156 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518157 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078158 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508159
inlinechan894515af2016-12-09 02:40:108160 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508161
danakj1fd259a02016-04-16 03:17:098162 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298163
bncdf80d44fd2016-07-15 20:27:418164 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458165 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358166 SpdySerializedFrame stream2_priority(
8167 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298168
8169 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418170 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358171 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298172 };
8173
bncdf80d44fd2016-07-15 20:27:418174 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158175 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298176
bncdf80d44fd2016-07-15 20:27:418177 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298178
bncdf80d44fd2016-07-15 20:27:418179 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558180 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438181 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418182 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8183 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298184
8185 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418186 CreateMockRead(stream1_reply, 1, ASYNC),
8187 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358188 CreateMockRead(stream1_body, 4, ASYNC),
8189 CreateMockRead(stream2_body, 5, ASYNC),
8190 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298191 };
8192
rch8e6c6c42015-05-01 14:05:138193 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8194 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078195 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298196 // Negotiate SPDY to the proxy
8197 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368198 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078199 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298200
bnc691fda62016-08-12 00:43:168201 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:298203 TestCompletionCallback callback;
8204 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018205 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298206
8207 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018208 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298209 const HttpResponseInfo* response = trans->GetResponseInfo();
8210
bnc691fda62016-08-12 00:43:168211 std::unique_ptr<HttpNetworkTransaction> push_trans(
[email protected]90499482013-06-01 00:39:508212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8213 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018214 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298215
8216 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018217 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298218 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8219
wezca1070932016-05-26 20:30:528220 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298221 EXPECT_TRUE(response->headers->IsKeepAlive());
8222
8223 EXPECT_EQ(200, response->headers->response_code());
8224 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8225
8226 std::string response_data;
8227 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018228 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298229 EXPECT_EQ("hello!", response_data);
8230
[email protected]029c83b62013-01-24 05:28:208231 LoadTimingInfo load_timing_info;
8232 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8233 TestLoadTimingNotReusedWithPac(load_timing_info,
8234 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8235
[email protected]7c6f7ba2012-04-03 04:09:298236 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528237 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298238 EXPECT_EQ(200, push_response->headers->response_code());
8239
8240 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018241 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298242 EXPECT_EQ("pushed", response_data);
8243
[email protected]029c83b62013-01-24 05:28:208244 LoadTimingInfo push_load_timing_info;
8245 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8246 TestLoadTimingReusedWithPac(push_load_timing_info);
8247 // The transactions should share a socket ID, despite being for different
8248 // origins.
8249 EXPECT_EQ(load_timing_info.socket_log_id,
8250 push_load_timing_info.socket_log_id);
8251
[email protected]7c6f7ba2012-04-03 04:09:298252 trans.reset();
8253 push_trans.reset();
8254 session->CloseAllConnections();
8255}
8256
[email protected]8c843192012-04-05 07:15:008257// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018258TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158259 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098260 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158261 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8262 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008263 HttpRequestInfo request;
8264
8265 request.method = "GET";
bncce36dca22015-04-21 22:11:238266 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008267
tbansal28e68f82016-02-04 02:56:158268 session_deps_.proxy_service =
8269 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518270 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078271 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508272
8273 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108274 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508275
danakj1fd259a02016-04-16 03:17:098276 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008277
bncdf80d44fd2016-07-15 20:27:418278 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458279 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008280
bncdf80d44fd2016-07-15 20:27:418281 SpdySerializedFrame push_rst(
[email protected]c10b20852013-05-15 21:29:208282 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008283
8284 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418285 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008286 };
8287
bncdf80d44fd2016-07-15 20:27:418288 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158289 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008290
bncdf80d44fd2016-07-15 20:27:418291 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008292
bncdf80d44fd2016-07-15 20:27:418293 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558294 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008295
8296 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418297 CreateMockRead(stream1_reply, 1, ASYNC),
8298 CreateMockRead(stream2_syn, 2, ASYNC),
8299 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598300 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008301 };
8302
rch8e6c6c42015-05-01 14:05:138303 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8304 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078305 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008306 // Negotiate SPDY to the proxy
8307 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368308 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078309 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008310
bnc691fda62016-08-12 00:43:168311 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508312 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:008313 TestCompletionCallback callback;
8314 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018315 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008316
8317 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018318 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008319 const HttpResponseInfo* response = trans->GetResponseInfo();
8320
wezca1070932016-05-26 20:30:528321 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008322 EXPECT_TRUE(response->headers->IsKeepAlive());
8323
8324 EXPECT_EQ(200, response->headers->response_code());
8325 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8326
8327 std::string response_data;
8328 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018329 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008330 EXPECT_EQ("hello!", response_data);
8331
8332 trans.reset();
8333 session->CloseAllConnections();
8334}
8335
tbansal8ef1d3e2016-02-03 04:05:428336// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8337// resources.
bncd16676a2016-07-20 16:23:018338TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158339 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098340 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158341 proxy_delegate->set_trusted_spdy_proxy(
8342 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8343
tbansal8ef1d3e2016-02-03 04:05:428344 HttpRequestInfo request;
8345
8346 request.method = "GET";
8347 request.url = GURL("http://www.example.org/");
8348
8349 // Configure against https proxy server "myproxy:70".
8350 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8351 BoundTestNetLog log;
8352 session_deps_.net_log = log.bound().net_log();
8353
8354 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108355 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:428356
danakj1fd259a02016-04-16 03:17:098357 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428358
bncdf80d44fd2016-07-15 20:27:418359 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458360 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358361 SpdySerializedFrame stream2_priority(
8362 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:428363
8364 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418365 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358366 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428367 };
8368
bncdf80d44fd2016-07-15 20:27:418369 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158370 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428371
bncdf80d44fd2016-07-15 20:27:418372 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:498373 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
8374
bncdf80d44fd2016-07-15 20:27:418375 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428376
bncdf80d44fd2016-07-15 20:27:418377 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158378 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428379
bncdf80d44fd2016-07-15 20:27:418380 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428381
8382 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418383 CreateMockRead(stream1_reply, 1, ASYNC),
8384 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358385 CreateMockRead(stream1_body, 4, ASYNC),
8386 CreateMockRead(stream2_body, 5, ASYNC),
8387 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:428388 };
8389
8390 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8391 arraysize(spdy_writes));
8392 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8393 // Negotiate SPDY to the proxy
8394 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368395 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428396 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8397
bnc691fda62016-08-12 00:43:168398 std::unique_ptr<HttpNetworkTransaction> trans(
tbansal8ef1d3e2016-02-03 04:05:428399 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8400 TestCompletionCallback callback;
8401 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018402 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428403
8404 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018405 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428406 const HttpResponseInfo* response = trans->GetResponseInfo();
8407
wezca1070932016-05-26 20:30:528408 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428409 EXPECT_TRUE(response->headers->IsKeepAlive());
8410
8411 EXPECT_EQ(200, response->headers->response_code());
8412 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8413
8414 std::string response_data;
8415 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018416 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428417 EXPECT_EQ("hello!", response_data);
8418
8419 trans.reset();
8420 session->CloseAllConnections();
8421}
8422
[email protected]2df19bb2010-08-25 20:13:468423// Test HTTPS connections to a site with a bad certificate, going through an
8424// HTTPS proxy
bncd16676a2016-07-20 16:23:018425TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038426 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468427
8428 HttpRequestInfo request;
8429 request.method = "GET";
bncce36dca22015-04-21 22:11:238430 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468431
8432 // Attempt to fetch the URL from a server with a bad cert
8433 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178434 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8435 "Host: www.example.org:443\r\n"
8436 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468437 };
8438
8439 MockRead bad_cert_reads[] = {
8440 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068441 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468442 };
8443
8444 // Attempt to fetch the URL with a good cert
8445 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178446 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8447 "Host: www.example.org:443\r\n"
8448 "Proxy-Connection: keep-alive\r\n\r\n"),
8449 MockWrite("GET / HTTP/1.1\r\n"
8450 "Host: www.example.org\r\n"
8451 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468452 };
8453
8454 MockRead good_cert_reads[] = {
8455 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8456 MockRead("HTTP/1.0 200 OK\r\n"),
8457 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8458 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068459 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468460 };
8461
8462 StaticSocketDataProvider ssl_bad_certificate(
8463 bad_cert_reads, arraysize(bad_cert_reads),
8464 bad_cert_writes, arraysize(bad_cert_writes));
8465 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8466 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068467 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8468 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468469
8470 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078471 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8472 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8473 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468474
8475 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078476 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8477 session_deps_.socket_factory->AddSocketDataProvider(&data);
8478 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468479
[email protected]49639fa2011-12-20 23:22:418480 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468481
danakj1fd259a02016-04-16 03:17:098482 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168483 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468484
tfarina42834112016-09-22 13:38:208485 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018486 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468487
8488 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018489 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468490
bnc691fda62016-08-12 00:43:168491 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018492 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468493
8494 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018495 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468496
bnc691fda62016-08-12 00:43:168497 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468498
wezca1070932016-05-26 20:30:528499 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468500 EXPECT_EQ(100, response->headers->GetContentLength());
8501}
8502
bncd16676a2016-07-20 16:23:018503TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428504 HttpRequestInfo request;
8505 request.method = "GET";
bncce36dca22015-04-21 22:11:238506 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438507 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8508 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428509
danakj1fd259a02016-04-16 03:17:098510 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168511 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278512
[email protected]1c773ea12009-04-28 19:58:428513 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238514 MockWrite(
8515 "GET / HTTP/1.1\r\n"
8516 "Host: www.example.org\r\n"
8517 "Connection: keep-alive\r\n"
8518 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428519 };
8520
8521 // Lastly, the server responds with the actual content.
8522 MockRead data_reads[] = {
8523 MockRead("HTTP/1.0 200 OK\r\n"),
8524 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8525 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068526 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428527 };
8528
[email protected]31a2bfe2010-02-09 08:03:398529 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8530 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078531 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428532
[email protected]49639fa2011-12-20 23:22:418533 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428534
tfarina42834112016-09-22 13:38:208535 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018536 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428537
8538 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018539 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428540}
8541
bncd16676a2016-07-20 16:23:018542TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298543 HttpRequestInfo request;
8544 request.method = "GET";
bncce36dca22015-04-21 22:11:238545 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298546 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8547 "Chromium Ultra Awesome X Edition");
8548
rdsmith82957ad2015-09-16 19:42:038549 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098550 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168551 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278552
[email protected]da81f132010-08-18 23:39:298553 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178554 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8555 "Host: www.example.org:443\r\n"
8556 "Proxy-Connection: keep-alive\r\n"
8557 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298558 };
8559 MockRead data_reads[] = {
8560 // Return an error, so the transaction stops here (this test isn't
8561 // interested in the rest).
8562 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8563 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8564 MockRead("Proxy-Connection: close\r\n\r\n"),
8565 };
8566
8567 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8568 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078569 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298570
[email protected]49639fa2011-12-20 23:22:418571 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298572
tfarina42834112016-09-22 13:38:208573 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018574 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298575
8576 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018577 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298578}
8579
bncd16676a2016-07-20 16:23:018580TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428581 HttpRequestInfo request;
8582 request.method = "GET";
bncce36dca22015-04-21 22:11:238583 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168584 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8585 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428586
danakj1fd259a02016-04-16 03:17:098587 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168588 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278589
[email protected]1c773ea12009-04-28 19:58:428590 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238591 MockWrite(
8592 "GET / HTTP/1.1\r\n"
8593 "Host: www.example.org\r\n"
8594 "Connection: keep-alive\r\n"
8595 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428596 };
8597
8598 // Lastly, the server responds with the actual content.
8599 MockRead data_reads[] = {
8600 MockRead("HTTP/1.0 200 OK\r\n"),
8601 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8602 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068603 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428604 };
8605
[email protected]31a2bfe2010-02-09 08:03:398606 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8607 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078608 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428609
[email protected]49639fa2011-12-20 23:22:418610 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428611
tfarina42834112016-09-22 13:38:208612 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428614
8615 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018616 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428617}
8618
bncd16676a2016-07-20 16:23:018619TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428620 HttpRequestInfo request;
8621 request.method = "POST";
bncce36dca22015-04-21 22:11:238622 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428623
danakj1fd259a02016-04-16 03:17:098624 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168625 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278626
[email protected]1c773ea12009-04-28 19:58:428627 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238628 MockWrite(
8629 "POST / HTTP/1.1\r\n"
8630 "Host: www.example.org\r\n"
8631 "Connection: keep-alive\r\n"
8632 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428633 };
8634
8635 // Lastly, the server responds with the actual content.
8636 MockRead data_reads[] = {
8637 MockRead("HTTP/1.0 200 OK\r\n"),
8638 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8639 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068640 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428641 };
8642
[email protected]31a2bfe2010-02-09 08:03:398643 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8644 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078645 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428646
[email protected]49639fa2011-12-20 23:22:418647 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428648
tfarina42834112016-09-22 13:38:208649 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428651
8652 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018653 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428654}
8655
bncd16676a2016-07-20 16:23:018656TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428657 HttpRequestInfo request;
8658 request.method = "PUT";
bncce36dca22015-04-21 22:11:238659 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428660
danakj1fd259a02016-04-16 03:17:098661 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168662 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278663
[email protected]1c773ea12009-04-28 19:58:428664 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238665 MockWrite(
8666 "PUT / HTTP/1.1\r\n"
8667 "Host: www.example.org\r\n"
8668 "Connection: keep-alive\r\n"
8669 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428670 };
8671
8672 // Lastly, the server responds with the actual content.
8673 MockRead data_reads[] = {
8674 MockRead("HTTP/1.0 200 OK\r\n"),
8675 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8676 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068677 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428678 };
8679
[email protected]31a2bfe2010-02-09 08:03:398680 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8681 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078682 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428683
[email protected]49639fa2011-12-20 23:22:418684 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428685
tfarina42834112016-09-22 13:38:208686 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018687 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428688
8689 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018690 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428691}
8692
bncd16676a2016-07-20 16:23:018693TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428694 HttpRequestInfo request;
8695 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238696 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428697
danakj1fd259a02016-04-16 03:17:098698 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168699 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278700
[email protected]1c773ea12009-04-28 19:58:428701 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138702 MockWrite("HEAD / HTTP/1.1\r\n"
8703 "Host: www.example.org\r\n"
8704 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428705 };
8706
8707 // Lastly, the server responds with the actual content.
8708 MockRead data_reads[] = {
8709 MockRead("HTTP/1.0 200 OK\r\n"),
8710 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8711 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068712 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428713 };
8714
[email protected]31a2bfe2010-02-09 08:03:398715 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8716 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078717 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428718
[email protected]49639fa2011-12-20 23:22:418719 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428720
tfarina42834112016-09-22 13:38:208721 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018722 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428723
8724 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018725 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428726}
8727
bncd16676a2016-07-20 16:23:018728TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428729 HttpRequestInfo request;
8730 request.method = "GET";
bncce36dca22015-04-21 22:11:238731 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428732 request.load_flags = LOAD_BYPASS_CACHE;
8733
danakj1fd259a02016-04-16 03:17:098734 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168735 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278736
[email protected]1c773ea12009-04-28 19:58:428737 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238738 MockWrite(
8739 "GET / HTTP/1.1\r\n"
8740 "Host: www.example.org\r\n"
8741 "Connection: keep-alive\r\n"
8742 "Pragma: no-cache\r\n"
8743 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428744 };
8745
8746 // Lastly, the server responds with the actual content.
8747 MockRead data_reads[] = {
8748 MockRead("HTTP/1.0 200 OK\r\n"),
8749 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8750 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068751 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428752 };
8753
[email protected]31a2bfe2010-02-09 08:03:398754 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8755 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078756 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428757
[email protected]49639fa2011-12-20 23:22:418758 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428759
tfarina42834112016-09-22 13:38:208760 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018761 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428762
8763 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018764 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428765}
8766
bncd16676a2016-07-20 16:23:018767TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428768 HttpRequestInfo request;
8769 request.method = "GET";
bncce36dca22015-04-21 22:11:238770 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428771 request.load_flags = LOAD_VALIDATE_CACHE;
8772
danakj1fd259a02016-04-16 03:17:098773 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168774 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278775
[email protected]1c773ea12009-04-28 19:58:428776 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238777 MockWrite(
8778 "GET / HTTP/1.1\r\n"
8779 "Host: www.example.org\r\n"
8780 "Connection: keep-alive\r\n"
8781 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428782 };
8783
8784 // Lastly, the server responds with the actual content.
8785 MockRead data_reads[] = {
8786 MockRead("HTTP/1.0 200 OK\r\n"),
8787 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8788 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068789 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428790 };
8791
[email protected]31a2bfe2010-02-09 08:03:398792 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8793 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078794 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428795
[email protected]49639fa2011-12-20 23:22:418796 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428797
tfarina42834112016-09-22 13:38:208798 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428800
8801 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018802 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428803}
8804
bncd16676a2016-07-20 16:23:018805TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428806 HttpRequestInfo request;
8807 request.method = "GET";
bncce36dca22015-04-21 22:11:238808 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438809 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428810
danakj1fd259a02016-04-16 03:17:098811 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168812 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278813
[email protected]1c773ea12009-04-28 19:58:428814 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238815 MockWrite(
8816 "GET / HTTP/1.1\r\n"
8817 "Host: www.example.org\r\n"
8818 "Connection: keep-alive\r\n"
8819 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428820 };
8821
8822 // Lastly, the server responds with the actual content.
8823 MockRead data_reads[] = {
8824 MockRead("HTTP/1.0 200 OK\r\n"),
8825 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8826 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068827 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428828 };
8829
[email protected]31a2bfe2010-02-09 08:03:398830 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8831 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078832 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428833
[email protected]49639fa2011-12-20 23:22:418834 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428835
tfarina42834112016-09-22 13:38:208836 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018837 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428838
8839 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018840 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428841}
8842
bncd16676a2016-07-20 16:23:018843TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478844 HttpRequestInfo request;
8845 request.method = "GET";
bncce36dca22015-04-21 22:11:238846 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438847 request.extra_headers.SetHeader("referer", "www.foo.com");
8848 request.extra_headers.SetHeader("hEllo", "Kitty");
8849 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478850
danakj1fd259a02016-04-16 03:17:098851 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168852 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278853
[email protected]270c6412010-03-29 22:02:478854 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238855 MockWrite(
8856 "GET / HTTP/1.1\r\n"
8857 "Host: www.example.org\r\n"
8858 "Connection: keep-alive\r\n"
8859 "referer: www.foo.com\r\n"
8860 "hEllo: Kitty\r\n"
8861 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478862 };
8863
8864 // Lastly, the server responds with the actual content.
8865 MockRead data_reads[] = {
8866 MockRead("HTTP/1.0 200 OK\r\n"),
8867 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8868 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068869 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478870 };
8871
8872 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8873 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078874 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478875
[email protected]49639fa2011-12-20 23:22:418876 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478877
tfarina42834112016-09-22 13:38:208878 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018879 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:478880
8881 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018882 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:478883}
8884
bncd16676a2016-07-20 16:23:018885TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278886 HttpRequestInfo request;
8887 request.method = "GET";
bncce36dca22015-04-21 22:11:238888 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278889
rdsmith82957ad2015-09-16 19:42:038890 session_deps_.proxy_service =
8891 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518892 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078893 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028894
danakj1fd259a02016-04-16 03:17:098895 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168896 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028897
[email protected]3cd17242009-06-23 02:59:028898 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8899 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8900
8901 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238902 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8903 MockWrite(
8904 "GET / HTTP/1.1\r\n"
8905 "Host: www.example.org\r\n"
8906 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028907
8908 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068909 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028910 MockRead("HTTP/1.0 200 OK\r\n"),
8911 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8912 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068913 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028914 };
8915
[email protected]31a2bfe2010-02-09 08:03:398916 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8917 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078918 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028919
[email protected]49639fa2011-12-20 23:22:418920 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028921
tfarina42834112016-09-22 13:38:208922 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:028924
8925 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018926 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028927
bnc691fda62016-08-12 00:43:168928 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528929 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028930
tbansal2ecbbc72016-10-06 17:15:478931 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:208932 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168933 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208934 TestLoadTimingNotReusedWithPac(load_timing_info,
8935 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8936
[email protected]3cd17242009-06-23 02:59:028937 std::string response_text;
bnc691fda62016-08-12 00:43:168938 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018939 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028940 EXPECT_EQ("Payload", response_text);
8941}
8942
bncd16676a2016-07-20 16:23:018943TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278944 HttpRequestInfo request;
8945 request.method = "GET";
bncce36dca22015-04-21 22:11:238946 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278947
rdsmith82957ad2015-09-16 19:42:038948 session_deps_.proxy_service =
8949 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518950 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078951 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028952
danakj1fd259a02016-04-16 03:17:098953 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168954 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028955
[email protected]3cd17242009-06-23 02:59:028956 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8957 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8958
8959 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238960 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8961 arraysize(write_buffer)),
8962 MockWrite(
8963 "GET / HTTP/1.1\r\n"
8964 "Host: www.example.org\r\n"
8965 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028966
8967 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018968 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8969 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358970 MockRead("HTTP/1.0 200 OK\r\n"),
8971 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8972 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068973 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358974 };
8975
[email protected]31a2bfe2010-02-09 08:03:398976 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8977 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078978 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358979
[email protected]8ddf8322012-02-23 18:08:068980 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078981 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358982
[email protected]49639fa2011-12-20 23:22:418983 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358984
tfarina42834112016-09-22 13:38:208985 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018986 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:358987
8988 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018989 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:358990
[email protected]029c83b62013-01-24 05:28:208991 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168992 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208993 TestLoadTimingNotReusedWithPac(load_timing_info,
8994 CONNECT_TIMING_HAS_SSL_TIMES);
8995
bnc691fda62016-08-12 00:43:168996 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528997 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:478998 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:358999
9000 std::string response_text;
bnc691fda62016-08-12 00:43:169001 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019002 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359003 EXPECT_EQ("Payload", response_text);
9004}
9005
bncd16676a2016-07-20 16:23:019006TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209007 HttpRequestInfo request;
9008 request.method = "GET";
bncce36dca22015-04-21 22:11:239009 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209010
rdsmith82957ad2015-09-16 19:42:039011 session_deps_.proxy_service =
9012 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519013 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079014 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209015
danakj1fd259a02016-04-16 03:17:099016 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169017 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209018
9019 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9020 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9021
9022 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239023 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9024 MockWrite(
9025 "GET / HTTP/1.1\r\n"
9026 "Host: www.example.org\r\n"
9027 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209028
9029 MockRead data_reads[] = {
9030 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9031 MockRead("HTTP/1.0 200 OK\r\n"),
9032 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9033 MockRead("Payload"),
9034 MockRead(SYNCHRONOUS, OK)
9035 };
9036
9037 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9038 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079039 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209040
9041 TestCompletionCallback callback;
9042
tfarina42834112016-09-22 13:38:209043 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019044 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209045
9046 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019047 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209048
bnc691fda62016-08-12 00:43:169049 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529050 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209051
9052 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169053 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209054 TestLoadTimingNotReused(load_timing_info,
9055 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9056
9057 std::string response_text;
bnc691fda62016-08-12 00:43:169058 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019059 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209060 EXPECT_EQ("Payload", response_text);
9061}
9062
bncd16676a2016-07-20 16:23:019063TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279064 HttpRequestInfo request;
9065 request.method = "GET";
bncce36dca22015-04-21 22:11:239066 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279067
rdsmith82957ad2015-09-16 19:42:039068 session_deps_.proxy_service =
9069 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519070 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079071 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359072
danakj1fd259a02016-04-16 03:17:099073 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169074 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359075
[email protected]e0c27be2009-07-15 13:09:359076 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9077 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379078 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239079 0x05, // Version
9080 0x01, // Command (CONNECT)
9081 0x00, // Reserved.
9082 0x03, // Address type (DOMAINNAME).
9083 0x0F, // Length of domain (15)
9084 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9085 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379086 };
[email protected]e0c27be2009-07-15 13:09:359087 const char kSOCKS5OkResponse[] =
9088 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9089
9090 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239091 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9092 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9093 MockWrite(
9094 "GET / HTTP/1.1\r\n"
9095 "Host: www.example.org\r\n"
9096 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359097
9098 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019099 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9100 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359101 MockRead("HTTP/1.0 200 OK\r\n"),
9102 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9103 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069104 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359105 };
9106
[email protected]31a2bfe2010-02-09 08:03:399107 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9108 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079109 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359110
[email protected]49639fa2011-12-20 23:22:419111 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359112
tfarina42834112016-09-22 13:38:209113 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359115
9116 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019117 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359118
bnc691fda62016-08-12 00:43:169119 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529120 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479121 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359122
[email protected]029c83b62013-01-24 05:28:209123 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169124 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209125 TestLoadTimingNotReusedWithPac(load_timing_info,
9126 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9127
[email protected]e0c27be2009-07-15 13:09:359128 std::string response_text;
bnc691fda62016-08-12 00:43:169129 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019130 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359131 EXPECT_EQ("Payload", response_text);
9132}
9133
bncd16676a2016-07-20 16:23:019134TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279135 HttpRequestInfo request;
9136 request.method = "GET";
bncce36dca22015-04-21 22:11:239137 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279138
rdsmith82957ad2015-09-16 19:42:039139 session_deps_.proxy_service =
9140 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519141 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079142 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359143
danakj1fd259a02016-04-16 03:17:099144 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169145 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359146
[email protected]e0c27be2009-07-15 13:09:359147 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9148 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379149 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239150 0x05, // Version
9151 0x01, // Command (CONNECT)
9152 0x00, // Reserved.
9153 0x03, // Address type (DOMAINNAME).
9154 0x0F, // Length of domain (15)
9155 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9156 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379157 };
9158
[email protected]e0c27be2009-07-15 13:09:359159 const char kSOCKS5OkResponse[] =
9160 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9161
9162 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239163 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9164 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9165 arraysize(kSOCKS5OkRequest)),
9166 MockWrite(
9167 "GET / HTTP/1.1\r\n"
9168 "Host: www.example.org\r\n"
9169 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359170
9171 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019172 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9173 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029174 MockRead("HTTP/1.0 200 OK\r\n"),
9175 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9176 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069177 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029178 };
9179
[email protected]31a2bfe2010-02-09 08:03:399180 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9181 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079182 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029183
[email protected]8ddf8322012-02-23 18:08:069184 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079185 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029186
[email protected]49639fa2011-12-20 23:22:419187 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029188
tfarina42834112016-09-22 13:38:209189 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019190 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029191
9192 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019193 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029194
bnc691fda62016-08-12 00:43:169195 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529196 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479197 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029198
[email protected]029c83b62013-01-24 05:28:209199 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169200 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209201 TestLoadTimingNotReusedWithPac(load_timing_info,
9202 CONNECT_TIMING_HAS_SSL_TIMES);
9203
[email protected]3cd17242009-06-23 02:59:029204 std::string response_text;
bnc691fda62016-08-12 00:43:169205 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019206 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029207 EXPECT_EQ("Payload", response_text);
9208}
9209
[email protected]448d4ca52012-03-04 04:12:239210namespace {
9211
[email protected]04e5be32009-06-26 20:00:319212// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069213
9214struct GroupNameTest {
9215 std::string proxy_server;
9216 std::string url;
9217 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189218 bool ssl;
[email protected]2d731a32010-04-29 01:04:069219};
9220
danakj1fd259a02016-04-16 03:17:099221std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079222 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099223 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069224
bnc525e175a2016-06-20 12:36:409225 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539226 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219227 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129228 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229229 http_server_properties->SetAlternativeService(
bncaa60ff402016-06-22 19:12:429230 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469231 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069232
9233 return session;
9234}
9235
mmenkee65e7af2015-10-13 17:16:429236int GroupNameTransactionHelper(const std::string& url,
9237 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069238 HttpRequestInfo request;
9239 request.method = "GET";
9240 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069241
bnc691fda62016-08-12 00:43:169242 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279243
[email protected]49639fa2011-12-20 23:22:419244 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069245
9246 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209247 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069248}
9249
[email protected]448d4ca52012-03-04 04:12:239250} // namespace
9251
bncd16676a2016-07-20 16:23:019252TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069253 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239254 {
9255 "", // unused
9256 "http://www.example.org/direct",
9257 "www.example.org:80",
9258 false,
9259 },
9260 {
9261 "", // unused
9262 "http://[2001:1418:13:1::25]/direct",
9263 "[2001:1418:13:1::25]:80",
9264 false,
9265 },
[email protected]04e5be32009-06-26 20:00:319266
bncce36dca22015-04-21 22:11:239267 // SSL Tests
9268 {
9269 "", // unused
9270 "https://www.example.org/direct_ssl",
9271 "ssl/www.example.org:443",
9272 true,
9273 },
9274 {
9275 "", // unused
9276 "https://[2001:1418:13:1::25]/direct",
9277 "ssl/[2001:1418:13:1::25]:443",
9278 true,
9279 },
9280 {
9281 "", // unused
bncaa60ff402016-06-22 19:12:429282 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239283 "ssl/host.with.alternate:443",
9284 true,
9285 },
[email protected]2d731a32010-04-29 01:04:069286 };
[email protected]2ff8b312010-04-26 22:20:549287
viettrungluue4a8b882014-10-16 06:17:389288 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039289 session_deps_.proxy_service =
9290 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099291 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409292 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069293
mmenkee65e7af2015-10-13 17:16:429294 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289295 CaptureGroupNameTransportSocketPool* transport_conn_pool =
9296 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139297 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349298 new CaptureGroupNameSSLSocketPool(NULL, NULL);
danakj1fd259a02016-04-16 03:17:099299 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449300 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029301 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9302 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489303 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069304
9305 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429306 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189307 if (tests[i].ssl)
9308 EXPECT_EQ(tests[i].expected_group_name,
9309 ssl_conn_pool->last_group_name_received());
9310 else
9311 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289312 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069313 }
[email protected]2d731a32010-04-29 01:04:069314}
9315
bncd16676a2016-07-20 16:23:019316TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069317 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239318 {
9319 "http_proxy",
9320 "http://www.example.org/http_proxy_normal",
9321 "www.example.org:80",
9322 false,
9323 },
[email protected]2d731a32010-04-29 01:04:069324
bncce36dca22015-04-21 22:11:239325 // SSL Tests
9326 {
9327 "http_proxy",
9328 "https://www.example.org/http_connect_ssl",
9329 "ssl/www.example.org:443",
9330 true,
9331 },
[email protected]af3490e2010-10-16 21:02:299332
bncce36dca22015-04-21 22:11:239333 {
9334 "http_proxy",
bncaa60ff402016-06-22 19:12:429335 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239336 "ssl/host.with.alternate:443",
9337 true,
9338 },
[email protected]45499252013-01-23 17:12:569339
bncce36dca22015-04-21 22:11:239340 {
9341 "http_proxy",
9342 "ftp://ftp.google.com/http_proxy_normal",
9343 "ftp/ftp.google.com:21",
9344 false,
9345 },
[email protected]2d731a32010-04-29 01:04:069346 };
9347
viettrungluue4a8b882014-10-16 06:17:389348 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039349 session_deps_.proxy_service =
9350 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099351 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409352 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069353
mmenkee65e7af2015-10-13 17:16:429354 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069355
[email protected]e60e47a2010-07-14 03:37:189356 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139357 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349358 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139359 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349360 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029361
danakj1fd259a02016-04-16 03:17:099362 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449363 new MockClientSocketPoolManager);
aviadef3442016-10-03 18:50:399364 mock_pool_manager->SetSocketPoolForHTTPProxy(
9365 proxy_host, base::WrapUnique(http_proxy_pool));
9366 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9367 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489368 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069369
9370 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429371 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189372 if (tests[i].ssl)
9373 EXPECT_EQ(tests[i].expected_group_name,
9374 ssl_conn_pool->last_group_name_received());
9375 else
9376 EXPECT_EQ(tests[i].expected_group_name,
9377 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069378 }
[email protected]2d731a32010-04-29 01:04:069379}
9380
bncd16676a2016-07-20 16:23:019381TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069382 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239383 {
9384 "socks4://socks_proxy:1080",
9385 "http://www.example.org/socks4_direct",
9386 "socks4/www.example.org:80",
9387 false,
9388 },
9389 {
9390 "socks5://socks_proxy:1080",
9391 "http://www.example.org/socks5_direct",
9392 "socks5/www.example.org:80",
9393 false,
9394 },
[email protected]2d731a32010-04-29 01:04:069395
bncce36dca22015-04-21 22:11:239396 // SSL Tests
9397 {
9398 "socks4://socks_proxy:1080",
9399 "https://www.example.org/socks4_ssl",
9400 "socks4/ssl/www.example.org:443",
9401 true,
9402 },
9403 {
9404 "socks5://socks_proxy:1080",
9405 "https://www.example.org/socks5_ssl",
9406 "socks5/ssl/www.example.org:443",
9407 true,
9408 },
[email protected]af3490e2010-10-16 21:02:299409
bncce36dca22015-04-21 22:11:239410 {
9411 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429412 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239413 "socks4/ssl/host.with.alternate:443",
9414 true,
9415 },
[email protected]04e5be32009-06-26 20:00:319416 };
9417
viettrungluue4a8b882014-10-16 06:17:389418 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039419 session_deps_.proxy_service =
9420 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099421 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409422 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029423
mmenkee65e7af2015-10-13 17:16:429424 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319425
[email protected]e60e47a2010-07-14 03:37:189426 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139427 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349428 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139429 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349430 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029431
danakj1fd259a02016-04-16 03:17:099432 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449433 new MockClientSocketPoolManager);
aviadef3442016-10-03 18:50:399434 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9435 proxy_host, base::WrapUnique(socks_conn_pool));
9436 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9437 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489438 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319439
bnc691fda62016-08-12 00:43:169440 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319441
[email protected]2d731a32010-04-29 01:04:069442 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429443 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189444 if (tests[i].ssl)
9445 EXPECT_EQ(tests[i].expected_group_name,
9446 ssl_conn_pool->last_group_name_received());
9447 else
9448 EXPECT_EQ(tests[i].expected_group_name,
9449 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319450 }
9451}
9452
bncd16676a2016-07-20 16:23:019453TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279454 HttpRequestInfo request;
9455 request.method = "GET";
bncce36dca22015-04-21 22:11:239456 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279457
rdsmith82957ad2015-09-16 19:42:039458 session_deps_.proxy_service =
9459 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329460
[email protected]69719062010-01-05 20:09:219461 // This simulates failure resolving all hostnames; that means we will fail
9462 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079463 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329464
danakj1fd259a02016-04-16 03:17:099465 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169466 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259467
[email protected]49639fa2011-12-20 23:22:419468 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259469
tfarina42834112016-09-22 13:38:209470 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019471 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259472
[email protected]9172a982009-06-06 00:30:259473 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019474 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259475}
9476
[email protected]685af592010-05-11 19:31:249477// Base test to make sure that when the load flags for a request specify to
9478// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029479void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079480 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279481 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109482 HttpRequestInfo request_info;
9483 request_info.method = "GET";
9484 request_info.load_flags = load_flags;
9485 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279486
[email protected]a2c2fb92009-07-18 07:31:049487 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:079488 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:329489
danakj1fd259a02016-04-16 03:17:099490 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169491 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289492
bncce36dca22015-04-21 22:11:239493 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289494 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299495 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109496 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079497 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239498 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109499 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209500 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019501 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479502 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019503 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289504
9505 // Verify that it was added to host cache, by doing a subsequent async lookup
9506 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109507 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079508 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239509 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109510 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209511 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019512 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289513
bncce36dca22015-04-21 22:11:239514 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289515 // we can tell if the next lookup hit the cache, or the "network".
9516 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239517 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289518
9519 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9520 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069521 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399522 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079523 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289524
[email protected]3b9cca42009-06-16 01:08:289525 // Run the request.
tfarina42834112016-09-22 13:38:209526 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019527 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419528 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289529
9530 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239531 // "www.example.org".
robpercival214763f2016-07-01 23:27:019532 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289533}
9534
[email protected]685af592010-05-11 19:31:249535// There are multiple load flags that should trigger the host cache bypass.
9536// Test each in isolation:
bncd16676a2016-07-20 16:23:019537TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249538 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9539}
9540
bncd16676a2016-07-20 16:23:019541TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249542 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9543}
9544
bncd16676a2016-07-20 16:23:019545TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249546 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9547}
9548
[email protected]0877e3d2009-10-17 22:29:579549// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019550TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579551 HttpRequestInfo request;
9552 request.method = "GET";
9553 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579554
9555 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069556 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579557 };
[email protected]31a2bfe2010-02-09 08:03:399558 StaticSocketDataProvider data(NULL, 0,
9559 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079560 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099561 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579562
[email protected]49639fa2011-12-20 23:22:419563 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579564
bnc691fda62016-08-12 00:43:169565 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579566
tfarina42834112016-09-22 13:38:209567 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019568 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579569
9570 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019571 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599572
9573 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169574 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599575 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579576}
9577
zmo9528c9f42015-08-04 22:12:089578// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019579TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579580 HttpRequestInfo request;
9581 request.method = "GET";
9582 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579583
9584 MockRead data_reads[] = {
9585 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069586 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579587 };
9588
[email protected]31a2bfe2010-02-09 08:03:399589 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079590 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099591 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579592
[email protected]49639fa2011-12-20 23:22:419593 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579594
bnc691fda62016-08-12 00:43:169595 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579596
tfarina42834112016-09-22 13:38:209597 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019598 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579599
9600 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019601 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089602
bnc691fda62016-08-12 00:43:169603 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529604 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089605
wezca1070932016-05-26 20:30:529606 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089607 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9608
9609 std::string response_data;
bnc691fda62016-08-12 00:43:169610 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019611 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089612 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599613
9614 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169615 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599616 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579617}
9618
9619// Make sure that a dropped connection while draining the body for auth
9620// restart does the right thing.
bncd16676a2016-07-20 16:23:019621TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579622 HttpRequestInfo request;
9623 request.method = "GET";
bncce36dca22015-04-21 22:11:239624 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579625
9626 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239627 MockWrite(
9628 "GET / HTTP/1.1\r\n"
9629 "Host: www.example.org\r\n"
9630 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579631 };
9632
9633 MockRead data_reads1[] = {
9634 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9635 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9636 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9637 MockRead("Content-Length: 14\r\n\r\n"),
9638 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069639 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579640 };
9641
[email protected]31a2bfe2010-02-09 08:03:399642 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9643 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079644 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579645
bnc691fda62016-08-12 00:43:169646 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579647 // be issuing -- the final header line contains the credentials.
9648 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239649 MockWrite(
9650 "GET / HTTP/1.1\r\n"
9651 "Host: www.example.org\r\n"
9652 "Connection: keep-alive\r\n"
9653 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579654 };
9655
9656 // Lastly, the server responds with the actual content.
9657 MockRead data_reads2[] = {
9658 MockRead("HTTP/1.1 200 OK\r\n"),
9659 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9660 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069661 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579662 };
9663
[email protected]31a2bfe2010-02-09 08:03:399664 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9665 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079666 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099667 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579668
[email protected]49639fa2011-12-20 23:22:419669 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579670
bnc691fda62016-08-12 00:43:169671 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509672
tfarina42834112016-09-22 13:38:209673 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019674 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579675
9676 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019677 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579678
bnc691fda62016-08-12 00:43:169679 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529680 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049681 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579682
[email protected]49639fa2011-12-20 23:22:419683 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579684
bnc691fda62016-08-12 00:43:169685 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579687
9688 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019689 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579690
bnc691fda62016-08-12 00:43:169691 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529692 ASSERT_TRUE(response);
9693 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579694 EXPECT_EQ(100, response->headers->GetContentLength());
9695}
9696
9697// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019698TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039699 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579700
9701 HttpRequestInfo request;
9702 request.method = "GET";
bncce36dca22015-04-21 22:11:239703 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579704
9705 MockRead proxy_reads[] = {
9706 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069707 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579708 };
9709
[email protected]31a2bfe2010-02-09 08:03:399710 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069711 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579712
[email protected]bb88e1d32013-05-03 23:11:079713 session_deps_.socket_factory->AddSocketDataProvider(&data);
9714 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579715
[email protected]49639fa2011-12-20 23:22:419716 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579717
[email protected]bb88e1d32013-05-03 23:11:079718 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579719
danakj1fd259a02016-04-16 03:17:099720 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169721 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579722
tfarina42834112016-09-22 13:38:209723 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019724 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579725
9726 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019727 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:579728}
9729
bncd16676a2016-07-20 16:23:019730TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469731 HttpRequestInfo request;
9732 request.method = "GET";
bncce36dca22015-04-21 22:11:239733 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469734
danakj1fd259a02016-04-16 03:17:099735 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169736 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279737
[email protected]e22e1362009-11-23 21:31:129738 MockRead data_reads[] = {
9739 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069740 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129741 };
[email protected]9492e4a2010-02-24 00:58:469742
9743 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079744 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469745
[email protected]49639fa2011-12-20 23:22:419746 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469747
tfarina42834112016-09-22 13:38:209748 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019749 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:469750
robpercival214763f2016-07-01 23:27:019751 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:469752
bnc691fda62016-08-12 00:43:169753 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529754 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469755
wezca1070932016-05-26 20:30:529756 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469757 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9758
9759 std::string response_data;
bnc691fda62016-08-12 00:43:169760 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019761 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:129762}
9763
bncd16676a2016-07-20 16:23:019764TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159765 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529766 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149767 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219768 UploadFileElementReader::ScopedOverridingContentLengthForTests
9769 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339770
danakj1fd259a02016-04-16 03:17:099771 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079772 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149773 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:079774 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229775 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279776
9777 HttpRequestInfo request;
9778 request.method = "POST";
bncce36dca22015-04-21 22:11:239779 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279780 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279781
danakj1fd259a02016-04-16 03:17:099782 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169783 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:339784
9785 MockRead data_reads[] = {
9786 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9787 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069788 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339789 };
[email protected]31a2bfe2010-02-09 08:03:399790 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079791 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339792
[email protected]49639fa2011-12-20 23:22:419793 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339794
tfarina42834112016-09-22 13:38:209795 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019796 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:339797
9798 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019799 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:339800
bnc691fda62016-08-12 00:43:169801 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529802 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339803
maksim.sisove869bf52016-06-23 17:11:529804 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339805
[email protected]dd3aa792013-07-16 19:10:239806 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339807}
9808
bncd16676a2016-07-20 16:23:019809TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159810 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529811 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369812 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:309813 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:369814 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119815 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369816
danakj1fd259a02016-04-16 03:17:099817 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079818 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149819 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:079820 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229821 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279822
9823 HttpRequestInfo request;
9824 request.method = "POST";
bncce36dca22015-04-21 22:11:239825 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279826 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279827
[email protected]999dd8c2013-11-12 06:45:549828 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099829 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169830 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:369831
[email protected]999dd8c2013-11-12 06:45:549832 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079833 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369834
[email protected]49639fa2011-12-20 23:22:419835 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369836
tfarina42834112016-09-22 13:38:209837 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019838 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:369839
9840 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019841 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:369842
[email protected]dd3aa792013-07-16 19:10:239843 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369844}
9845
bncd16676a2016-07-20 16:23:019846TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:039847 class FakeUploadElementReader : public UploadElementReader {
9848 public:
9849 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209850 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039851
9852 const CompletionCallback& callback() const { return callback_; }
9853
9854 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209855 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039856 callback_ = callback;
9857 return ERR_IO_PENDING;
9858 }
avibf0746c2015-12-09 19:53:149859 uint64_t GetContentLength() const override { return 0; }
9860 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209861 int Read(IOBuffer* buf,
9862 int buf_length,
9863 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039864 return ERR_FAILED;
9865 }
9866
9867 private:
9868 CompletionCallback callback_;
9869 };
9870
9871 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099872 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9873 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229874 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039875
9876 HttpRequestInfo request;
9877 request.method = "POST";
bncce36dca22015-04-21 22:11:239878 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039879 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:039880
danakj1fd259a02016-04-16 03:17:099881 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169882 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:419883 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039884
9885 StaticSocketDataProvider data;
9886 session_deps_.socket_factory->AddSocketDataProvider(&data);
9887
9888 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:209889 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019890 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:559891 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039892
9893 // Transaction is pending on request body initialization.
9894 ASSERT_FALSE(fake_reader->callback().is_null());
9895
9896 // Return Init()'s result after the transaction gets destroyed.
9897 trans.reset();
9898 fake_reader->callback().Run(OK); // Should not crash.
9899}
9900
[email protected]aeefc9e82010-02-19 16:18:279901// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:019902TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279903 HttpRequestInfo request;
9904 request.method = "GET";
bncce36dca22015-04-21 22:11:239905 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279906
9907 // First transaction will request a resource and receive a Basic challenge
9908 // with realm="first_realm".
9909 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239910 MockWrite(
9911 "GET / HTTP/1.1\r\n"
9912 "Host: www.example.org\r\n"
9913 "Connection: keep-alive\r\n"
9914 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279915 };
9916 MockRead data_reads1[] = {
9917 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9918 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9919 "\r\n"),
9920 };
9921
bnc691fda62016-08-12 00:43:169922 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:279923 // for first_realm. The server will reject and provide a challenge with
9924 // second_realm.
9925 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239926 MockWrite(
9927 "GET / HTTP/1.1\r\n"
9928 "Host: www.example.org\r\n"
9929 "Connection: keep-alive\r\n"
9930 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9931 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279932 };
9933 MockRead data_reads2[] = {
9934 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9935 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9936 "\r\n"),
9937 };
9938
9939 // This again fails, and goes back to first_realm. Make sure that the
9940 // entry is removed from cache.
9941 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239942 MockWrite(
9943 "GET / HTTP/1.1\r\n"
9944 "Host: www.example.org\r\n"
9945 "Connection: keep-alive\r\n"
9946 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9947 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279948 };
9949 MockRead data_reads3[] = {
9950 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9951 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9952 "\r\n"),
9953 };
9954
9955 // Try one last time (with the correct password) and get the resource.
9956 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239957 MockWrite(
9958 "GET / HTTP/1.1\r\n"
9959 "Host: www.example.org\r\n"
9960 "Connection: keep-alive\r\n"
9961 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9962 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279963 };
9964 MockRead data_reads4[] = {
9965 MockRead("HTTP/1.1 200 OK\r\n"
9966 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509967 "Content-Length: 5\r\n"
9968 "\r\n"
9969 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279970 };
9971
9972 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9973 data_writes1, arraysize(data_writes1));
9974 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9975 data_writes2, arraysize(data_writes2));
9976 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9977 data_writes3, arraysize(data_writes3));
9978 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9979 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079980 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9981 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9982 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9983 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279984
[email protected]49639fa2011-12-20 23:22:419985 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279986
danakj1fd259a02016-04-16 03:17:099987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169988 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509989
[email protected]aeefc9e82010-02-19 16:18:279990 // Issue the first request with Authorize headers. There should be a
9991 // password prompt for first_realm waiting to be filled in after the
9992 // transaction completes.
tfarina42834112016-09-22 13:38:209993 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:279995 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019996 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169997 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529998 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049999 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210000 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410001 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310002 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410003 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910004 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710005
10006 // Issue the second request with an incorrect password. There should be a
10007 // password prompt for second_realm waiting to be filled in after the
10008 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110009 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610010 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10011 callback2.callback());
robpercival214763f2016-07-01 23:27:0110012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710013 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110014 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610015 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210016 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410017 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210018 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410019 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310020 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410021 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910022 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710023
10024 // Issue the third request with another incorrect password. There should be
10025 // a password prompt for first_realm waiting to be filled in. If the password
10026 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10027 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110028 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610029 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10030 callback3.callback());
robpercival214763f2016-07-01 23:27:0110031 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710032 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110033 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610034 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210035 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410036 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210037 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410038 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310039 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410040 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910041 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710042
10043 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110044 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610045 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10046 callback4.callback());
robpercival214763f2016-07-01 23:27:0110047 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710048 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110049 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610050 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210051 ASSERT_TRUE(response);
10052 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710053}
10054
bncd16676a2016-07-20 16:23:0110055TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210056 MockRead data_reads[] = {
10057 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310058 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210059 MockRead("\r\n"),
10060 MockRead("hello world"),
10061 MockRead(SYNCHRONOUS, OK),
10062 };
10063
10064 HttpRequestInfo request;
10065 request.method = "GET";
bncb26024382016-06-29 02:39:4510066 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210067
10068 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210069 session_deps_.socket_factory->AddSocketDataProvider(&data);
10070
bncb26024382016-06-29 02:39:4510071 SSLSocketDataProvider ssl(ASYNC, OK);
10072 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10073
bncc958faa2015-07-31 18:14:5210074 TestCompletionCallback callback;
10075
danakj1fd259a02016-04-16 03:17:0910076 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610077 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210078
tfarina42834112016-09-22 13:38:2010079 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210081
bncb26024382016-06-29 02:39:4510082 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010083 HttpServerProperties* http_server_properties =
10084 session->http_server_properties();
bncc958faa2015-07-31 18:14:5210085 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010086 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210087 EXPECT_TRUE(alternative_service_vector.empty());
10088
robpercival214763f2016-07-01 23:27:0110089 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210090
bnc691fda62016-08-12 00:43:1610091 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210092 ASSERT_TRUE(response);
10093 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210094 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10095 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210096 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210097
10098 std::string response_data;
bnc691fda62016-08-12 00:43:1610099 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210100 EXPECT_EQ("hello world", response_data);
10101
10102 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010103 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210104 ASSERT_EQ(1u, alternative_service_vector.size());
bnc3472afd2016-11-17 15:27:2110105 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[0].protocol);
bncb26024382016-06-29 02:39:4510106 EXPECT_EQ("mail.example.org", alternative_service_vector[0].host);
bncc958faa2015-07-31 18:14:5210107 EXPECT_EQ(443, alternative_service_vector[0].port);
10108}
10109
bnce3dd56f2016-06-01 10:37:1110110// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110111TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110112 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110113 MockRead data_reads[] = {
10114 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310115 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110116 MockRead("\r\n"),
10117 MockRead("hello world"),
10118 MockRead(SYNCHRONOUS, OK),
10119 };
10120
10121 HttpRequestInfo request;
10122 request.method = "GET";
10123 request.url = GURL("http://www.example.org/");
10124 request.load_flags = 0;
10125
10126 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10127 session_deps_.socket_factory->AddSocketDataProvider(&data);
10128
10129 TestCompletionCallback callback;
10130
10131 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610132 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110133
10134 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010135 HttpServerProperties* http_server_properties =
10136 session->http_server_properties();
bnce3dd56f2016-06-01 10:37:1110137 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010138 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:1110139 EXPECT_TRUE(alternative_service_vector.empty());
10140
tfarina42834112016-09-22 13:38:2010141 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110142 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10143 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110144
bnc691fda62016-08-12 00:43:1610145 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110146 ASSERT_TRUE(response);
10147 ASSERT_TRUE(response->headers);
10148 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10149 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210150 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110151
10152 std::string response_data;
bnc691fda62016-08-12 00:43:1610153 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110154 EXPECT_EQ("hello world", response_data);
10155
10156 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010157 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:1110158 EXPECT_TRUE(alternative_service_vector.empty());
10159}
10160
bnc8bef8da22016-05-30 01:28:2510161// HTTP/2 Alternative Services should be disabled if alternative service
10162// hostname is different from that of origin.
10163// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110164TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510165 DisableHTTP2AlternativeServicesWithDifferentHost) {
bncb26024382016-06-29 02:39:4510166 session_deps_.enable_http2_alternative_service_with_different_host = false;
10167
bnc8bef8da22016-05-30 01:28:2510168 HttpRequestInfo request;
10169 request.method = "GET";
bncb26024382016-06-29 02:39:4510170 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510171 request.load_flags = 0;
10172
10173 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10174 StaticSocketDataProvider first_data;
10175 first_data.set_connect_data(mock_connect);
10176 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510177 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610178 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510179 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510180
10181 MockRead data_reads[] = {
10182 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10183 MockRead(ASYNC, OK),
10184 };
10185 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10186 0);
10187 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10188
10189 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10190
bnc525e175a2016-06-20 12:36:4010191 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510192 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110193 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10194 444);
bnc8bef8da22016-05-30 01:28:2510195 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10196 http_server_properties->SetAlternativeService(
10197 url::SchemeHostPort(request.url), alternative_service, expiration);
10198
bnc691fda62016-08-12 00:43:1610199 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510200 TestCompletionCallback callback;
10201
tfarina42834112016-09-22 13:38:2010202 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510203 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110204 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510205}
10206
bnce3dd56f2016-06-01 10:37:1110207// Regression test for https://crbug.com/615497:
10208// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110209TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110210 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110211 HttpRequestInfo request;
10212 request.method = "GET";
10213 request.url = GURL("http://www.example.org/");
10214 request.load_flags = 0;
10215
10216 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10217 StaticSocketDataProvider first_data;
10218 first_data.set_connect_data(mock_connect);
10219 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10220
10221 MockRead data_reads[] = {
10222 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10223 MockRead(ASYNC, OK),
10224 };
10225 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10226 0);
10227 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10228
10229 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10230
bnc525e175a2016-06-20 12:36:4010231 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110232 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110233 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110234 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10235 http_server_properties->SetAlternativeService(
10236 url::SchemeHostPort(request.url), alternative_service, expiration);
10237
bnc691fda62016-08-12 00:43:1610238 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110239 TestCompletionCallback callback;
10240
tfarina42834112016-09-22 13:38:2010241 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110242 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110243 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110244}
10245
bncd16676a2016-07-20 16:23:0110246TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810247 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910248 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010249 HttpServerProperties* http_server_properties =
10250 session->http_server_properties();
bncb26024382016-06-29 02:39:4510251 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110252 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810253 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc525e175a2016-06-20 12:36:4010254 http_server_properties->SetAlternativeService(
10255 test_server, alternative_service, expiration);
bnc4f575852015-10-14 18:35:0810256 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010257 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810258 EXPECT_EQ(1u, alternative_service_vector.size());
10259
10260 // Send a clear header.
10261 MockRead data_reads[] = {
10262 MockRead("HTTP/1.1 200 OK\r\n"),
10263 MockRead("Alt-Svc: clear\r\n"),
10264 MockRead("\r\n"),
10265 MockRead("hello world"),
10266 MockRead(SYNCHRONOUS, OK),
10267 };
10268 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10269 session_deps_.socket_factory->AddSocketDataProvider(&data);
10270
bncb26024382016-06-29 02:39:4510271 SSLSocketDataProvider ssl(ASYNC, OK);
10272 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10273
bnc4f575852015-10-14 18:35:0810274 HttpRequestInfo request;
10275 request.method = "GET";
bncb26024382016-06-29 02:39:4510276 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810277
10278 TestCompletionCallback callback;
10279
bnc691fda62016-08-12 00:43:1610280 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810281
tfarina42834112016-09-22 13:38:2010282 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110283 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810284
bnc691fda62016-08-12 00:43:1610285 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210286 ASSERT_TRUE(response);
10287 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810288 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10289 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210290 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810291
10292 std::string response_data;
bnc691fda62016-08-12 00:43:1610293 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810294 EXPECT_EQ("hello world", response_data);
10295
10296 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010297 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810298 EXPECT_TRUE(alternative_service_vector.empty());
10299}
10300
bncd16676a2016-07-20 16:23:0110301TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210302 MockRead data_reads[] = {
10303 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310304 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10305 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210306 MockRead("hello world"),
10307 MockRead(SYNCHRONOUS, OK),
10308 };
10309
10310 HttpRequestInfo request;
10311 request.method = "GET";
bncb26024382016-06-29 02:39:4510312 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210313
10314 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210315 session_deps_.socket_factory->AddSocketDataProvider(&data);
10316
bncb26024382016-06-29 02:39:4510317 SSLSocketDataProvider ssl(ASYNC, OK);
10318 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10319
bncc958faa2015-07-31 18:14:5210320 TestCompletionCallback callback;
10321
danakj1fd259a02016-04-16 03:17:0910322 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610323 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210324
tfarina42834112016-09-22 13:38:2010325 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110326 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210327
bncb26024382016-06-29 02:39:4510328 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010329 HttpServerProperties* http_server_properties =
10330 session->http_server_properties();
bncc958faa2015-07-31 18:14:5210331 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010332 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210333 EXPECT_TRUE(alternative_service_vector.empty());
10334
robpercival214763f2016-07-01 23:27:0110335 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210336
bnc691fda62016-08-12 00:43:1610337 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210338 ASSERT_TRUE(response);
10339 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210340 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10341 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210342 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210343
10344 std::string response_data;
bnc691fda62016-08-12 00:43:1610345 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210346 EXPECT_EQ("hello world", response_data);
10347
10348 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010349 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210350 ASSERT_EQ(2u, alternative_service_vector.size());
bnc3472afd2016-11-17 15:27:2110351 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[0].protocol);
bncc958faa2015-07-31 18:14:5210352 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
10353 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc3472afd2016-11-17 15:27:2110354 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[1].protocol);
bncc958faa2015-07-31 18:14:5210355 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
10356 EXPECT_EQ(1234, alternative_service_vector[1].port);
10357}
10358
bncd16676a2016-07-20 16:23:0110359TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610360 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210361 HostPortPair alternative("alternative.example.org", 443);
10362 std::string origin_url = "https://origin.example.org:443";
10363 std::string alternative_url = "https://alternative.example.org:443";
10364
10365 // Negotiate HTTP/1.1 with alternative.example.org.
10366 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610367 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210368 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10369
10370 // HTTP/1.1 data for request.
10371 MockWrite http_writes[] = {
10372 MockWrite("GET / HTTP/1.1\r\n"
10373 "Host: alternative.example.org\r\n"
10374 "Connection: keep-alive\r\n\r\n"),
10375 };
10376
10377 MockRead http_reads[] = {
10378 MockRead("HTTP/1.1 200 OK\r\n"
10379 "Content-Type: text/html; charset=iso-8859-1\r\n"
10380 "Content-Length: 40\r\n\r\n"
10381 "first HTTP/1.1 response from alternative"),
10382 };
10383 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10384 http_writes, arraysize(http_writes));
10385 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10386
10387 StaticSocketDataProvider data_refused;
10388 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10389 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10390
zhongyi3d4a55e72016-04-22 20:36:4610391 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010393 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210394 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110395 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0210396 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610397 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5010398 expiration);
zhongyi48704c182015-12-07 07:52:0210399 // Mark the QUIC alternative service as broken.
10400 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10401
zhongyi48704c182015-12-07 07:52:0210402 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610403 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210404 request.method = "GET";
10405 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210406 TestCompletionCallback callback;
10407 NetErrorDetails details;
10408 EXPECT_FALSE(details.quic_broken);
10409
tfarina42834112016-09-22 13:38:2010410 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610411 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210412 EXPECT_TRUE(details.quic_broken);
10413}
10414
bncd16676a2016-07-20 16:23:0110415TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610416 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210417 HostPortPair alternative1("alternative1.example.org", 443);
10418 HostPortPair alternative2("alternative2.example.org", 443);
10419 std::string origin_url = "https://origin.example.org:443";
10420 std::string alternative_url1 = "https://alternative1.example.org:443";
10421 std::string alternative_url2 = "https://alternative2.example.org:443";
10422
10423 // Negotiate HTTP/1.1 with alternative1.example.org.
10424 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610425 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210426 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10427
10428 // HTTP/1.1 data for request.
10429 MockWrite http_writes[] = {
10430 MockWrite("GET / HTTP/1.1\r\n"
10431 "Host: alternative1.example.org\r\n"
10432 "Connection: keep-alive\r\n\r\n"),
10433 };
10434
10435 MockRead http_reads[] = {
10436 MockRead("HTTP/1.1 200 OK\r\n"
10437 "Content-Type: text/html; charset=iso-8859-1\r\n"
10438 "Content-Length: 40\r\n\r\n"
10439 "first HTTP/1.1 response from alternative1"),
10440 };
10441 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10442 http_writes, arraysize(http_writes));
10443 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10444
10445 StaticSocketDataProvider data_refused;
10446 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10447 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10448
danakj1fd259a02016-04-16 03:17:0910449 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010450 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210451 session->http_server_properties();
10452
zhongyi3d4a55e72016-04-22 20:36:4610453 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210454 AlternativeServiceInfoVector alternative_service_info_vector;
10455 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10456
bnc3472afd2016-11-17 15:27:2110457 AlternativeService alternative_service1(kProtoQUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010458 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210459 expiration);
10460 alternative_service_info_vector.push_back(alternative_service_info1);
bnc3472afd2016-11-17 15:27:2110461 AlternativeService alternative_service2(kProtoQUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010462 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210463 expiration);
10464 alternative_service_info_vector.push_back(alternative_service_info2);
10465
10466 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610467 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210468
10469 // Mark one of the QUIC alternative service as broken.
10470 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
10471
10472 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610473 http_server_properties->GetAlternativeServices(server);
zhongyi48704c182015-12-07 07:52:0210474
zhongyi48704c182015-12-07 07:52:0210475 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610476 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210477 request.method = "GET";
10478 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210479 TestCompletionCallback callback;
10480 NetErrorDetails details;
10481 EXPECT_FALSE(details.quic_broken);
10482
tfarina42834112016-09-22 13:38:2010483 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610484 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210485 EXPECT_FALSE(details.quic_broken);
10486}
10487
bncd16676a2016-07-20 16:23:0110488TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210489 HttpRequestInfo request;
10490 request.method = "GET";
bncb26024382016-06-29 02:39:4510491 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210492
[email protected]d973e99a2012-02-17 21:02:3610493 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210494 StaticSocketDataProvider first_data;
10495 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710496 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510497 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610498 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510499 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210500
10501 MockRead data_reads[] = {
10502 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10503 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610504 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210505 };
10506 StaticSocketDataProvider second_data(
10507 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710508 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210509
danakj1fd259a02016-04-16 03:17:0910510 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210511
bnc525e175a2016-06-20 12:36:4010512 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310513 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610514 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110515 // Port must be < 1024, or the header will be ignored (since initial port was
10516 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010517 const AlternativeService alternative_service(
bnc3472afd2016-11-17 15:27:2110518 kProtoHTTP2, "www.example.org",
bncd9b132e2015-07-08 05:16:1010519 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210520 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610521 http_server_properties->SetAlternativeService(server, alternative_service,
10522 expiration);
[email protected]564b4912010-03-09 16:30:4210523
bnc691fda62016-08-12 00:43:1610524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110525 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210526
tfarina42834112016-09-22 13:38:2010527 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110528 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10529 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210530
bnc691fda62016-08-12 00:43:1610531 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210532 ASSERT_TRUE(response);
10533 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210534 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10535
10536 std::string response_data;
bnc691fda62016-08-12 00:43:1610537 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210538 EXPECT_EQ("hello world", response_data);
10539
bncd9b132e2015-07-08 05:16:1010540 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610541 http_server_properties->GetAlternativeServices(server);
bncd9b132e2015-07-08 05:16:1010542 ASSERT_EQ(1u, alternative_service_vector.size());
10543 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
10544 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
10545 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:4210546}
10547
bnc55ff9da2015-08-19 18:42:3510548// Ensure that we are not allowed to redirect traffic via an alternate protocol
10549// to an unrestricted (port >= 1024) when the original traffic was on a
10550// restricted port (port < 1024). Ensure that we can redirect in all other
10551// cases.
bncd16676a2016-07-20 16:23:0110552TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110553 HttpRequestInfo restricted_port_request;
10554 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510555 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110556 restricted_port_request.load_flags = 0;
10557
[email protected]d973e99a2012-02-17 21:02:3610558 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110559 StaticSocketDataProvider first_data;
10560 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710561 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110562
10563 MockRead data_reads[] = {
10564 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10565 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610566 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110567 };
10568 StaticSocketDataProvider second_data(
10569 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710570 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510571 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610572 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510573 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110574
danakj1fd259a02016-04-16 03:17:0910575 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110576
bnc525e175a2016-06-20 12:36:4010577 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310578 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110579 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110580 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10581 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210582 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210583 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610584 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010585 expiration);
[email protected]3912662a32011-10-04 00:51:1110586
bnc691fda62016-08-12 00:43:1610587 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110588 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110589
tfarina42834112016-09-22 13:38:2010590 int rv = trans.Start(&restricted_port_request, callback.callback(),
10591 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110592 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110593 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110594 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910595}
[email protected]3912662a32011-10-04 00:51:1110596
bnc55ff9da2015-08-19 18:42:3510597// Ensure that we are allowed to redirect traffic via an alternate protocol to
10598// an unrestricted (port >= 1024) when the original traffic was on a restricted
10599// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110600TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710601 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910602
10603 HttpRequestInfo restricted_port_request;
10604 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510605 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910606 restricted_port_request.load_flags = 0;
10607
10608 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10609 StaticSocketDataProvider first_data;
10610 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710611 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910612
10613 MockRead data_reads[] = {
10614 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10615 MockRead("hello world"),
10616 MockRead(ASYNC, OK),
10617 };
10618 StaticSocketDataProvider second_data(
10619 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710620 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510621 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610622 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910624
danakj1fd259a02016-04-16 03:17:0910625 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910626
bnc525e175a2016-06-20 12:36:4010627 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910628 session->http_server_properties();
10629 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110630 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10631 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210632 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210633 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610634 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010635 expiration);
[email protected]c54c6962013-02-01 04:53:1910636
bnc691fda62016-08-12 00:43:1610637 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910638 TestCompletionCallback callback;
10639
tfarina42834112016-09-22 13:38:2010640 EXPECT_EQ(ERR_IO_PENDING,
10641 trans.Start(&restricted_port_request, callback.callback(),
10642 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910643 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110644 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110645}
10646
bnc55ff9da2015-08-19 18:42:3510647// Ensure that we are not allowed to redirect traffic via an alternate protocol
10648// to an unrestricted (port >= 1024) when the original traffic was on a
10649// restricted port (port < 1024). Ensure that we can redirect in all other
10650// cases.
bncd16676a2016-07-20 16:23:0110651TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110652 HttpRequestInfo restricted_port_request;
10653 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510654 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110655 restricted_port_request.load_flags = 0;
10656
[email protected]d973e99a2012-02-17 21:02:3610657 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110658 StaticSocketDataProvider first_data;
10659 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710660 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110661
10662 MockRead data_reads[] = {
10663 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10664 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610665 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110666 };
10667 StaticSocketDataProvider second_data(
10668 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710669 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110670
bncb26024382016-06-29 02:39:4510671 SSLSocketDataProvider ssl(ASYNC, OK);
10672 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10673
danakj1fd259a02016-04-16 03:17:0910674 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110675
bnc525e175a2016-06-20 12:36:4010676 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310677 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110678 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110679 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10680 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210681 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210682 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610683 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010684 expiration);
[email protected]3912662a32011-10-04 00:51:1110685
bnc691fda62016-08-12 00:43:1610686 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110687 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110688
tfarina42834112016-09-22 13:38:2010689 int rv = trans.Start(&restricted_port_request, callback.callback(),
10690 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110691 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110692 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110693 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110694}
10695
bnc55ff9da2015-08-19 18:42:3510696// Ensure that we are not allowed to redirect traffic via an alternate protocol
10697// to an unrestricted (port >= 1024) when the original traffic was on a
10698// restricted port (port < 1024). Ensure that we can redirect in all other
10699// cases.
bncd16676a2016-07-20 16:23:0110700TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1110701 HttpRequestInfo unrestricted_port_request;
10702 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510703 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110704 unrestricted_port_request.load_flags = 0;
10705
[email protected]d973e99a2012-02-17 21:02:3610706 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110707 StaticSocketDataProvider first_data;
10708 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710709 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110710
10711 MockRead data_reads[] = {
10712 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10713 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610714 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110715 };
10716 StaticSocketDataProvider second_data(
10717 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710718 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510719 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610720 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510721 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110722
danakj1fd259a02016-04-16 03:17:0910723 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110724
bnc525e175a2016-06-20 12:36:4010725 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310726 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110727 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110728 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10729 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(),
tfarina42834112016-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;
bnc3472afd2016-11-17 15:27:2110777 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10778 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210779 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210780 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610781 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010782 expiration);
[email protected]3912662a32011-10-04 00:51:1110783
bnc691fda62016-08-12 00:43:1610784 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110785 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110786
bnc691fda62016-08-12 00:43:1610787 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010788 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110789 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110790 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0110791 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110792}
10793
bnc55ff9da2015-08-19 18:42:3510794// Ensure that we are not allowed to redirect traffic via an alternate protocol
10795// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10796// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0110797TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0210798 HttpRequestInfo request;
10799 request.method = "GET";
bncce36dca22015-04-21 22:11:2310800 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210801
10802 // The alternate protocol request will error out before we attempt to connect,
10803 // so only the standard HTTP request will try to connect.
10804 MockRead data_reads[] = {
10805 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10806 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610807 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210808 };
10809 StaticSocketDataProvider data(
10810 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710811 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210812
danakj1fd259a02016-04-16 03:17:0910813 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210814
bnc525e175a2016-06-20 12:36:4010815 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210816 session->http_server_properties();
10817 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2110818 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10819 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210820 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210821 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610822 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210823
bnc691fda62016-08-12 00:43:1610824 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0210825 TestCompletionCallback callback;
10826
tfarina42834112016-09-22 13:38:2010827 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110828 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0210829 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0110830 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210831
bnc691fda62016-08-12 00:43:1610832 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210833 ASSERT_TRUE(response);
10834 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210835 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10836
10837 std::string response_data;
bnc691fda62016-08-12 00:43:1610838 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210839 EXPECT_EQ("hello world", response_data);
10840}
10841
bncd16676a2016-07-20 16:23:0110842TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5410843 HttpRequestInfo request;
10844 request.method = "GET";
bncb26024382016-06-29 02:39:4510845 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410846
10847 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210848 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310849 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210850 MockRead("\r\n"),
10851 MockRead("hello world"),
10852 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10853 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410854
10855 StaticSocketDataProvider first_transaction(
10856 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710857 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4510858 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610859 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510860 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5410861
bnc032658ba2016-09-26 18:17:1510862 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5410863
bncdf80d44fd2016-07-15 20:27:4110864 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4510865 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110866 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410867
bnc42331402016-07-25 13:36:1510868 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110869 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410870 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110871 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410872 };
10873
rch8e6c6c42015-05-01 14:05:1310874 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10875 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710876 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410877
[email protected]d973e99a2012-02-17 21:02:3610878 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510879 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10880 NULL, 0, NULL, 0);
10881 hanging_non_alternate_protocol_socket.set_connect_data(
10882 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710883 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510884 &hanging_non_alternate_protocol_socket);
10885
[email protected]49639fa2011-12-20 23:22:4110886 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410887
danakj1fd259a02016-04-16 03:17:0910888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610889 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010890 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410891
tfarina42834112016-09-22 13:38:2010892 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10894 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410895
10896 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210897 ASSERT_TRUE(response);
10898 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410899 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10900
10901 std::string response_data;
robpercival214763f2016-07-01 23:27:0110902 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410903 EXPECT_EQ("hello world", response_data);
10904
[email protected]90499482013-06-01 00:39:5010905 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410906
tfarina42834112016-09-22 13:38:2010907 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110908 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10909 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410910
10911 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210912 ASSERT_TRUE(response);
10913 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210914 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310915 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210916 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410917
robpercival214763f2016-07-01 23:27:0110918 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410919 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410920}
10921
bncd16676a2016-07-20 16:23:0110922TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5510923 HttpRequestInfo request;
10924 request.method = "GET";
bncb26024382016-06-29 02:39:4510925 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510926
bncb26024382016-06-29 02:39:4510927 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5510928 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210929 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310930 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210931 MockRead("\r\n"),
10932 MockRead("hello world"),
10933 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10934 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510935 };
10936
bncb26024382016-06-29 02:39:4510937 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
10938 0);
10939 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5510940
bncb26024382016-06-29 02:39:4510941 SSLSocketDataProvider ssl_http11(ASYNC, OK);
10942 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
10943
10944 // Second transaction starts an alternative and a non-alternative Job.
10945 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3610946 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810947 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10948 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1810949 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10950
10951 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10952 hanging_socket2.set_connect_data(never_finishing_connect);
10953 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510954
bncb26024382016-06-29 02:39:4510955 // Third transaction starts an alternative and a non-alternative job.
10956 // The non-alternative job hangs, but the alternative one succeeds.
10957 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4110958 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4510959 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110960 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4510961 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5510962 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110963 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5510964 };
bnc42331402016-07-25 13:36:1510965 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110966 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1510967 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4110968 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510969 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110970 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
10971 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1310972 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510973 };
10974
rch8e6c6c42015-05-01 14:05:1310975 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10976 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710977 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510978
bnc032658ba2016-09-26 18:17:1510979 AddSSLSocketData();
bncb26024382016-06-29 02:39:4510980
mmenkecc2298e2015-12-07 18:20:1810981 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10982 hanging_socket3.set_connect_data(never_finishing_connect);
10983 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510984
danakj1fd259a02016-04-16 03:17:0910985 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110986 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010987 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510988
tfarina42834112016-09-22 13:38:2010989 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110990 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10991 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5510992
10993 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5210994 ASSERT_TRUE(response);
10995 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510996 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10997
10998 std::string response_data;
robpercival214763f2016-07-01 23:27:0110999 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511000 EXPECT_EQ("hello world", response_data);
11001
[email protected]49639fa2011-12-20 23:22:4111002 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011003 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011004 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111005 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511006
[email protected]49639fa2011-12-20 23:22:4111007 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011008 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011009 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111010 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511011
robpercival214763f2016-07-01 23:27:0111012 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11013 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511014
11015 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211016 ASSERT_TRUE(response);
11017 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211018 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511019 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211020 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111021 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511022 EXPECT_EQ("hello!", response_data);
11023
11024 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211025 ASSERT_TRUE(response);
11026 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211027 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511028 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211029 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111030 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511031 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511032}
11033
bncd16676a2016-07-20 16:23:0111034TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511035 HttpRequestInfo request;
11036 request.method = "GET";
bncb26024382016-06-29 02:39:4511037 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511038
11039 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211040 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311041 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211042 MockRead("\r\n"),
11043 MockRead("hello world"),
11044 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11045 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511046 };
11047
11048 StaticSocketDataProvider first_transaction(
11049 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711050 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511051
[email protected]8ddf8322012-02-23 18:08:0611052 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711053 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511054
[email protected]d973e99a2012-02-17 21:02:3611055 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511056 StaticSocketDataProvider hanging_alternate_protocol_socket(
11057 NULL, 0, NULL, 0);
11058 hanging_alternate_protocol_socket.set_connect_data(
11059 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711060 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511061 &hanging_alternate_protocol_socket);
11062
bncb26024382016-06-29 02:39:4511063 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811064 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11065 NULL, 0);
11066 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511067 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511068
[email protected]49639fa2011-12-20 23:22:4111069 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511070
danakj1fd259a02016-04-16 03:17:0911071 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611072 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011073 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511074
tfarina42834112016-09-22 13:38:2011075 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111076 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11077 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511078
11079 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211080 ASSERT_TRUE(response);
11081 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511082 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11083
11084 std::string response_data;
robpercival214763f2016-07-01 23:27:0111085 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511086 EXPECT_EQ("hello world", response_data);
11087
[email protected]90499482013-06-01 00:39:5011088 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511089
tfarina42834112016-09-22 13:38:2011090 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111091 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11092 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511093
11094 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211095 ASSERT_TRUE(response);
11096 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511097 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11098 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211099 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511100
robpercival214763f2016-07-01 23:27:0111101 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511102 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511103}
11104
[email protected]631f1322010-04-30 17:59:1111105class CapturingProxyResolver : public ProxyResolver {
11106 public:
sammce90c9212015-05-27 23:43:3511107 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011108 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111109
dchengb03027d2014-10-21 12:00:2011110 int GetProxyForURL(const GURL& url,
11111 ProxyInfo* results,
11112 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511113 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011114 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011115 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11116 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211117 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111118 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211119 return OK;
[email protected]631f1322010-04-30 17:59:1111120 }
11121
[email protected]24476402010-07-20 20:55:1711122 const std::vector<GURL>& resolved() const { return resolved_; }
11123
11124 private:
[email protected]631f1322010-04-30 17:59:1111125 std::vector<GURL> resolved_;
11126
11127 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11128};
11129
sammce64b2362015-04-29 03:50:2311130class CapturingProxyResolverFactory : public ProxyResolverFactory {
11131 public:
11132 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11133 : ProxyResolverFactory(false), resolver_(resolver) {}
11134
11135 int CreateProxyResolver(
11136 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911137 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311138 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911139 std::unique_ptr<Request>* request) override {
sammce64b2362015-04-29 03:50:2311140 resolver->reset(new ForwardingProxyResolver(resolver_));
11141 return OK;
11142 }
11143
11144 private:
11145 ProxyResolver* resolver_;
11146};
11147
bnc2e884782016-08-11 19:45:1911148// Test that proxy is resolved using the origin url,
11149// regardless of the alternative server.
11150TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11151 // Configure proxy to bypass www.example.org, which is the origin URL.
11152 ProxyConfig proxy_config;
11153 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11154 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11155 auto proxy_config_service =
11156 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config);
11157
11158 CapturingProxyResolver capturing_proxy_resolver;
11159 auto proxy_resolver_factory = base::MakeUnique<CapturingProxyResolverFactory>(
11160 &capturing_proxy_resolver);
11161
11162 TestNetLog net_log;
11163
11164 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11165 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11166 &net_log);
11167
11168 session_deps_.net_log = &net_log;
11169
11170 // Configure alternative service with a hostname that is not bypassed by the
11171 // proxy.
11172 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11173 HttpServerProperties* http_server_properties =
11174 session->http_server_properties();
11175 url::SchemeHostPort server("https", "www.example.org", 443);
11176 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111177 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911178 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11179 http_server_properties->SetAlternativeService(server, alternative_service,
11180 expiration);
11181
11182 // Non-alternative job should hang.
11183 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11184 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11185 nullptr, 0);
11186 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11187 session_deps_.socket_factory->AddSocketDataProvider(
11188 &hanging_alternate_protocol_socket);
11189
bnc032658ba2016-09-26 18:17:1511190 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911191
11192 HttpRequestInfo request;
11193 request.method = "GET";
11194 request.url = GURL("https://www.example.org/");
11195 request.load_flags = 0;
11196
11197 SpdySerializedFrame req(
11198 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11199
11200 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11201
11202 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11203 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11204 MockRead spdy_reads[] = {
11205 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11206 };
11207
11208 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11209 arraysize(spdy_writes));
11210 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11211
11212 TestCompletionCallback callback;
11213
11214 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11215
tfarina42834112016-09-22 13:38:2011216 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911217 EXPECT_THAT(callback.GetResult(rv), IsOk());
11218
11219 const HttpResponseInfo* response = trans.GetResponseInfo();
11220 ASSERT_TRUE(response);
11221 ASSERT_TRUE(response->headers);
11222 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11223 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211224 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911225
11226 std::string response_data;
11227 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11228 EXPECT_EQ("hello!", response_data);
11229
11230 // Origin host bypasses proxy, no resolution should have happened.
11231 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11232}
11233
bncd16676a2016-07-20 16:23:0111234TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111235 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211236 proxy_config.set_auto_detect(true);
11237 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111238
sammc5dd160c2015-04-02 02:43:1311239 CapturingProxyResolver capturing_proxy_resolver;
ricea2deef682016-09-09 08:04:0711240 session_deps_.proxy_service.reset(
11241 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
11242 base::MakeUnique<CapturingProxyResolverFactory>(
11243 &capturing_proxy_resolver),
11244 NULL));
vishal.b62985ca92015-04-17 08:45:5111245 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711246 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111247
11248 HttpRequestInfo request;
11249 request.method = "GET";
bncb26024382016-06-29 02:39:4511250 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111251
11252 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211253 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311254 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211255 MockRead("\r\n"),
11256 MockRead("hello world"),
11257 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11258 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111259 };
11260
11261 StaticSocketDataProvider first_transaction(
11262 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711263 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511264 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611265 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511266 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111267
bnc032658ba2016-09-26 18:17:1511268 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111269
bncdf80d44fd2016-07-15 20:27:4111270 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511271 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111272 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311273 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511274 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11275 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311276 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111277 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111278 };
11279
[email protected]d911f1b2010-05-05 22:39:4211280 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11281
bnc42331402016-07-25 13:36:1511282 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111283 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111284 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111285 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11286 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111287 };
11288
rch8e6c6c42015-05-01 14:05:1311289 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11290 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711291 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111292
[email protected]d973e99a2012-02-17 21:02:3611293 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511294 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11295 NULL, 0, NULL, 0);
11296 hanging_non_alternate_protocol_socket.set_connect_data(
11297 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711298 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511299 &hanging_non_alternate_protocol_socket);
11300
[email protected]49639fa2011-12-20 23:22:4111301 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111302
danakj1fd259a02016-04-16 03:17:0911303 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611304 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011305 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111306
tfarina42834112016-09-22 13:38:2011307 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111308 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11309 EXPECT_THAT(callback.WaitForResult(), IsOk());
11310
11311 const HttpResponseInfo* response = trans->GetResponseInfo();
11312 ASSERT_TRUE(response);
11313 ASSERT_TRUE(response->headers);
11314 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11315 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211316 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111317
11318 std::string response_data;
11319 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11320 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111321
[email protected]90499482013-06-01 00:39:5011322 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111323
tfarina42834112016-09-22 13:38:2011324 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111325 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11326 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111327
mmenkea2dcd3bf2016-08-16 21:49:4111328 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211329 ASSERT_TRUE(response);
11330 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211331 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311332 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211333 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111334
robpercival214763f2016-07-01 23:27:0111335 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111336 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511337 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11338 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311339 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311340 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311341 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111342
[email protected]029c83b62013-01-24 05:28:2011343 LoadTimingInfo load_timing_info;
11344 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11345 TestLoadTimingNotReusedWithPac(load_timing_info,
11346 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111347}
[email protected]631f1322010-04-30 17:59:1111348
bncd16676a2016-07-20 16:23:0111349TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811350 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411351 HttpRequestInfo request;
11352 request.method = "GET";
bncb26024382016-06-29 02:39:4511353 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411354
11355 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211356 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311357 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211358 MockRead("\r\n"),
11359 MockRead("hello world"),
11360 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411361 };
11362
11363 StaticSocketDataProvider first_transaction(
11364 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711365 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511366 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611367 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511368 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411369
bnc032658ba2016-09-26 18:17:1511370 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411371
bncdf80d44fd2016-07-15 20:27:4111372 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511373 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111374 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411375
bnc42331402016-07-25 13:36:1511376 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111377 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411378 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111379 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411380 };
11381
rch8e6c6c42015-05-01 14:05:1311382 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11383 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711384 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411385
[email protected]83039bb2011-12-09 18:43:5511386 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411387
danakj1fd259a02016-04-16 03:17:0911388 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411389
bnc691fda62016-08-12 00:43:1611390 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011391 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411392
tfarina42834112016-09-22 13:38:2011393 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111394 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11395 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411396
11397 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211398 ASSERT_TRUE(response);
11399 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411400 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11401
11402 std::string response_data;
robpercival214763f2016-07-01 23:27:0111403 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411404 EXPECT_EQ("hello world", response_data);
11405
11406 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511407 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011408 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311409 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711410 base::WeakPtr<SpdySession> spdy_session =
tfarina42834112016-09-22 13:38:2011411 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811412
[email protected]90499482013-06-01 00:39:5011413 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411414
tfarina42834112016-09-22 13:38:2011415 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111416 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11417 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411418
11419 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211420 ASSERT_TRUE(response);
11421 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211422 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311423 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211424 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411425
robpercival214763f2016-07-01 23:27:0111426 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411427 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211428}
11429
[email protected]044de0642010-06-17 10:42:1511430// GenerateAuthToken is a mighty big test.
11431// It tests all permutation of GenerateAuthToken behavior:
11432// - Synchronous and Asynchronous completion.
11433// - OK or error on completion.
11434// - Direct connection, non-authenticating proxy, and authenticating proxy.
11435// - HTTP or HTTPS backend (to include proxy tunneling).
11436// - Non-authenticating and authenticating backend.
11437//
[email protected]fe3b7dc2012-02-03 19:52:0911438// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511439// problems generating an auth token for an authenticating proxy, we don't
11440// need to test all permutations of the backend server).
11441//
11442// The test proceeds by going over each of the configuration cases, and
11443// potentially running up to three rounds in each of the tests. The TestConfig
11444// specifies both the configuration for the test as well as the expectations
11445// for the results.
bncd16676a2016-07-20 16:23:0111446TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011447 static const char kServer[] = "http://www.example.com";
11448 static const char kSecureServer[] = "https://www.example.com";
11449 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511450
11451 enum AuthTiming {
11452 AUTH_NONE,
11453 AUTH_SYNC,
11454 AUTH_ASYNC,
11455 };
11456
11457 const MockWrite kGet(
11458 "GET / HTTP/1.1\r\n"
11459 "Host: www.example.com\r\n"
11460 "Connection: keep-alive\r\n\r\n");
11461 const MockWrite kGetProxy(
11462 "GET http://www.example.com/ HTTP/1.1\r\n"
11463 "Host: www.example.com\r\n"
11464 "Proxy-Connection: keep-alive\r\n\r\n");
11465 const MockWrite kGetAuth(
11466 "GET / HTTP/1.1\r\n"
11467 "Host: www.example.com\r\n"
11468 "Connection: keep-alive\r\n"
11469 "Authorization: auth_token\r\n\r\n");
11470 const MockWrite kGetProxyAuth(
11471 "GET http://www.example.com/ HTTP/1.1\r\n"
11472 "Host: www.example.com\r\n"
11473 "Proxy-Connection: keep-alive\r\n"
11474 "Proxy-Authorization: auth_token\r\n\r\n");
11475 const MockWrite kGetAuthThroughProxy(
11476 "GET http://www.example.com/ HTTP/1.1\r\n"
11477 "Host: www.example.com\r\n"
11478 "Proxy-Connection: keep-alive\r\n"
11479 "Authorization: auth_token\r\n\r\n");
11480 const MockWrite kGetAuthWithProxyAuth(
11481 "GET http://www.example.com/ HTTP/1.1\r\n"
11482 "Host: www.example.com\r\n"
11483 "Proxy-Connection: keep-alive\r\n"
11484 "Proxy-Authorization: auth_token\r\n"
11485 "Authorization: auth_token\r\n\r\n");
11486 const MockWrite kConnect(
11487 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711488 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511489 "Proxy-Connection: keep-alive\r\n\r\n");
11490 const MockWrite kConnectProxyAuth(
11491 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711492 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511493 "Proxy-Connection: keep-alive\r\n"
11494 "Proxy-Authorization: auth_token\r\n\r\n");
11495
11496 const MockRead kSuccess(
11497 "HTTP/1.1 200 OK\r\n"
11498 "Content-Type: text/html; charset=iso-8859-1\r\n"
11499 "Content-Length: 3\r\n\r\n"
11500 "Yes");
11501 const MockRead kFailure(
11502 "Should not be called.");
11503 const MockRead kServerChallenge(
11504 "HTTP/1.1 401 Unauthorized\r\n"
11505 "WWW-Authenticate: Mock realm=server\r\n"
11506 "Content-Type: text/html; charset=iso-8859-1\r\n"
11507 "Content-Length: 14\r\n\r\n"
11508 "Unauthorized\r\n");
11509 const MockRead kProxyChallenge(
11510 "HTTP/1.1 407 Unauthorized\r\n"
11511 "Proxy-Authenticate: Mock realm=proxy\r\n"
11512 "Proxy-Connection: close\r\n"
11513 "Content-Type: text/html; charset=iso-8859-1\r\n"
11514 "Content-Length: 14\r\n\r\n"
11515 "Unauthorized\r\n");
11516 const MockRead kProxyConnected(
11517 "HTTP/1.1 200 Connection Established\r\n\r\n");
11518
11519 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11520 // no constructors, but the C++ compiler on Windows warns about
11521 // unspecified data in compound literals. So, moved to using constructors,
11522 // and TestRound's created with the default constructor should not be used.
11523 struct TestRound {
11524 TestRound()
11525 : expected_rv(ERR_UNEXPECTED),
11526 extra_write(NULL),
11527 extra_read(NULL) {
11528 }
11529 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11530 int expected_rv_arg)
11531 : write(write_arg),
11532 read(read_arg),
11533 expected_rv(expected_rv_arg),
11534 extra_write(NULL),
11535 extra_read(NULL) {
11536 }
11537 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11538 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111539 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511540 : write(write_arg),
11541 read(read_arg),
11542 expected_rv(expected_rv_arg),
11543 extra_write(extra_write_arg),
11544 extra_read(extra_read_arg) {
11545 }
11546 MockWrite write;
11547 MockRead read;
11548 int expected_rv;
11549 const MockWrite* extra_write;
11550 const MockRead* extra_read;
11551 };
11552
11553 static const int kNoSSL = 500;
11554
11555 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111556 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111557 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511558 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111559 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111560 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511561 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111562 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511563 int num_auth_rounds;
11564 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611565 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511566 } test_configs[] = {
asankac93076192016-10-03 15:46:0211567 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111568 {__LINE__,
11569 nullptr,
asankac93076192016-10-03 15:46:0211570 AUTH_NONE,
11571 OK,
11572 kServer,
11573 AUTH_NONE,
11574 OK,
11575 1,
11576 kNoSSL,
11577 {TestRound(kGet, kSuccess, OK)}},
11578 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111579 {__LINE__,
11580 nullptr,
asankac93076192016-10-03 15:46:0211581 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)}},
asanka463ca4262016-11-16 02:34:3111590 {__LINE__,
11591 nullptr,
asankac93076192016-10-03 15:46:0211592 AUTH_NONE,
11593 OK,
11594 kServer,
11595 AUTH_SYNC,
11596 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611597 3,
11598 kNoSSL,
11599 {TestRound(kGet, kServerChallenge, OK),
11600 TestRound(kGet, kServerChallenge, OK),
11601 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111602 {__LINE__,
11603 nullptr,
asankae2257db2016-10-11 22:03:1611604 AUTH_NONE,
11605 OK,
11606 kServer,
11607 AUTH_SYNC,
11608 ERR_UNSUPPORTED_AUTH_SCHEME,
11609 2,
11610 kNoSSL,
11611 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111612 {__LINE__,
11613 nullptr,
asankae2257db2016-10-11 22:03:1611614 AUTH_NONE,
11615 OK,
11616 kServer,
11617 AUTH_SYNC,
11618 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11619 2,
11620 kNoSSL,
11621 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111622 {__LINE__,
11623 kProxy,
asankae2257db2016-10-11 22:03:1611624 AUTH_SYNC,
11625 ERR_FAILED,
11626 kServer,
11627 AUTH_NONE,
11628 OK,
11629 2,
11630 kNoSSL,
11631 {TestRound(kGetProxy, kProxyChallenge, OK),
11632 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111633 {__LINE__,
11634 kProxy,
asankae2257db2016-10-11 22:03:1611635 AUTH_ASYNC,
11636 ERR_FAILED,
11637 kServer,
11638 AUTH_NONE,
11639 OK,
11640 2,
11641 kNoSSL,
11642 {TestRound(kGetProxy, kProxyChallenge, OK),
11643 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111644 {__LINE__,
11645 nullptr,
asankae2257db2016-10-11 22:03:1611646 AUTH_NONE,
11647 OK,
11648 kServer,
11649 AUTH_SYNC,
11650 ERR_FAILED,
asankac93076192016-10-03 15:46:0211651 2,
11652 kNoSSL,
11653 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611654 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111655 {__LINE__,
11656 nullptr,
asankae2257db2016-10-11 22:03:1611657 AUTH_NONE,
11658 OK,
11659 kServer,
11660 AUTH_ASYNC,
11661 ERR_FAILED,
11662 2,
11663 kNoSSL,
11664 {TestRound(kGet, kServerChallenge, OK),
11665 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111666 {__LINE__,
11667 nullptr,
asankac93076192016-10-03 15:46:0211668 AUTH_NONE,
11669 OK,
11670 kServer,
11671 AUTH_ASYNC,
11672 OK,
11673 2,
11674 kNoSSL,
11675 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511676 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111677 {__LINE__,
11678 nullptr,
asankac93076192016-10-03 15:46:0211679 AUTH_NONE,
11680 OK,
11681 kServer,
11682 AUTH_ASYNC,
11683 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611684 3,
asankac93076192016-10-03 15:46:0211685 kNoSSL,
11686 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611687 // The second round uses a HttpAuthHandlerMock that always succeeds.
11688 TestRound(kGet, kServerChallenge, OK),
11689 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211690 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111691 {__LINE__,
11692 kProxy,
asankac93076192016-10-03 15:46:0211693 AUTH_NONE,
11694 OK,
11695 kServer,
11696 AUTH_NONE,
11697 OK,
11698 1,
11699 kNoSSL,
11700 {TestRound(kGetProxy, kSuccess, OK)}},
11701 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111702 {__LINE__,
11703 kProxy,
asankac93076192016-10-03 15:46:0211704 AUTH_NONE,
11705 OK,
11706 kServer,
11707 AUTH_SYNC,
11708 OK,
11709 2,
11710 kNoSSL,
11711 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511712 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111713 {__LINE__,
11714 kProxy,
asankac93076192016-10-03 15:46:0211715 AUTH_NONE,
11716 OK,
11717 kServer,
11718 AUTH_SYNC,
11719 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611720 3,
asankac93076192016-10-03 15:46:0211721 kNoSSL,
11722 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611723 TestRound(kGetProxy, kServerChallenge, OK),
11724 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111725 {__LINE__,
11726 kProxy,
asankac93076192016-10-03 15:46:0211727 AUTH_NONE,
11728 OK,
11729 kServer,
11730 AUTH_ASYNC,
11731 OK,
11732 2,
11733 kNoSSL,
11734 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511735 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111736 {__LINE__,
11737 kProxy,
asankac93076192016-10-03 15:46:0211738 AUTH_NONE,
11739 OK,
11740 kServer,
11741 AUTH_ASYNC,
11742 ERR_INVALID_AUTH_CREDENTIALS,
11743 2,
11744 kNoSSL,
11745 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611746 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211747 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111748 {__LINE__,
11749 kProxy,
asankac93076192016-10-03 15:46:0211750 AUTH_SYNC,
11751 OK,
11752 kServer,
11753 AUTH_NONE,
11754 OK,
11755 2,
11756 kNoSSL,
11757 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511758 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111759 {__LINE__,
11760 kProxy,
asankac93076192016-10-03 15:46:0211761 AUTH_SYNC,
11762 ERR_INVALID_AUTH_CREDENTIALS,
11763 kServer,
11764 AUTH_NONE,
11765 OK,
11766 2,
11767 kNoSSL,
11768 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611769 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111770 {__LINE__,
11771 kProxy,
asankac93076192016-10-03 15:46:0211772 AUTH_ASYNC,
11773 OK,
11774 kServer,
11775 AUTH_NONE,
11776 OK,
11777 2,
11778 kNoSSL,
11779 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511780 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111781 {__LINE__,
11782 kProxy,
asankac93076192016-10-03 15:46:0211783 AUTH_ASYNC,
11784 ERR_INVALID_AUTH_CREDENTIALS,
11785 kServer,
11786 AUTH_NONE,
11787 OK,
11788 2,
11789 kNoSSL,
11790 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611791 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111792 {__LINE__,
11793 kProxy,
11794 AUTH_ASYNC,
11795 ERR_INVALID_AUTH_CREDENTIALS,
11796 kServer,
11797 AUTH_NONE,
11798 OK,
11799 3,
11800 kNoSSL,
11801 {TestRound(kGetProxy, kProxyChallenge, OK),
11802 TestRound(kGetProxy, kProxyChallenge, OK),
11803 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211804 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111805 {__LINE__,
11806 kProxy,
asankac93076192016-10-03 15:46:0211807 AUTH_SYNC,
11808 OK,
11809 kServer,
11810 AUTH_SYNC,
11811 OK,
11812 3,
11813 kNoSSL,
11814 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511815 TestRound(kGetProxyAuth, kServerChallenge, OK),
11816 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111817 {__LINE__,
11818 kProxy,
asankac93076192016-10-03 15:46:0211819 AUTH_SYNC,
11820 OK,
11821 kServer,
11822 AUTH_SYNC,
11823 ERR_INVALID_AUTH_CREDENTIALS,
11824 3,
11825 kNoSSL,
11826 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511827 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611828 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111829 {__LINE__,
11830 kProxy,
asankac93076192016-10-03 15:46:0211831 AUTH_ASYNC,
11832 OK,
11833 kServer,
11834 AUTH_SYNC,
11835 OK,
11836 3,
11837 kNoSSL,
11838 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511839 TestRound(kGetProxyAuth, kServerChallenge, OK),
11840 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111841 {__LINE__,
11842 kProxy,
asankac93076192016-10-03 15:46:0211843 AUTH_ASYNC,
11844 OK,
11845 kServer,
11846 AUTH_SYNC,
11847 ERR_INVALID_AUTH_CREDENTIALS,
11848 3,
11849 kNoSSL,
11850 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511851 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611852 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111853 {__LINE__,
11854 kProxy,
asankac93076192016-10-03 15:46:0211855 AUTH_SYNC,
11856 OK,
11857 kServer,
11858 AUTH_ASYNC,
11859 OK,
11860 3,
11861 kNoSSL,
11862 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511863 TestRound(kGetProxyAuth, kServerChallenge, OK),
11864 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111865 {__LINE__,
11866 kProxy,
11867 AUTH_SYNC,
11868 ERR_INVALID_AUTH_CREDENTIALS,
11869 kServer,
11870 AUTH_ASYNC,
11871 OK,
11872 4,
11873 kNoSSL,
11874 {TestRound(kGetProxy, kProxyChallenge, OK),
11875 TestRound(kGetProxy, kProxyChallenge, OK),
11876 TestRound(kGetProxyAuth, kServerChallenge, OK),
11877 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11878 {__LINE__,
11879 kProxy,
asankac93076192016-10-03 15:46:0211880 AUTH_SYNC,
11881 OK,
11882 kServer,
11883 AUTH_ASYNC,
11884 ERR_INVALID_AUTH_CREDENTIALS,
11885 3,
11886 kNoSSL,
11887 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511888 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611889 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111890 {__LINE__,
11891 kProxy,
asankac93076192016-10-03 15:46:0211892 AUTH_ASYNC,
11893 OK,
11894 kServer,
11895 AUTH_ASYNC,
11896 OK,
11897 3,
11898 kNoSSL,
11899 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511900 TestRound(kGetProxyAuth, kServerChallenge, OK),
11901 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111902 {__LINE__,
11903 kProxy,
asankac93076192016-10-03 15:46:0211904 AUTH_ASYNC,
11905 OK,
11906 kServer,
11907 AUTH_ASYNC,
11908 ERR_INVALID_AUTH_CREDENTIALS,
11909 3,
11910 kNoSSL,
11911 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511912 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611913 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111914 {__LINE__,
11915 kProxy,
11916 AUTH_ASYNC,
11917 ERR_INVALID_AUTH_CREDENTIALS,
11918 kServer,
11919 AUTH_ASYNC,
11920 ERR_INVALID_AUTH_CREDENTIALS,
11921 4,
11922 kNoSSL,
11923 {TestRound(kGetProxy, kProxyChallenge, OK),
11924 TestRound(kGetProxy, kProxyChallenge, OK),
11925 TestRound(kGetProxyAuth, kServerChallenge, OK),
11926 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211927 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111928 {__LINE__,
11929 nullptr,
asankac93076192016-10-03 15:46:0211930 AUTH_NONE,
11931 OK,
11932 kSecureServer,
11933 AUTH_NONE,
11934 OK,
11935 1,
11936 0,
11937 {TestRound(kGet, kSuccess, OK)}},
11938 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111939 {__LINE__,
11940 nullptr,
asankac93076192016-10-03 15:46:0211941 AUTH_NONE,
11942 OK,
11943 kSecureServer,
11944 AUTH_SYNC,
11945 OK,
11946 2,
11947 0,
11948 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511949 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111950 {__LINE__,
11951 nullptr,
asankac93076192016-10-03 15:46:0211952 AUTH_NONE,
11953 OK,
11954 kSecureServer,
11955 AUTH_SYNC,
11956 ERR_INVALID_AUTH_CREDENTIALS,
11957 2,
11958 0,
asankae2257db2016-10-11 22:03:1611959 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111960 {__LINE__,
11961 nullptr,
asankac93076192016-10-03 15:46:0211962 AUTH_NONE,
11963 OK,
11964 kSecureServer,
11965 AUTH_ASYNC,
11966 OK,
11967 2,
11968 0,
11969 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511970 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111971 {__LINE__,
11972 nullptr,
asankac93076192016-10-03 15:46:0211973 AUTH_NONE,
11974 OK,
11975 kSecureServer,
11976 AUTH_ASYNC,
11977 ERR_INVALID_AUTH_CREDENTIALS,
11978 2,
11979 0,
asankae2257db2016-10-11 22:03:1611980 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211981 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111982 {__LINE__,
11983 kProxy,
asankac93076192016-10-03 15:46:0211984 AUTH_NONE,
11985 OK,
11986 kSecureServer,
11987 AUTH_NONE,
11988 OK,
11989 1,
11990 0,
11991 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11992 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111993 {__LINE__,
11994 kProxy,
asankac93076192016-10-03 15:46:0211995 AUTH_NONE,
11996 OK,
11997 kSecureServer,
11998 AUTH_SYNC,
11999 OK,
12000 2,
12001 0,
12002 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512003 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112004 {__LINE__,
12005 kProxy,
asankac93076192016-10-03 15:46:0212006 AUTH_NONE,
12007 OK,
12008 kSecureServer,
12009 AUTH_SYNC,
12010 ERR_INVALID_AUTH_CREDENTIALS,
12011 2,
12012 0,
12013 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612014 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112015 {__LINE__,
12016 kProxy,
asankac93076192016-10-03 15:46:0212017 AUTH_NONE,
12018 OK,
12019 kSecureServer,
12020 AUTH_ASYNC,
12021 OK,
12022 2,
12023 0,
12024 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512025 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112026 {__LINE__,
12027 kProxy,
asankac93076192016-10-03 15:46:0212028 AUTH_NONE,
12029 OK,
12030 kSecureServer,
12031 AUTH_ASYNC,
12032 ERR_INVALID_AUTH_CREDENTIALS,
12033 2,
12034 0,
12035 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612036 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212037 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112038 {__LINE__,
12039 kProxy,
asankac93076192016-10-03 15:46:0212040 AUTH_SYNC,
12041 OK,
12042 kSecureServer,
12043 AUTH_NONE,
12044 OK,
12045 2,
12046 1,
12047 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512048 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112049 {__LINE__,
12050 kProxy,
asankac93076192016-10-03 15:46:0212051 AUTH_SYNC,
12052 ERR_INVALID_AUTH_CREDENTIALS,
12053 kSecureServer,
12054 AUTH_NONE,
12055 OK,
12056 2,
12057 kNoSSL,
12058 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612059 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112060 {__LINE__,
12061 kProxy,
asankae2257db2016-10-11 22:03:1612062 AUTH_SYNC,
12063 ERR_UNSUPPORTED_AUTH_SCHEME,
12064 kSecureServer,
12065 AUTH_NONE,
12066 OK,
12067 2,
12068 kNoSSL,
12069 {TestRound(kConnect, kProxyChallenge, OK),
12070 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112071 {__LINE__,
12072 kProxy,
asankae2257db2016-10-11 22:03:1612073 AUTH_SYNC,
12074 ERR_UNEXPECTED,
12075 kSecureServer,
12076 AUTH_NONE,
12077 OK,
12078 2,
12079 kNoSSL,
12080 {TestRound(kConnect, kProxyChallenge, OK),
12081 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112082 {__LINE__,
12083 kProxy,
asankac93076192016-10-03 15:46:0212084 AUTH_ASYNC,
12085 OK,
12086 kSecureServer,
12087 AUTH_NONE,
12088 OK,
12089 2,
12090 1,
12091 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512092 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112093 {__LINE__,
12094 kProxy,
asankac93076192016-10-03 15:46:0212095 AUTH_ASYNC,
12096 ERR_INVALID_AUTH_CREDENTIALS,
12097 kSecureServer,
12098 AUTH_NONE,
12099 OK,
12100 2,
12101 kNoSSL,
12102 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612103 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212104 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112105 {__LINE__,
12106 kProxy,
asankac93076192016-10-03 15:46:0212107 AUTH_SYNC,
12108 OK,
12109 kSecureServer,
12110 AUTH_SYNC,
12111 OK,
12112 3,
12113 1,
12114 {TestRound(kConnect, kProxyChallenge, OK),
12115 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12116 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512117 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112118 {__LINE__,
12119 kProxy,
asankac93076192016-10-03 15:46:0212120 AUTH_SYNC,
12121 OK,
12122 kSecureServer,
12123 AUTH_SYNC,
12124 ERR_INVALID_AUTH_CREDENTIALS,
12125 3,
12126 1,
12127 {TestRound(kConnect, kProxyChallenge, OK),
12128 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12129 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612130 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112131 {__LINE__,
12132 kProxy,
asankac93076192016-10-03 15:46:0212133 AUTH_ASYNC,
12134 OK,
12135 kSecureServer,
12136 AUTH_SYNC,
12137 OK,
12138 3,
12139 1,
12140 {TestRound(kConnect, kProxyChallenge, OK),
12141 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12142 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512143 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112144 {__LINE__,
12145 kProxy,
asankac93076192016-10-03 15:46:0212146 AUTH_ASYNC,
12147 OK,
12148 kSecureServer,
12149 AUTH_SYNC,
12150 ERR_INVALID_AUTH_CREDENTIALS,
12151 3,
12152 1,
12153 {TestRound(kConnect, kProxyChallenge, OK),
12154 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12155 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612156 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112157 {__LINE__,
12158 kProxy,
asankac93076192016-10-03 15:46:0212159 AUTH_SYNC,
12160 OK,
12161 kSecureServer,
12162 AUTH_ASYNC,
12163 OK,
12164 3,
12165 1,
12166 {TestRound(kConnect, kProxyChallenge, OK),
12167 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12168 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512169 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112170 {__LINE__,
12171 kProxy,
asankac93076192016-10-03 15:46:0212172 AUTH_SYNC,
12173 OK,
12174 kSecureServer,
12175 AUTH_ASYNC,
12176 ERR_INVALID_AUTH_CREDENTIALS,
12177 3,
12178 1,
12179 {TestRound(kConnect, kProxyChallenge, OK),
12180 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12181 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612182 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112183 {__LINE__,
12184 kProxy,
asankac93076192016-10-03 15:46:0212185 AUTH_ASYNC,
12186 OK,
12187 kSecureServer,
12188 AUTH_ASYNC,
12189 OK,
12190 3,
12191 1,
12192 {TestRound(kConnect, kProxyChallenge, OK),
12193 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12194 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512195 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112196 {__LINE__,
12197 kProxy,
asankac93076192016-10-03 15:46:0212198 AUTH_ASYNC,
12199 OK,
12200 kSecureServer,
12201 AUTH_ASYNC,
12202 ERR_INVALID_AUTH_CREDENTIALS,
12203 3,
12204 1,
12205 {TestRound(kConnect, kProxyChallenge, OK),
12206 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12207 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612208 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112209 {__LINE__,
12210 kProxy,
12211 AUTH_ASYNC,
12212 ERR_INVALID_AUTH_CREDENTIALS,
12213 kSecureServer,
12214 AUTH_ASYNC,
12215 ERR_INVALID_AUTH_CREDENTIALS,
12216 4,
12217 2,
12218 {TestRound(kConnect, kProxyChallenge, OK),
12219 TestRound(kConnect, kProxyChallenge, OK),
12220 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12221 &kServerChallenge),
12222 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512223 };
12224
asanka463ca4262016-11-16 02:34:3112225 for (const auto& test_config : test_configs) {
12226 SCOPED_TRACE(::testing::Message() << "Test config at "
12227 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812228 HttpAuthHandlerMock::Factory* auth_factory(
12229 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712230 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912231 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612232
12233 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512234 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112235 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812236 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12237 std::string auth_challenge = "Mock realm=proxy";
12238 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412239 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12240 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812241 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012242 empty_ssl_info, origin,
12243 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812244 auth_handler->SetGenerateExpectation(
12245 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112246 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812247 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12248 }
[email protected]044de0642010-06-17 10:42:1512249 }
12250 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012251 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512252 std::string auth_challenge = "Mock realm=server";
12253 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412254 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12255 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512256 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012257 empty_ssl_info, origin,
12258 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512259 auth_handler->SetGenerateExpectation(
12260 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112261 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812262 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612263
12264 // The second handler always succeeds. It should only be used where there
12265 // are multiple auth sessions for server auth in the same network
12266 // transaction using the same auth scheme.
12267 std::unique_ptr<HttpAuthHandlerMock> second_handler =
12268 base::MakeUnique<HttpAuthHandlerMock>();
12269 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12270 empty_ssl_info, origin,
12271 NetLogWithSource());
12272 second_handler->SetGenerateExpectation(true, OK);
12273 auth_factory->AddMockHandler(second_handler.release(),
12274 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512275 }
12276 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312277 session_deps_.proxy_service =
12278 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512279 } else {
rdsmith82957ad2015-09-16 19:42:0312280 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512281 }
12282
12283 HttpRequestInfo request;
12284 request.method = "GET";
12285 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512286
danakj1fd259a02016-04-16 03:17:0912287 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512288
rchcb68dc62015-05-21 04:45:3612289 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12290
12291 std::vector<std::vector<MockRead>> mock_reads(1);
12292 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512293 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
12294 const TestRound& read_write_round = test_config.rounds[round];
12295
12296 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612297 mock_reads.back().push_back(read_write_round.read);
12298 mock_writes.back().push_back(read_write_round.write);
12299
12300 // kProxyChallenge uses Proxy-Connection: close which means that the
12301 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412302 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612303 mock_reads.push_back(std::vector<MockRead>());
12304 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512305 }
12306
rchcb68dc62015-05-21 04:45:3612307 if (read_write_round.extra_read) {
12308 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512309 }
rchcb68dc62015-05-21 04:45:3612310 if (read_write_round.extra_write) {
12311 mock_writes.back().push_back(*read_write_round.extra_write);
12312 }
[email protected]044de0642010-06-17 10:42:1512313
12314 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512315 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712316 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512317 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612318 }
[email protected]044de0642010-06-17 10:42:1512319
danakj1fd259a02016-04-16 03:17:0912320 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612321 for (size_t i = 0; i < mock_reads.size(); ++i) {
danakj1fd259a02016-04-16 03:17:0912322 data_providers.push_back(base::WrapUnique(new StaticSocketDataProvider(
davidben5f8b6bc2015-11-25 03:19:5412323 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
olli.raula525048c2015-12-10 07:38:3212324 mock_writes[i].size())));
rchcb68dc62015-05-21 04:45:3612325 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212326 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612327 }
12328
mmenkecc2298e2015-12-07 18:20:1812329 // Transaction must be created after DataProviders, so it's destroyed before
12330 // they are as well.
12331 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12332
rchcb68dc62015-05-21 04:45:3612333 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
12334 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512335 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112336 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512337 int rv;
12338 if (round == 0) {
tfarina42834112016-09-22 13:38:2012339 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512340 } else {
[email protected]49639fa2011-12-20 23:22:4112341 rv = trans.RestartWithAuth(
12342 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512343 }
12344 if (rv == ERR_IO_PENDING)
12345 rv = callback.WaitForResult();
12346
12347 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612348 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012349 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512350 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512351 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12352 continue;
12353 }
12354 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212355 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512356 } else {
wezca1070932016-05-26 20:30:5212357 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612358 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512359 }
12360 }
[email protected]e5ae96a2010-04-14 20:12:4512361 }
12362}
12363
bncd16676a2016-07-20 16:23:0112364TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412365 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412366 HttpAuthHandlerMock::Factory* auth_factory(
12367 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712368 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312369 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712370 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12371 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412372
12373 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12374 auth_handler->set_connection_based(true);
12375 std::string auth_challenge = "Mock realm=server";
12376 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412377 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12378 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912379 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412380 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012381 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812382 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412383
[email protected]c871bce92010-07-15 21:51:1412384 int rv = OK;
12385 const HttpResponseInfo* response = NULL;
12386 HttpRequestInfo request;
12387 request.method = "GET";
12388 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712389
danakj1fd259a02016-04-16 03:17:0912390 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012391
12392 // Use a TCP Socket Pool with only one connection per group. This is used
12393 // to validate that the TCP socket is not released to the pool between
12394 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212395 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812396 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012397 50, // Max sockets for pool
12398 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112399 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12400 NULL, session_deps_.net_log);
danakj1fd259a02016-04-16 03:17:0912401 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:4412402 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0212403 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812404 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012405
bnc691fda62016-08-12 00:43:1612406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112407 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412408
12409 const MockWrite kGet(
12410 "GET / HTTP/1.1\r\n"
12411 "Host: www.example.com\r\n"
12412 "Connection: keep-alive\r\n\r\n");
12413 const MockWrite kGetAuth(
12414 "GET / HTTP/1.1\r\n"
12415 "Host: www.example.com\r\n"
12416 "Connection: keep-alive\r\n"
12417 "Authorization: auth_token\r\n\r\n");
12418
12419 const MockRead kServerChallenge(
12420 "HTTP/1.1 401 Unauthorized\r\n"
12421 "WWW-Authenticate: Mock realm=server\r\n"
12422 "Content-Type: text/html; charset=iso-8859-1\r\n"
12423 "Content-Length: 14\r\n\r\n"
12424 "Unauthorized\r\n");
12425 const MockRead kSuccess(
12426 "HTTP/1.1 200 OK\r\n"
12427 "Content-Type: text/html; charset=iso-8859-1\r\n"
12428 "Content-Length: 3\r\n\r\n"
12429 "Yes");
12430
12431 MockWrite writes[] = {
12432 // First round
12433 kGet,
12434 // Second round
12435 kGetAuth,
12436 // Third round
12437 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012438 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012439 kGetAuth,
12440 // Competing request
12441 kGet,
[email protected]c871bce92010-07-15 21:51:1412442 };
12443 MockRead reads[] = {
12444 // First round
12445 kServerChallenge,
12446 // Second round
12447 kServerChallenge,
12448 // Third round
[email protected]eca50e122010-09-11 14:03:3012449 kServerChallenge,
12450 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412451 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012452 // Competing response
12453 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412454 };
12455 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12456 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712457 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412458
thestig9d3bb0c2015-01-24 00:49:5112459 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012460
12461 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412462 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012463 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412464 if (rv == ERR_IO_PENDING)
12465 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112466 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612467 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212468 ASSERT_TRUE(response);
12469 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812470 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112471 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12472 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412473
[email protected]7ef4cbbb2011-02-06 11:19:1012474 // In between rounds, another request comes in for the same domain.
12475 // It should not be able to grab the TCP socket that trans has already
12476 // claimed.
bnc691fda62016-08-12 00:43:1612477 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112478 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012479 rv = trans_compete.Start(&request, callback_compete.callback(),
12480 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112481 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012482 // callback_compete.WaitForResult at this point would stall forever,
12483 // since the HttpNetworkTransaction does not release the request back to
12484 // the pool until after authentication completes.
12485
12486 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412487 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612488 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412489 if (rv == ERR_IO_PENDING)
12490 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112491 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612492 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212493 ASSERT_TRUE(response);
12494 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812495 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112496 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12497 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412498
[email protected]7ef4cbbb2011-02-06 11:19:1012499 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412500 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612501 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412502 if (rv == ERR_IO_PENDING)
12503 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112504 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612505 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212506 ASSERT_TRUE(response);
12507 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812508 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112509 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12510 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012511
[email protected]7ef4cbbb2011-02-06 11:19:1012512 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012513 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612514 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012515 if (rv == ERR_IO_PENDING)
12516 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112517 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612518 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212519 ASSERT_TRUE(response);
12520 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812521 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012522
asanka463ca4262016-11-16 02:34:3112523 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12524 // auth handler should transition to a DONE state in concert with the remote
12525 // server. But that's not something we can test here with a mock handler.
12526 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12527 auth_handler->state());
12528
[email protected]7ef4cbbb2011-02-06 11:19:1012529 // Read the body since the fourth round was successful. This will also
12530 // release the socket back to the pool.
12531 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612532 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012533 if (rv == ERR_IO_PENDING)
12534 rv = callback.WaitForResult();
12535 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612536 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012537 EXPECT_EQ(0, rv);
12538 // There are still 0 idle sockets, since the trans_compete transaction
12539 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812540 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012541
12542 // The competing request can now finish. Wait for the headers and then
12543 // read the body.
12544 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112545 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612546 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012547 if (rv == ERR_IO_PENDING)
12548 rv = callback.WaitForResult();
12549 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612550 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012551 EXPECT_EQ(0, rv);
12552
12553 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812554 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412555}
12556
[email protected]65041fa2010-05-21 06:56:5312557// This tests the case that a request is issued via http instead of spdy after
12558// npn is negotiated.
bncd16676a2016-07-20 16:23:0112559TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312560 HttpRequestInfo request;
12561 request.method = "GET";
bncce36dca22015-04-21 22:11:2312562 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312563
12564 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312565 MockWrite(
12566 "GET / HTTP/1.1\r\n"
12567 "Host: www.example.org\r\n"
12568 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312569 };
12570
12571 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212572 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312573 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212574 MockRead("\r\n"),
12575 MockRead("hello world"),
12576 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312577 };
12578
[email protected]8ddf8322012-02-23 18:08:0612579 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612580 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312581
[email protected]bb88e1d32013-05-03 23:11:0712582 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312583
12584 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12585 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712586 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312587
[email protected]49639fa2011-12-20 23:22:4112588 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312589
danakj1fd259a02016-04-16 03:17:0912590 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312592
tfarina42834112016-09-22 13:38:2012593 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312594
robpercival214763f2016-07-01 23:27:0112595 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12596 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312597
bnc691fda62016-08-12 00:43:1612598 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212599 ASSERT_TRUE(response);
12600 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312601 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12602
12603 std::string response_data;
bnc691fda62016-08-12 00:43:1612604 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312605 EXPECT_EQ("hello world", response_data);
12606
12607 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212608 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312609}
[email protected]26ef6582010-06-24 02:30:4712610
bnc55ff9da2015-08-19 18:42:3512611// Simulate the SSL handshake completing with an NPN negotiation followed by an
12612// immediate server closing of the socket.
12613// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112614TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712615 HttpRequestInfo request;
12616 request.method = "GET";
bncce36dca22015-04-21 22:11:2312617 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712618
[email protected]8ddf8322012-02-23 18:08:0612619 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612620 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712621 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712622
bncdf80d44fd2016-07-15 20:27:4112623 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912624 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112625 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712626
12627 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612628 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712629 };
12630
rch8e6c6c42015-05-01 14:05:1312631 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12632 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712633 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712634
[email protected]49639fa2011-12-20 23:22:4112635 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712636
danakj1fd259a02016-04-16 03:17:0912637 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612638 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712639
tfarina42834112016-09-22 13:38:2012640 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12642 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712643}
[email protected]65d34382010-07-01 18:12:2612644
[email protected]795cbf82013-07-22 09:37:2712645// A subclass of HttpAuthHandlerMock that records the request URL when
12646// it gets it. This is needed since the auth handler may get destroyed
12647// before we get a chance to query it.
12648class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12649 public:
12650 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12651
dchengb03027d2014-10-21 12:00:2012652 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712653
12654 protected:
dchengb03027d2014-10-21 12:00:2012655 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12656 const HttpRequestInfo* request,
12657 const CompletionCallback& callback,
12658 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712659 *url_ = request->url;
12660 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12661 credentials, request, callback, auth_token);
12662 }
12663
12664 private:
12665 GURL* url_;
12666};
12667
[email protected]8e6441ca2010-08-19 05:56:3812668// Test that if we cancel the transaction as the connection is completing, that
12669// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112670TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812671 // Setup everything about the connection to complete synchronously, so that
12672 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12673 // for is the callback from the HttpStreamRequest.
12674 // Then cancel the transaction.
12675 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612676 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812677 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612678 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12679 MockRead(SYNCHRONOUS, "hello world"),
12680 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812681 };
12682
[email protected]8e6441ca2010-08-19 05:56:3812683 HttpRequestInfo request;
12684 request.method = "GET";
bncce36dca22015-04-21 22:11:2312685 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812686
[email protected]bb88e1d32013-05-03 23:11:0712687 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612689 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112690 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2712691
[email protected]8e6441ca2010-08-19 05:56:3812692 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12693 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712694 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812695
[email protected]49639fa2011-12-20 23:22:4112696 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812697
vishal.b62985ca92015-04-17 08:45:5112698 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112699 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112700 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3812701 trans.reset(); // Cancel the transaction here.
12702
fdoray92e35a72016-06-10 15:54:5512703 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012704}
12705
[email protected]ecab6e052014-05-16 14:58:1212706// Test that if a transaction is cancelled after receiving the headers, the
12707// stream is drained properly and added back to the socket pool. The main
12708// purpose of this test is to make sure that an HttpStreamParser can be read
12709// from after the HttpNetworkTransaction and the objects it owns have been
12710// deleted.
12711// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0112712TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1212713 MockRead data_reads[] = {
12714 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12715 MockRead(ASYNC, "Content-Length: 2\r\n"),
12716 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12717 MockRead(ASYNC, "1"),
12718 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12719 // HttpNetworkTransaction has been deleted.
12720 MockRead(ASYNC, "2"),
12721 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12722 };
12723 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12724 session_deps_.socket_factory->AddSocketDataProvider(&data);
12725
danakj1fd259a02016-04-16 03:17:0912726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212727
12728 {
12729 HttpRequestInfo request;
12730 request.method = "GET";
bncce36dca22015-04-21 22:11:2312731 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212732
dcheng48459ac22014-08-26 00:46:4112733 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212734 TestCompletionCallback callback;
12735
tfarina42834112016-09-22 13:38:2012736 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112737 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1212738 callback.WaitForResult();
12739
12740 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212741 ASSERT_TRUE(response);
12742 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212743 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12744
12745 // The transaction and HttpRequestInfo are deleted.
12746 }
12747
12748 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512749 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212750
12751 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112752 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212753}
12754
[email protected]76a505b2010-08-25 06:23:0012755// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0112756TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312757 session_deps_.proxy_service =
12758 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112759 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712760 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912761 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012762
[email protected]76a505b2010-08-25 06:23:0012763 HttpRequestInfo request;
12764 request.method = "GET";
bncce36dca22015-04-21 22:11:2312765 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012766
12767 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312768 MockWrite(
12769 "GET http://www.example.org/ HTTP/1.1\r\n"
12770 "Host: www.example.org\r\n"
12771 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012772 };
12773
12774 MockRead data_reads1[] = {
12775 MockRead("HTTP/1.1 200 OK\r\n"),
12776 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12777 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612778 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012779 };
12780
12781 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12782 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712783 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012784
[email protected]49639fa2011-12-20 23:22:4112785 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012786
bnc691fda62016-08-12 00:43:1612787 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912788 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612789 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912790 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12791 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012792
bnc691fda62016-08-12 00:43:1612793 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112794 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012795
12796 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112797 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0012798
bnc691fda62016-08-12 00:43:1612799 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212800 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012801
12802 EXPECT_TRUE(response->headers->IsKeepAlive());
12803 EXPECT_EQ(200, response->headers->response_code());
12804 EXPECT_EQ(100, response->headers->GetContentLength());
12805 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712806 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12807 HostPortPair::FromString("myproxy:70")),
12808 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912809 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12810 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12811 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012812 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012813
12814 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612815 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012816 TestLoadTimingNotReusedWithPac(load_timing_info,
12817 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012818}
12819
12820// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0112821TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312822 session_deps_.proxy_service =
12823 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112824 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712825 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912826 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012827
[email protected]76a505b2010-08-25 06:23:0012828 HttpRequestInfo request;
12829 request.method = "GET";
bncce36dca22015-04-21 22:11:2312830 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012831
12832 // Since we have proxy, should try to establish tunnel.
12833 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712834 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12835 "Host: www.example.org:443\r\n"
12836 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012837
rsleevidb16bb02015-11-12 23:47:1712838 MockWrite("GET / HTTP/1.1\r\n"
12839 "Host: www.example.org\r\n"
12840 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012841 };
12842
12843 MockRead data_reads1[] = {
12844 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12845
12846 MockRead("HTTP/1.1 200 OK\r\n"),
12847 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12848 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612849 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012850 };
12851
12852 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12853 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712854 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612855 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712856 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012857
[email protected]49639fa2011-12-20 23:22:4112858 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012859
bnc691fda62016-08-12 00:43:1612860 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912861 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612862 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912863 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12864 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012865
bnc691fda62016-08-12 00:43:1612866 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112867 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012868
12869 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112870 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4612871 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012872 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012873 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012874 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12875 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012876 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012877 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012878 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12879 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012880
bnc691fda62016-08-12 00:43:1612881 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212882 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012883
12884 EXPECT_TRUE(response->headers->IsKeepAlive());
12885 EXPECT_EQ(200, response->headers->response_code());
12886 EXPECT_EQ(100, response->headers->GetContentLength());
12887 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12888 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712889 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12890 HostPortPair::FromString("myproxy:70")),
12891 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912892 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12893 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12894 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012895
12896 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612897 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012898 TestLoadTimingNotReusedWithPac(load_timing_info,
12899 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012900}
12901
rsleevidb16bb02015-11-12 23:47:1712902// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12903// literal host.
bncd16676a2016-07-20 16:23:0112904TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1712905 session_deps_.proxy_service =
12906 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12907 BoundTestNetLog log;
12908 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912909 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712910
12911 HttpRequestInfo request;
12912 request.method = "GET";
12913 request.url = GURL("https://[::1]:443/");
12914
12915 // Since we have proxy, should try to establish tunnel.
12916 MockWrite data_writes1[] = {
12917 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12918 "Host: [::1]:443\r\n"
12919 "Proxy-Connection: keep-alive\r\n\r\n"),
12920
12921 MockWrite("GET / HTTP/1.1\r\n"
12922 "Host: [::1]\r\n"
12923 "Connection: keep-alive\r\n\r\n"),
12924 };
12925
12926 MockRead data_reads1[] = {
12927 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12928
12929 MockRead("HTTP/1.1 200 OK\r\n"),
12930 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12931 MockRead("Content-Length: 100\r\n\r\n"),
12932 MockRead(SYNCHRONOUS, OK),
12933 };
12934
12935 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12936 data_writes1, arraysize(data_writes1));
12937 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12938 SSLSocketDataProvider ssl(ASYNC, OK);
12939 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12940
12941 TestCompletionCallback callback1;
12942
bnc691fda62016-08-12 00:43:1612943 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1712944
bnc691fda62016-08-12 00:43:1612945 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1712947
12948 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112949 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1712950 TestNetLogEntry::List entries;
12951 log.GetEntries(&entries);
12952 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012953 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12954 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712955 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012956 entries, pos,
12957 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12958 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712959
bnc691fda62016-08-12 00:43:1612960 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212961 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712962
12963 EXPECT_TRUE(response->headers->IsKeepAlive());
12964 EXPECT_EQ(200, response->headers->response_code());
12965 EXPECT_EQ(100, response->headers->GetContentLength());
12966 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12967 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712968 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12969 HostPortPair::FromString("myproxy:70")),
12970 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1712971
12972 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612973 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1712974 TestLoadTimingNotReusedWithPac(load_timing_info,
12975 CONNECT_TIMING_HAS_SSL_TIMES);
12976}
12977
[email protected]76a505b2010-08-25 06:23:0012978// Test a basic HTTPS GET request through a proxy, but the server hangs up
12979// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0112980TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312981 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112982 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712983 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912984 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012985
[email protected]76a505b2010-08-25 06:23:0012986 HttpRequestInfo request;
12987 request.method = "GET";
bncce36dca22015-04-21 22:11:2312988 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012989
12990 // Since we have proxy, should try to establish tunnel.
12991 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712992 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12993 "Host: www.example.org:443\r\n"
12994 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012995
rsleevidb16bb02015-11-12 23:47:1712996 MockWrite("GET / HTTP/1.1\r\n"
12997 "Host: www.example.org\r\n"
12998 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012999 };
13000
13001 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0613002 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0013003 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613004 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013005 };
13006
13007 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13008 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713009 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613010 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713011 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013012
[email protected]49639fa2011-12-20 23:22:4113013 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013014
bnc691fda62016-08-12 00:43:1613015 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013016
bnc691fda62016-08-12 00:43:1613017 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113018 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013019
13020 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113021 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613022 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013023 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013024 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013025 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13026 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013027 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013028 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013029 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13030 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013031}
13032
[email protected]749eefa82010-09-13 22:14:0313033// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113034TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113035 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913036 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113037 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313038
bnc42331402016-07-25 13:36:1513039 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113040 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313041 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113042 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313043 };
13044
rch8e6c6c42015-05-01 14:05:1313045 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13046 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713047 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313048
[email protected]8ddf8322012-02-23 18:08:0613049 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613050 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713051 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313052
danakj1fd259a02016-04-16 03:17:0913053 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313054
13055 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313056 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013057 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313058 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713059 base::WeakPtr<SpdySession> spdy_session =
bnc032658ba2016-09-26 18:17:1513060 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313061
13062 HttpRequestInfo request;
13063 request.method = "GET";
bncce36dca22015-04-21 22:11:2313064 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313065
13066 // This is the important line that marks this as a preconnect.
13067 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13068
bnc691fda62016-08-12 00:43:1613069 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313070
[email protected]41d64e82013-07-03 22:44:2613071 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013072 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13074 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313075}
13076
[email protected]73b8dd222010-11-11 19:55:2413077// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613078// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213079void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713080 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913081 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713082 request_info.url = GURL("https://www.example.com/");
13083 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913084 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713085
[email protected]8ddf8322012-02-23 18:08:0613086 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913087 MockWrite data_writes[] = {
13088 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413089 };
ttuttle859dc7a2015-04-23 19:42:2913090 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713091 session_deps_.socket_factory->AddSocketDataProvider(&data);
13092 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413093
danakj1fd259a02016-04-16 03:17:0913094 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613095 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413096
[email protected]49639fa2011-12-20 23:22:4113097 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013098 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913099 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413100 rv = callback.WaitForResult();
13101 ASSERT_EQ(error, rv);
13102}
13103
bncd16676a2016-07-20 16:23:0113104TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413105 // Just check a grab bag of cert errors.
13106 static const int kErrors[] = {
13107 ERR_CERT_COMMON_NAME_INVALID,
13108 ERR_CERT_AUTHORITY_INVALID,
13109 ERR_CERT_DATE_INVALID,
13110 };
13111 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613112 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13113 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413114 }
13115}
13116
[email protected]bd0b6772011-01-11 19:59:3013117// Ensure that a client certificate is removed from the SSL client auth
13118// cache when:
13119// 1) No proxy is involved.
13120// 2) TLS False Start is disabled.
13121// 3) The initial TLS handshake requests a client certificate.
13122// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113123TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913124 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713125 request_info.url = GURL("https://www.example.com/");
13126 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913127 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713128
[email protected]bd0b6772011-01-11 19:59:3013129 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113130 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013131
13132 // [ssl_]data1 contains the data for the first SSL handshake. When a
13133 // CertificateRequest is received for the first time, the handshake will
13134 // be aborted to allow the caller to provide a certificate.
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 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13142 // False Start is not being used, the result of the SSL handshake will be
13143 // returned as part of the SSLClientSocket::Connect() call. This test
13144 // matches the result of a server sending a handshake_failure alert,
13145 // rather than a Finished message, because it requires a client
13146 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913147 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013148 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713149 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913150 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713151 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013152
13153 // [ssl_]data3 contains the data for the third SSL handshake. When a
13154 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213155 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13156 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013157 // of the HttpNetworkTransaction. Because this test failure is due to
13158 // requiring a client certificate, this fallback handshake should also
13159 // fail.
ttuttle859dc7a2015-04-23 19:42:2913160 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[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(NULL, 0, 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 contains the data for the fourth SSL handshake. When a
13167 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213168 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13169 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713170 // of the HttpNetworkTransaction. Because this test failure is due to
13171 // requiring a client certificate, this fallback handshake should also
13172 // fail.
ttuttle859dc7a2015-04-23 19:42:2913173 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713174 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713175 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913176 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713177 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713178
danakj1fd259a02016-04-16 03:17:0913179 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613180 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013181
[email protected]bd0b6772011-01-11 19:59:3013182 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113183 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013184 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113185 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013186
13187 // Complete the SSL handshake, which should abort due to requiring a
13188 // client certificate.
13189 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113190 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013191
13192 // Indicate that no certificate should be supplied. From the perspective
13193 // of SSLClientCertCache, NULL is just as meaningful as a real
13194 // certificate, so this is the same as supply a
13195 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613196 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113197 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013198
13199 // Ensure the certificate was added to the client auth cache before
13200 // allowing the connection to continue restarting.
13201 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413202 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113203 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413204 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213205 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013206
13207 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713208 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13209 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013210 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113211 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013212
13213 // Ensure that the client certificate is removed from the cache on a
13214 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113215 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413216 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013217}
13218
13219// Ensure that a client certificate is removed from the SSL client auth
13220// cache when:
13221// 1) No proxy is involved.
13222// 2) TLS False Start is enabled.
13223// 3) The initial TLS handshake requests a client certificate.
13224// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113225TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913226 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713227 request_info.url = GURL("https://www.example.com/");
13228 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913229 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713230
[email protected]bd0b6772011-01-11 19:59:3013231 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113232 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013233
13234 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13235 // return successfully after reading up to the peer's Certificate message.
13236 // This is to allow the caller to call SSLClientSocket::Write(), which can
13237 // enqueue application data to be sent in the same packet as the
13238 // ChangeCipherSpec and Finished messages.
13239 // The actual handshake will be finished when SSLClientSocket::Read() is
13240 // called, which expects to process the peer's ChangeCipherSpec and
13241 // Finished messages. If there was an error negotiating with the peer,
13242 // such as due to the peer requiring a client certificate when none was
13243 // supplied, the alert sent by the peer won't be processed until Read() is
13244 // called.
13245
13246 // Like the non-False Start case, when a client certificate is requested by
13247 // the peer, the handshake is aborted during the Connect() call.
13248 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913249 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013250 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713251 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913252 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713253 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013254
13255 // When a client certificate is supplied, Connect() will not be aborted
13256 // when the peer requests the certificate. Instead, the handshake will
13257 // artificially succeed, allowing the caller to write the HTTP request to
13258 // the socket. The handshake messages are not processed until Read() is
13259 // called, which then detects that the handshake was aborted, due to the
13260 // peer sending a handshake_failure because it requires a client
13261 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913262 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013263 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713264 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913265 MockRead data2_reads[] = {
13266 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013267 };
ttuttle859dc7a2015-04-23 19:42:2913268 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713269 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013270
13271 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713272 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13273 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913274 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013275 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713276 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913277 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713278 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013279
[email protected]80c75f682012-05-26 16:22:1713280 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13281 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913282 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713283 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713284 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913285 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713286 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713287
[email protected]7799de12013-05-30 05:52:5113288 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913289 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113290 ssl_data5.cert_request_info = cert_request.get();
13291 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913292 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113293 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13294
danakj1fd259a02016-04-16 03:17:0913295 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613296 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013297
[email protected]bd0b6772011-01-11 19:59:3013298 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113299 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013300 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113301 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013302
13303 // Complete the SSL handshake, which should abort due to requiring a
13304 // client certificate.
13305 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113306 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013307
13308 // Indicate that no certificate should be supplied. From the perspective
13309 // of SSLClientCertCache, NULL is just as meaningful as a real
13310 // certificate, so this is the same as supply a
13311 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613312 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113313 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013314
13315 // Ensure the certificate was added to the client auth cache before
13316 // allowing the connection to continue restarting.
13317 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413318 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113319 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413320 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213321 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013322
[email protected]bd0b6772011-01-11 19:59:3013323 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713324 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13325 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013326 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113327 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013328
13329 // Ensure that the client certificate is removed from the cache on a
13330 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113331 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413332 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013333}
13334
[email protected]8c405132011-01-11 22:03:1813335// Ensure that a client certificate is removed from the SSL client auth
13336// cache when:
13337// 1) An HTTPS proxy is involved.
13338// 3) The HTTPS proxy requests a client certificate.
13339// 4) The client supplies an invalid/unacceptable certificate for the
13340// proxy.
13341// The test is repeated twice, first for connecting to an HTTPS endpoint,
13342// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113343TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313344 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113345 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713346 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813347
13348 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113349 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813350
13351 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13352 // [ssl_]data[1-3]. Rather than represending the endpoint
13353 // (www.example.com:443), they represent failures with the HTTPS proxy
13354 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913355 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813356 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713357 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913358 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713359 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813360
ttuttle859dc7a2015-04-23 19:42:2913361 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813362 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713363 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913364 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713365 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813366
[email protected]80c75f682012-05-26 16:22:1713367 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13368#if 0
ttuttle859dc7a2015-04-23 19:42:2913369 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813370 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913372 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713373 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713374#endif
[email protected]8c405132011-01-11 22:03:1813375
ttuttle859dc7a2015-04-23 19:42:2913376 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813377 requests[0].url = GURL("https://www.example.com/");
13378 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913379 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813380
13381 requests[1].url = GURL("http://www.example.com/");
13382 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913383 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813384
13385 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713386 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913387 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613388 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813389
13390 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113391 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013392 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113393 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813394
13395 // Complete the SSL handshake, which should abort due to requiring a
13396 // client certificate.
13397 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113398 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813399
13400 // Indicate that no certificate should be supplied. From the perspective
13401 // of SSLClientCertCache, NULL is just as meaningful as a real
13402 // certificate, so this is the same as supply a
13403 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613404 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113405 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813406
13407 // Ensure the certificate was added to the client auth cache before
13408 // allowing the connection to continue restarting.
13409 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413410 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113411 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413412 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213413 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813414 // Ensure the certificate was NOT cached for the endpoint. This only
13415 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113416 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413417 HostPortPair("www.example.com", 443), &client_cert,
13418 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813419
13420 // Restart the handshake. This will consume ssl_data2, which fails, and
13421 // then consume ssl_data3, which should also fail. The result code is
13422 // checked against what ssl_data3 should return.
13423 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113424 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813425
13426 // Now that the new handshake has failed, ensure that the client
13427 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113428 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413429 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113430 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413431 HostPortPair("www.example.com", 443), &client_cert,
13432 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813433 }
13434}
13435
bncd16676a2016-07-20 16:23:0113436TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613437 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713438 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913439 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613440
bnc032658ba2016-09-26 18:17:1513441 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613442
bncdf80d44fd2016-07-15 20:27:4113443 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913444 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813445 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113446 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713447 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613448 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113449 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613450 };
bnc42331402016-07-25 13:36:1513451 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113452 SpdySerializedFrame host1_resp_body(
13453 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513454 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113455 SpdySerializedFrame host2_resp_body(
13456 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613457 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113458 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13459 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313460 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613461 };
13462
eroman36d84e54432016-03-17 03:23:0213463 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213464 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313465 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13466 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713467 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613468
[email protected]aa22b242011-11-16 18:58:2913469 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613470 HttpRequestInfo request1;
13471 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313472 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613473 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013474 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613475
tfarina42834112016-09-22 13:38:2013476 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13478 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613479
13480 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213481 ASSERT_TRUE(response);
13482 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213483 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613484
13485 std::string response_data;
robpercival214763f2016-07-01 23:27:0113486 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613487 EXPECT_EQ("hello!", response_data);
13488
bnca4d611d2016-09-22 19:55:3713489 // Preload mail.example.com into HostCache.
13490 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013491 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613492 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013493 std::unique_ptr<HostResolver::Request> request;
13494 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13495 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013496 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113497 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713498 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113499 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613500
13501 HttpRequestInfo request2;
13502 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713503 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613504 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013505 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613506
tfarina42834112016-09-22 13:38:2013507 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113508 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13509 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613510
13511 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213512 ASSERT_TRUE(response);
13513 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213514 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613515 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213516 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113517 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613518 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613519}
13520
bncd16676a2016-07-20 16:23:0113521TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213522 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713523 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913524 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213525
bnc032658ba2016-09-26 18:17:1513526 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213527
bncdf80d44fd2016-07-15 20:27:4113528 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913529 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813530 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113531 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713532 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213533 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113534 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213535 };
bnc42331402016-07-25 13:36:1513536 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113537 SpdySerializedFrame host1_resp_body(
13538 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513539 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113540 SpdySerializedFrame host2_resp_body(
13541 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213542 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113543 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13544 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313545 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213546 };
13547
eroman36d84e54432016-03-17 03:23:0213548 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213549 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313550 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13551 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713552 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213553
13554 TestCompletionCallback callback;
13555 HttpRequestInfo request1;
13556 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313557 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213558 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013559 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213560
tfarina42834112016-09-22 13:38:2013561 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113562 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13563 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213564
13565 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213566 ASSERT_TRUE(response);
13567 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213568 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213569
13570 std::string response_data;
robpercival214763f2016-07-01 23:27:0113571 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213572 EXPECT_EQ("hello!", response_data);
13573
13574 HttpRequestInfo request2;
13575 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713576 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213577 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013578 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213579
tfarina42834112016-09-22 13:38:2013580 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113581 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13582 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213583
13584 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213585 ASSERT_TRUE(response);
13586 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213587 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213588 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213589 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113590 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213591 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213592}
13593
ttuttle859dc7a2015-04-23 19:42:2913594class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4613595 public:
13596 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
13597 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013598 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613599
13600 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
13601
13602 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2013603 int Resolve(const RequestInfo& info,
13604 RequestPriority priority,
13605 AddressList* addresses,
13606 const CompletionCallback& callback,
maksim.sisov31452af2016-07-27 06:38:1013607 std::unique_ptr<Request>* out_req,
tfarina42834112016-09-22 13:38:2013608 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013609 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1013610 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4013611 }
13612
dchengb03027d2014-10-21 12:00:2013613 int ResolveFromCache(const RequestInfo& info,
13614 AddressList* addresses,
tfarina42834112016-09-22 13:38:2013615 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013616 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
13617 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0913618 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613619 return rv;
13620 }
13621
[email protected]46da33be2011-07-19 21:58:0413622 MockCachingHostResolver* GetMockHostResolver() {
13623 return &host_resolver_;
13624 }
13625
[email protected]e3ceb682011-06-28 23:55:4613626 private:
13627 MockCachingHostResolver host_resolver_;
13628 const HostPortPair host_port_;
13629};
13630
bncd16676a2016-07-20 16:23:0113631TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1313632 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4613633 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
bnca4d611d2016-09-22 19:55:3713634 OneTimeCachingHostResolver host_resolver(
13635 HostPortPair("mail.example.com", 443));
[email protected]c6bf8152012-12-02 07:43:3413636 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0713637 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4613638 params.host_resolver = &host_resolver;
danakj1fd259a02016-04-16 03:17:0913639 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613640
bnc032658ba2016-09-26 18:17:1513641 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613642
bncdf80d44fd2016-07-15 20:27:4113643 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913644 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813645 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113646 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713647 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613648 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113649 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613650 };
bnc42331402016-07-25 13:36:1513651 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113652 SpdySerializedFrame host1_resp_body(
13653 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513654 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113655 SpdySerializedFrame host2_resp_body(
13656 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613657 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113658 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13659 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313660 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613661 };
13662
eroman36d84e54432016-03-17 03:23:0213663 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213664 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313665 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13666 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713667 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613668
[email protected]aa22b242011-11-16 18:58:2913669 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613670 HttpRequestInfo request1;
13671 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313672 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613673 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013674 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613675
tfarina42834112016-09-22 13:38:2013676 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113677 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13678 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613679
13680 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213681 ASSERT_TRUE(response);
13682 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213683 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613684
13685 std::string response_data;
robpercival214763f2016-07-01 23:27:0113686 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613687 EXPECT_EQ("hello!", response_data);
13688
13689 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3713690 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613691 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013692 std::unique_ptr<HostResolver::Request> request;
13693 rv = host_resolver.Resolve(resolve_info, DEFAULT_PRIORITY, &ignored,
tfarina42834112016-09-22 13:38:2013694 callback.callback(), &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113695 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713696 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113697 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613698
13699 HttpRequestInfo request2;
13700 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713701 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613702 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013703 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613704
tfarina42834112016-09-22 13:38:2013705 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13707 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613708
13709 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213710 ASSERT_TRUE(response);
13711 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213712 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613713 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213714 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113715 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613716 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613717}
13718
bncd16676a2016-07-20 16:23:0113719TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313720 const std::string https_url = "https://www.example.org:8080/";
13721 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413722
13723 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4113724 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4913725 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413726
13727 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113728 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0413729 };
13730
bnc42331402016-07-25 13:36:1513731 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113732 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13733 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5913734 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413735
rch8e6c6c42015-05-01 14:05:1313736 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13737 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413738 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713739 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413740
13741 // HTTP GET for the HTTP URL
13742 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313743 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413744 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313745 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413746 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413747 };
13748
13749 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313750 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13751 MockRead(ASYNC, 2, "hello"),
13752 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413753 };
13754
rch8e6c6c42015-05-01 14:05:1313755 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13756 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0413757
[email protected]8450d722012-07-02 19:14:0413758 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613759 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713760 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13761 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13762 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0413763
danakj1fd259a02016-04-16 03:17:0913764 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413765
13766 // Start the first transaction to set up the SpdySession
13767 HttpRequestInfo request1;
13768 request1.method = "GET";
13769 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413770 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013771 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413772 TestCompletionCallback callback1;
13773 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013774 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5513775 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413776
robpercival214763f2016-07-01 23:27:0113777 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0413778 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13779
13780 // Now, start the HTTP request
13781 HttpRequestInfo request2;
13782 request2.method = "GET";
13783 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413784 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013785 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413786 TestCompletionCallback callback2;
13787 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013788 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5513789 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413790
robpercival214763f2016-07-01 23:27:0113791 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0413792 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13793}
13794
bnc5452e2a2015-05-08 16:27:4213795// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
13796// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0113797TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2513798 url::SchemeHostPort server("https", "www.example.org", 443);
13799 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4213800
bnc8bef8da22016-05-30 01:28:2513801 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4213802 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613803 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4213804 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13805
13806 // No data should be read from the alternative, because HTTP/1.1 is
13807 // negotiated.
13808 StaticSocketDataProvider data;
13809 session_deps_.socket_factory->AddSocketDataProvider(&data);
13810
13811 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4613812 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4213813 // mocked. This way the request relies on the alternate Job.
13814 StaticSocketDataProvider data_refused;
13815 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13816 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13817
zhongyi3d4a55e72016-04-22 20:36:4613818 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913819 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013820 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4213821 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2113822 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1213823 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613824 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013825 expiration);
bnc5452e2a2015-05-08 16:27:4213826
bnc5452e2a2015-05-08 16:27:4213827 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4613828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4213829 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2513830 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4213831 TestCompletionCallback callback;
13832
13833 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5213834 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2013835 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5213836 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4213837}
13838
bnc40448a532015-05-11 19:13:1413839// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4613840// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1413841// succeeds, the request should succeed, even if the latter fails because
13842// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0113843TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2513844 url::SchemeHostPort server("https", "www.example.org", 443);
13845 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1413846
13847 // Negotiate HTTP/1.1 with alternative.
13848 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613849 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1413850 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13851
13852 // No data should be read from the alternative, because HTTP/1.1 is
13853 // negotiated.
13854 StaticSocketDataProvider data;
13855 session_deps_.socket_factory->AddSocketDataProvider(&data);
13856
zhongyi3d4a55e72016-04-22 20:36:4613857 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1413858 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613859 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1413860 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13861
13862 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2513863 MockWrite("GET / HTTP/1.1\r\n"
13864 "Host: www.example.org\r\n"
13865 "Connection: keep-alive\r\n\r\n"),
13866 MockWrite("GET /second HTTP/1.1\r\n"
13867 "Host: www.example.org\r\n"
13868 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1413869 };
13870
13871 MockRead http_reads[] = {
13872 MockRead("HTTP/1.1 200 OK\r\n"),
13873 MockRead("Content-Type: text/html\r\n"),
13874 MockRead("Content-Length: 6\r\n\r\n"),
13875 MockRead("foobar"),
13876 MockRead("HTTP/1.1 200 OK\r\n"),
13877 MockRead("Content-Type: text/html\r\n"),
13878 MockRead("Content-Length: 7\r\n\r\n"),
13879 MockRead("another"),
13880 };
13881 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13882 http_writes, arraysize(http_writes));
13883 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13884
zhongyi3d4a55e72016-04-22 20:36:4613885 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913886 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013887 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1413888 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2113889 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1213890 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613891 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013892 expiration);
bnc40448a532015-05-11 19:13:1413893
13894 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13895 HttpRequestInfo request1;
13896 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2513897 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1413898 request1.load_flags = 0;
13899 TestCompletionCallback callback1;
13900
tfarina42834112016-09-22 13:38:2013901 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1413902 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0113903 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1413904
13905 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213906 ASSERT_TRUE(response1);
13907 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1413908 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13909
13910 std::string response_data1;
robpercival214763f2016-07-01 23:27:0113911 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1413912 EXPECT_EQ("foobar", response_data1);
13913
13914 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13915 // for alternative service.
13916 EXPECT_TRUE(
13917 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13918
zhongyi3d4a55e72016-04-22 20:36:4613919 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1413920 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4613921 // to server.
bnc40448a532015-05-11 19:13:1413922 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13923 HttpRequestInfo request2;
13924 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2513925 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1413926 request2.load_flags = 0;
13927 TestCompletionCallback callback2;
13928
tfarina42834112016-09-22 13:38:2013929 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1413930 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0113931 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1413932
13933 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213934 ASSERT_TRUE(response2);
13935 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1413936 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13937
13938 std::string response_data2;
robpercival214763f2016-07-01 23:27:0113939 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1413940 EXPECT_EQ("another", response_data2);
13941}
13942
bnc5452e2a2015-05-08 16:27:4213943// Alternative service requires HTTP/2 (or SPDY), but there is already a
13944// HTTP/1.1 socket open to the alternative server. That socket should not be
13945// used.
bncd16676a2016-07-20 16:23:0113946TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4613947 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4213948 HostPortPair alternative("alternative.example.org", 443);
13949 std::string origin_url = "https://origin.example.org:443";
13950 std::string alternative_url = "https://alternative.example.org:443";
13951
13952 // Negotiate HTTP/1.1 with alternative.example.org.
13953 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613954 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4213955 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13956
13957 // HTTP/1.1 data for |request1| and |request2|.
13958 MockWrite http_writes[] = {
13959 MockWrite(
13960 "GET / HTTP/1.1\r\n"
13961 "Host: alternative.example.org\r\n"
13962 "Connection: keep-alive\r\n\r\n"),
13963 MockWrite(
13964 "GET / HTTP/1.1\r\n"
13965 "Host: alternative.example.org\r\n"
13966 "Connection: keep-alive\r\n\r\n"),
13967 };
13968
13969 MockRead http_reads[] = {
13970 MockRead(
13971 "HTTP/1.1 200 OK\r\n"
13972 "Content-Type: text/html; charset=iso-8859-1\r\n"
13973 "Content-Length: 40\r\n\r\n"
13974 "first HTTP/1.1 response from alternative"),
13975 MockRead(
13976 "HTTP/1.1 200 OK\r\n"
13977 "Content-Type: text/html; charset=iso-8859-1\r\n"
13978 "Content-Length: 41\r\n\r\n"
13979 "second HTTP/1.1 response from alternative"),
13980 };
13981 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13982 http_writes, arraysize(http_writes));
13983 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13984
13985 // This test documents that an alternate Job should not pool to an already
13986 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4613987 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4213988 StaticSocketDataProvider data_refused;
13989 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13990 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13991
zhongyi3d4a55e72016-04-22 20:36:4613992 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913993 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013994 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4213995 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2113996 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1213997 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613998 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013999 expiration);
bnc5452e2a2015-05-08 16:27:4214000
14001 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214002 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614003 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214004 request1.method = "GET";
14005 request1.url = GURL(alternative_url);
14006 request1.load_flags = 0;
14007 TestCompletionCallback callback1;
14008
tfarina42834112016-09-22 13:38:2014009 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114010 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614011 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214012 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214013 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214014 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214015 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214016 EXPECT_FALSE(response1->was_fetched_via_spdy);
14017 std::string response_data1;
bnc691fda62016-08-12 00:43:1614018 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214019 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14020
14021 // Request for origin.example.org, which has an alternative service. This
14022 // will start two Jobs: the alternative looks for connections to pool to,
14023 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614024 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214025 // this request fails.
bnc5452e2a2015-05-08 16:27:4214026 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614027 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214028 request2.method = "GET";
14029 request2.url = GURL(origin_url);
14030 request2.load_flags = 0;
14031 TestCompletionCallback callback2;
14032
tfarina42834112016-09-22 13:38:2014033 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114034 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214035
14036 // Another transaction to alternative. This is to test that the HTTP/1.1
14037 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214038 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614039 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214040 request3.method = "GET";
14041 request3.url = GURL(alternative_url);
14042 request3.load_flags = 0;
14043 TestCompletionCallback callback3;
14044
tfarina42834112016-09-22 13:38:2014045 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114046 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614047 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214048 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214049 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214050 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214051 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214052 EXPECT_FALSE(response3->was_fetched_via_spdy);
14053 std::string response_data3;
bnc691fda62016-08-12 00:43:1614054 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214055 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14056}
14057
bncd16676a2016-07-20 16:23:0114058TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314059 const std::string https_url = "https://www.example.org:8080/";
14060 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414061
rdsmithebb50aa2015-11-12 03:44:3814062 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114063 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814064
[email protected]8450d722012-07-02 19:14:0414065 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314066 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114067 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414068 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114069 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914070 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114071 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214072 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914073
14074 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914075 SpdyHeaderBlock req2_block;
14076 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2314077 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2914078 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4914079 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4114080 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514081 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414082
14083 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114084 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14085 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414086 };
14087
bncdf80d44fd2016-07-15 20:27:4114088 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514089 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114090 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514091 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114092 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14093 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814094 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114095 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814096 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514097 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114098 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314099 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114100 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314101 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114102 CreateMockRead(wrapped_resp1, 4),
14103 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314104 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114105 CreateMockRead(resp2, 8),
14106 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314107 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14108 };
[email protected]8450d722012-07-02 19:14:0414109
mmenke666a6fea2015-12-19 04:16:3314110 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14111 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414112 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714113 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414114
rdsmith82957ad2015-09-16 19:42:0314115 session_deps_.proxy_service =
14116 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114117 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714118 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414119 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614120 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314121 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414122 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614123 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314124 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14125 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414126
danakj1fd259a02016-04-16 03:17:0914127 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414128
14129 // Start the first transaction to set up the SpdySession
14130 HttpRequestInfo request1;
14131 request1.method = "GET";
14132 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414133 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014134 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414135 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014136 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414137
mmenke666a6fea2015-12-19 04:16:3314138 // This pause is a hack to avoid running into https://crbug.com/497228.
14139 data1.RunUntilPaused();
14140 base::RunLoop().RunUntilIdle();
14141 data1.Resume();
robpercival214763f2016-07-01 23:27:0114142 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414143 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14144
[email protected]f6c63db52013-02-02 00:35:2214145 LoadTimingInfo load_timing_info1;
14146 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14147 TestLoadTimingNotReusedWithPac(load_timing_info1,
14148 CONNECT_TIMING_HAS_SSL_TIMES);
14149
mmenke666a6fea2015-12-19 04:16:3314150 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414151 HttpRequestInfo request2;
14152 request2.method = "GET";
14153 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414154 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014155 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414156 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014157 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414158
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();
robpercival214763f2016-07-01 23:27:0114163 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314164
[email protected]8450d722012-07-02 19:14:0414165 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214166
14167 LoadTimingInfo load_timing_info2;
14168 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14169 // The established SPDY sessions is considered reused by the HTTP request.
14170 TestLoadTimingReusedWithPac(load_timing_info2);
14171 // HTTP requests over a SPDY session should have a different connection
14172 // socket_log_id than requests over a tunnel.
14173 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414174}
14175
[email protected]2d88e7d2012-07-19 17:55:1714176// Test that in the case where we have a SPDY session to a SPDY proxy
14177// that we do not pool other origins that resolve to the same IP when
14178// the certificate does not match the new origin.
14179// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114180TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314181 const std::string url1 = "http://www.example.org/";
14182 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714183 const std::string ip_addr = "1.2.3.4";
14184
rdsmithebb50aa2015-11-12 03:44:3814185 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114186 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814187
[email protected]2d88e7d2012-07-19 17:55:1714188 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614189 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314190 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114191 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514192 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714193
14194 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114195 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714196 };
14197
bnc42331402016-07-25 13:36:1514198 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114199 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714200 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114201 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14202 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714203 };
14204
mmenke666a6fea2015-12-19 04:16:3314205 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14206 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214207 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914208 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714209 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14210 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314211 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714212
14213 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114214 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914215 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714216
14217 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114218 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714219 };
14220
bnc42331402016-07-25 13:36:1514221 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114222 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14223 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314224 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714225
mmenke666a6fea2015-12-19 04:16:3314226 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14227 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714228 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314229 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714230
14231 // Set up a proxy config that sends HTTP requests to a proxy, and
14232 // all others direct.
14233 ProxyConfig proxy_config;
14234 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0714235 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0914236 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), nullptr,
csharrisonb7e3a082015-09-22 19:13:0414237 NULL));
[email protected]2d88e7d2012-07-19 17:55:1714238
bncce36dca22015-04-21 22:11:2314239 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614240 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714241 // Load a valid cert. Note, that this does not need to
14242 // be valid for proxy because the MockSSLClientSocket does
14243 // not actually verify it. But SpdySession will use this
14244 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314245 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214246 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314247 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14248 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714249
14250 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614251 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314252 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14253 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714254
[email protected]bb88e1d32013-05-03 23:11:0714255 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2314256 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714257 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714258
danakj1fd259a02016-04-16 03:17:0914259 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714260
14261 // Start the first transaction to set up the SpdySession
14262 HttpRequestInfo request1;
14263 request1.method = "GET";
14264 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714265 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014266 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714267 TestCompletionCallback callback1;
14268 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014269 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314270 // This pause is a hack to avoid running into https://crbug.com/497228.
14271 data1.RunUntilPaused();
14272 base::RunLoop().RunUntilIdle();
14273 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714274
robpercival214763f2016-07-01 23:27:0114275 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714276 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14277
14278 // Now, start the HTTP request
14279 HttpRequestInfo request2;
14280 request2.method = "GET";
14281 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714282 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014283 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714284 TestCompletionCallback callback2;
14285 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014286 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514287 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714288
14289 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114290 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714291 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14292}
14293
[email protected]85f97342013-04-17 06:12:2414294// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14295// error) in SPDY session, removes the socket from pool and closes the SPDY
14296// session. Verify that new url's from the same HttpNetworkSession (and a new
14297// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114298TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314299 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414300
14301 MockRead reads1[] = {
14302 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14303 };
14304
mmenke11eb5152015-06-09 14:50:5014305 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414306
bncdf80d44fd2016-07-15 20:27:4114307 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914308 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414309 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114310 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414311 };
14312
bnc42331402016-07-25 13:36:1514313 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114314 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414315 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114316 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14317 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414318 };
14319
mmenke11eb5152015-06-09 14:50:5014320 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14321 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414322
[email protected]85f97342013-04-17 06:12:2414323 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614324 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014325 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14326 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414327
14328 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614329 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14331 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414332
danakj1fd259a02016-04-16 03:17:0914333 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014334 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414335
14336 // Start the first transaction to set up the SpdySession and verify that
14337 // connection was closed.
14338 HttpRequestInfo request1;
14339 request1.method = "GET";
14340 request1.url = GURL(https_url);
14341 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014342 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414343 TestCompletionCallback callback1;
14344 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014345 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114346 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414347
14348 // Now, start the second request and make sure it succeeds.
14349 HttpRequestInfo request2;
14350 request2.method = "GET";
14351 request2.url = GURL(https_url);
14352 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014353 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414354 TestCompletionCallback callback2;
14355 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014356 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414357
robpercival214763f2016-07-01 23:27:0114358 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414359 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14360}
14361
bncd16676a2016-07-20 16:23:0114362TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314363 ClientSocketPoolManager::set_max_sockets_per_group(
14364 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14365 ClientSocketPoolManager::set_max_sockets_per_pool(
14366 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14367
14368 // Use two different hosts with different IPs so they don't get pooled.
14369 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14370 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914371 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314372
14373 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614374 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314375 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614376 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314377 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14378 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14379
bncdf80d44fd2016-07-15 20:27:4114380 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914381 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314382 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114383 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314384 };
bnc42331402016-07-25 13:36:1514385 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114386 SpdySerializedFrame host1_resp_body(
14387 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314388 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114389 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914390 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314391 };
14392
rdsmithebb50aa2015-11-12 03:44:3814393 // Use a separate test instance for the separate SpdySession that will be
14394 // created.
bncd16676a2016-07-20 16:23:0114395 SpdyTestUtil spdy_util_2;
danakj1fd259a02016-04-16 03:17:0914396 std::unique_ptr<SequencedSocketData> spdy1_data(
rch8e6c6c42015-05-01 14:05:1314397 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14398 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0314399 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14400
bncdf80d44fd2016-07-15 20:27:4114401 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914402 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314403 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114404 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314405 };
bnc42331402016-07-25 13:36:1514406 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114407 SpdySerializedFrame host2_resp_body(
14408 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314409 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114410 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914411 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314412 };
14413
danakj1fd259a02016-04-16 03:17:0914414 std::unique_ptr<SequencedSocketData> spdy2_data(
rch8e6c6c42015-05-01 14:05:1314415 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14416 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0314417 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14418
14419 MockWrite http_write[] = {
14420 MockWrite("GET / HTTP/1.1\r\n"
14421 "Host: www.a.com\r\n"
14422 "Connection: keep-alive\r\n\r\n"),
14423 };
14424
14425 MockRead http_read[] = {
14426 MockRead("HTTP/1.1 200 OK\r\n"),
14427 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14428 MockRead("Content-Length: 6\r\n\r\n"),
14429 MockRead("hello!"),
14430 };
14431 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14432 http_write, arraysize(http_write));
14433 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14434
14435 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014436 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314437 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314438 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614439 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314440
14441 TestCompletionCallback callback;
14442 HttpRequestInfo request1;
14443 request1.method = "GET";
14444 request1.url = GURL("https://www.a.com/");
14445 request1.load_flags = 0;
danakj1fd259a02016-04-16 03:17:0914446 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5014447 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314448
tfarina42834112016-09-22 13:38:2014449 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114450 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14451 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314452
14453 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214454 ASSERT_TRUE(response);
14455 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214456 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314457 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214458 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0314459
14460 std::string response_data;
robpercival214763f2016-07-01 23:27:0114461 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314462 EXPECT_EQ("hello!", response_data);
14463 trans.reset();
14464 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614465 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314466
14467 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014468 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314469 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314470 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614471 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314472 HttpRequestInfo request2;
14473 request2.method = "GET";
14474 request2.url = GURL("https://www.b.com/");
14475 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014476 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314477
tfarina42834112016-09-22 13:38:2014478 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14480 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314481
14482 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214483 ASSERT_TRUE(response);
14484 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214485 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314486 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214487 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114488 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314489 EXPECT_EQ("hello!", response_data);
14490 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614491 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314492 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614493 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314494
14495 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014496 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314497 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314498 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614499 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314500 HttpRequestInfo request3;
14501 request3.method = "GET";
14502 request3.url = GURL("http://www.a.com/");
14503 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014504 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314505
tfarina42834112016-09-22 13:38:2014506 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114507 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14508 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314509
14510 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214511 ASSERT_TRUE(response);
14512 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314513 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14514 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214515 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114516 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314517 EXPECT_EQ("hello!", response_data);
14518 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614519 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314520 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614521 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314522}
14523
bncd16676a2016-07-20 16:23:0114524TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414525 HttpRequestInfo request;
14526 request.method = "GET";
bncce36dca22015-04-21 22:11:2314527 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414528
danakj1fd259a02016-04-16 03:17:0914529 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614530 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414531
ttuttled9dbc652015-09-29 20:00:5914532 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414533 StaticSocketDataProvider data;
14534 data.set_connect_data(mock_connect);
14535 session_deps_.socket_factory->AddSocketDataProvider(&data);
14536
14537 TestCompletionCallback callback;
14538
tfarina42834112016-09-22 13:38:2014539 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114540 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414541
14542 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114543 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414544
[email protected]79e1fd62013-06-20 06:50:0414545 // We don't care whether this succeeds or fails, but it shouldn't crash.
14546 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614547 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714548
14549 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614550 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714551 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114552 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914553
14554 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614555 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914556 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414557}
14558
bncd16676a2016-07-20 16:23:0114559TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414560 HttpRequestInfo request;
14561 request.method = "GET";
bncce36dca22015-04-21 22:11:2314562 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414563
danakj1fd259a02016-04-16 03:17:0914564 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614565 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414566
ttuttled9dbc652015-09-29 20:00:5914567 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414568 StaticSocketDataProvider data;
14569 data.set_connect_data(mock_connect);
14570 session_deps_.socket_factory->AddSocketDataProvider(&data);
14571
14572 TestCompletionCallback callback;
14573
tfarina42834112016-09-22 13:38:2014574 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114575 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414576
14577 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114578 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414579
[email protected]79e1fd62013-06-20 06:50:0414580 // We don't care whether this succeeds or fails, but it shouldn't crash.
14581 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614582 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714583
14584 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614585 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714586 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114587 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914588
14589 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614590 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914591 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414592}
14593
bncd16676a2016-07-20 16:23:0114594TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414595 HttpRequestInfo request;
14596 request.method = "GET";
bncce36dca22015-04-21 22:11:2314597 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414598
danakj1fd259a02016-04-16 03:17:0914599 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614600 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414601
14602 MockWrite data_writes[] = {
14603 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14604 };
14605 MockRead data_reads[] = {
14606 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14607 };
14608
14609 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14610 data_writes, arraysize(data_writes));
14611 session_deps_.socket_factory->AddSocketDataProvider(&data);
14612
14613 TestCompletionCallback callback;
14614
tfarina42834112016-09-22 13:38:2014615 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114616 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414617
14618 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114619 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414620
[email protected]79e1fd62013-06-20 06:50:0414621 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614622 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414623 EXPECT_TRUE(request_headers.HasHeader("Host"));
14624}
14625
bncd16676a2016-07-20 16:23:0114626TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414627 HttpRequestInfo request;
14628 request.method = "GET";
bncce36dca22015-04-21 22:11:2314629 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414630
danakj1fd259a02016-04-16 03:17:0914631 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614632 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414633
14634 MockWrite data_writes[] = {
14635 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14636 };
14637 MockRead data_reads[] = {
14638 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14639 };
14640
14641 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14642 data_writes, arraysize(data_writes));
14643 session_deps_.socket_factory->AddSocketDataProvider(&data);
14644
14645 TestCompletionCallback callback;
14646
tfarina42834112016-09-22 13:38:2014647 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114648 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414649
14650 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114651 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414652
[email protected]79e1fd62013-06-20 06:50:0414653 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614654 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414655 EXPECT_TRUE(request_headers.HasHeader("Host"));
14656}
14657
bncd16676a2016-07-20 16:23:0114658TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414659 HttpRequestInfo request;
14660 request.method = "GET";
bncce36dca22015-04-21 22:11:2314661 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414662
danakj1fd259a02016-04-16 03:17:0914663 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614664 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414665
14666 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314667 MockWrite(
14668 "GET / HTTP/1.1\r\n"
14669 "Host: www.example.org\r\n"
14670 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414671 };
14672 MockRead data_reads[] = {
14673 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14674 };
14675
14676 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14677 data_writes, arraysize(data_writes));
14678 session_deps_.socket_factory->AddSocketDataProvider(&data);
14679
14680 TestCompletionCallback callback;
14681
tfarina42834112016-09-22 13:38:2014682 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114683 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414684
14685 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114686 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414687
[email protected]79e1fd62013-06-20 06:50:0414688 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614689 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414690 EXPECT_TRUE(request_headers.HasHeader("Host"));
14691}
14692
bncd16676a2016-07-20 16:23:0114693TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414694 HttpRequestInfo request;
14695 request.method = "GET";
bncce36dca22015-04-21 22:11:2314696 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414697
danakj1fd259a02016-04-16 03:17:0914698 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614699 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414700
14701 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314702 MockWrite(
14703 "GET / HTTP/1.1\r\n"
14704 "Host: www.example.org\r\n"
14705 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414706 };
14707 MockRead data_reads[] = {
14708 MockRead(ASYNC, ERR_CONNECTION_RESET),
14709 };
14710
14711 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14712 data_writes, arraysize(data_writes));
14713 session_deps_.socket_factory->AddSocketDataProvider(&data);
14714
14715 TestCompletionCallback callback;
14716
tfarina42834112016-09-22 13:38:2014717 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414719
14720 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114721 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414722
[email protected]79e1fd62013-06-20 06:50:0414723 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614724 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414725 EXPECT_TRUE(request_headers.HasHeader("Host"));
14726}
14727
bncd16676a2016-07-20 16:23:0114728TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0414729 HttpRequestInfo request;
14730 request.method = "GET";
bncce36dca22015-04-21 22:11:2314731 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414732 request.extra_headers.SetHeader("X-Foo", "bar");
14733
danakj1fd259a02016-04-16 03:17:0914734 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614735 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414736
14737 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314738 MockWrite(
14739 "GET / HTTP/1.1\r\n"
14740 "Host: www.example.org\r\n"
14741 "Connection: keep-alive\r\n"
14742 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414743 };
14744 MockRead data_reads[] = {
14745 MockRead("HTTP/1.1 200 OK\r\n"
14746 "Content-Length: 5\r\n\r\n"
14747 "hello"),
14748 MockRead(ASYNC, ERR_UNEXPECTED),
14749 };
14750
14751 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14752 data_writes, arraysize(data_writes));
14753 session_deps_.socket_factory->AddSocketDataProvider(&data);
14754
14755 TestCompletionCallback callback;
14756
tfarina42834112016-09-22 13:38:2014757 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114758 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414759
14760 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114761 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0414762
14763 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614764 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414765 std::string foo;
14766 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14767 EXPECT_EQ("bar", foo);
14768}
14769
[email protected]bf828982013-08-14 18:01:4714770namespace {
14771
yhiranoa7e05bb2014-11-06 05:40:3914772// Fake HttpStream that simply records calls to SetPriority().
14773class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0314774 public base::SupportsWeakPtr<FakeStream> {
14775 public:
14776 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2014777 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0314778
14779 RequestPriority priority() const { return priority_; }
14780
dchengb03027d2014-10-21 12:00:2014781 int InitializeStream(const HttpRequestInfo* request_info,
14782 RequestPriority priority,
tfarina42834112016-09-22 13:38:2014783 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2014784 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314785 return ERR_IO_PENDING;
14786 }
14787
dchengb03027d2014-10-21 12:00:2014788 int SendRequest(const HttpRequestHeaders& request_headers,
14789 HttpResponseInfo* response,
14790 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314791 ADD_FAILURE();
14792 return ERR_UNEXPECTED;
14793 }
14794
dchengb03027d2014-10-21 12:00:2014795 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314796 ADD_FAILURE();
14797 return ERR_UNEXPECTED;
14798 }
14799
dchengb03027d2014-10-21 12:00:2014800 int ReadResponseBody(IOBuffer* buf,
14801 int buf_len,
14802 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314803 ADD_FAILURE();
14804 return ERR_UNEXPECTED;
14805 }
14806
dchengb03027d2014-10-21 12:00:2014807 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0314808
dchengb03027d2014-10-21 12:00:2014809 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0314810 ADD_FAILURE();
14811 return false;
14812 }
14813
dchengb03027d2014-10-21 12:00:2014814 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0314815 ADD_FAILURE();
14816 return false;
14817 }
14818
dchengb03027d2014-10-21 12:00:2014819 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314820
mmenkebd84c392015-09-02 14:12:3414821 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314822
sclittle4de1bab92015-09-22 21:28:2414823 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914824 ADD_FAILURE();
14825 return 0;
14826 }
14827
sclittlebe1ccf62015-09-02 19:40:3614828 int64_t GetTotalSentBytes() const override {
14829 ADD_FAILURE();
14830 return 0;
14831 }
14832
dchengb03027d2014-10-21 12:00:2014833 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314834 ADD_FAILURE();
14835 return false;
14836 }
14837
dchengb03027d2014-10-21 12:00:2014838 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14839
14840 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314841 ADD_FAILURE();
14842 }
14843
ttuttled9dbc652015-09-29 20:00:5914844 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14845
nharper78e6d2b2016-09-21 05:42:3514846 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
14847 TokenBindingType tb_type,
14848 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1414849 ADD_FAILURE();
14850 return ERR_NOT_IMPLEMENTED;
14851 }
14852
dchengb03027d2014-10-21 12:00:2014853 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314854
zhongyica364fbb2015-12-12 03:39:1214855 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14856
dchengb03027d2014-10-21 12:00:2014857 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314858
yhiranoa7e05bb2014-11-06 05:40:3914859 HttpStream* RenewStreamForAuth() override { return NULL; }
14860
[email protected]e86839fd2013-08-14 18:29:0314861 private:
14862 RequestPriority priority_;
14863
14864 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14865};
14866
14867// Fake HttpStreamRequest that simply records calls to SetPriority()
14868// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714869class FakeStreamRequest : public HttpStreamRequest,
14870 public base::SupportsWeakPtr<FakeStreamRequest> {
14871 public:
[email protected]e86839fd2013-08-14 18:29:0314872 FakeStreamRequest(RequestPriority priority,
14873 HttpStreamRequest::Delegate* delegate)
14874 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414875 delegate_(delegate),
14876 websocket_stream_create_helper_(NULL) {}
14877
14878 FakeStreamRequest(RequestPriority priority,
14879 HttpStreamRequest::Delegate* delegate,
14880 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14881 : priority_(priority),
14882 delegate_(delegate),
14883 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314884
dchengb03027d2014-10-21 12:00:2014885 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714886
14887 RequestPriority priority() const { return priority_; }
14888
[email protected]831e4a32013-11-14 02:14:4414889 const WebSocketHandshakeStreamBase::CreateHelper*
14890 websocket_stream_create_helper() const {
14891 return websocket_stream_create_helper_;
14892 }
14893
[email protected]e86839fd2013-08-14 18:29:0314894 // Create a new FakeStream and pass it to the request's
14895 // delegate. Returns a weak pointer to the FakeStream.
14896 base::WeakPtr<FakeStream> FinishStreamRequest() {
14897 FakeStream* fake_stream = new FakeStream(priority_);
14898 // Do this before calling OnStreamReady() as OnStreamReady() may
14899 // immediately delete |fake_stream|.
14900 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14901 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14902 return weak_stream;
14903 }
14904
dchengb03027d2014-10-21 12:00:2014905 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714906 ADD_FAILURE();
14907 return ERR_UNEXPECTED;
14908 }
14909
dchengb03027d2014-10-21 12:00:2014910 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714911 ADD_FAILURE();
14912 return LoadState();
14913 }
14914
dchengb03027d2014-10-21 12:00:2014915 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714916
bnc94c92842016-09-21 15:22:5214917 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714918
bnc6227b26e2016-08-12 02:00:4314919 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714920
dchengb03027d2014-10-21 12:00:2014921 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714922
ttuttle1f2d7e92015-04-28 16:17:4714923 const ConnectionAttempts& connection_attempts() const override {
14924 static ConnectionAttempts no_attempts;
14925 return no_attempts;
14926 }
14927
[email protected]bf828982013-08-14 18:01:4714928 private:
14929 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314930 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414931 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714932
14933 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14934};
14935
14936// Fake HttpStreamFactory that vends FakeStreamRequests.
14937class FakeStreamFactory : public HttpStreamFactory {
14938 public:
14939 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014940 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714941
14942 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14943 // RequestStream() (which may be NULL if it was destroyed already).
14944 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14945 return last_stream_request_;
14946 }
14947
dchengb03027d2014-10-21 12:00:2014948 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14949 RequestPriority priority,
14950 const SSLConfig& server_ssl_config,
14951 const SSLConfig& proxy_ssl_config,
14952 HttpStreamRequest::Delegate* delegate,
tfarina42834112016-09-22 13:38:2014953 const NetLogWithSource& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314954 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714955 last_stream_request_ = fake_request->AsWeakPtr();
14956 return fake_request;
14957 }
14958
xunjieli5749218c2016-03-22 16:43:0614959 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0814960 const HttpRequestInfo& info,
14961 RequestPriority priority,
14962 const SSLConfig& server_ssl_config,
14963 const SSLConfig& proxy_ssl_config,
14964 HttpStreamRequest::Delegate* delegate,
tfarina42834112016-09-22 13:38:2014965 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0814966 NOTREACHED();
14967 return nullptr;
14968 }
14969
dchengb03027d2014-10-21 12:00:2014970 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714971 const HttpRequestInfo& info,
14972 RequestPriority priority,
14973 const SSLConfig& server_ssl_config,
14974 const SSLConfig& proxy_ssl_config,
14975 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614976 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
tfarina42834112016-09-22 13:38:2014977 const NetLogWithSource& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414978 FakeStreamRequest* fake_request =
14979 new FakeStreamRequest(priority, delegate, create_helper);
14980 last_stream_request_ = fake_request->AsWeakPtr();
14981 return fake_request;
[email protected]bf828982013-08-14 18:01:4714982 }
14983
dchengb03027d2014-10-21 12:00:2014984 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5914985 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4714986 ADD_FAILURE();
14987 }
14988
dchengb03027d2014-10-21 12:00:2014989 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714990 ADD_FAILURE();
14991 return NULL;
14992 }
14993
14994 private:
14995 base::WeakPtr<FakeStreamRequest> last_stream_request_;
14996
14997 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
14998};
14999
Adam Rice425cf122015-01-19 06:18:2415000// TODO(ricea): Maybe unify this with the one in
15001// url_request_http_job_unittest.cc ?
15002class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15003 public:
danakj1fd259a02016-04-16 03:17:0915004 FakeWebSocketBasicHandshakeStream(
15005 std::unique_ptr<ClientSocketHandle> connection,
15006 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215007 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415008
15009 // Fake implementation of HttpStreamBase methods.
15010 // This ends up being quite "real" because this object has to really send data
15011 // on the mock socket. It might be easier to use the real implementation, but
15012 // the fact that the WebSocket code is not compiled on iOS makes that
15013 // difficult.
15014 int InitializeStream(const HttpRequestInfo* request_info,
15015 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015016 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415017 const CompletionCallback& callback) override {
15018 state_.Initialize(request_info, priority, net_log, callback);
15019 return OK;
15020 }
15021
15022 int SendRequest(const HttpRequestHeaders& request_headers,
15023 HttpResponseInfo* response,
15024 const CompletionCallback& callback) override {
15025 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15026 response, callback);
15027 }
15028
15029 int ReadResponseHeaders(const CompletionCallback& callback) override {
15030 return parser()->ReadResponseHeaders(callback);
15031 }
15032
15033 int ReadResponseBody(IOBuffer* buf,
15034 int buf_len,
15035 const CompletionCallback& callback) override {
15036 NOTREACHED();
15037 return ERR_IO_PENDING;
15038 }
15039
15040 void Close(bool not_reusable) override {
15041 if (parser())
15042 parser()->Close(true);
15043 }
15044
15045 bool IsResponseBodyComplete() const override {
15046 NOTREACHED();
15047 return false;
15048 }
15049
Adam Rice425cf122015-01-19 06:18:2415050 bool IsConnectionReused() const override {
15051 NOTREACHED();
15052 return false;
15053 }
15054 void SetConnectionReused() override { NOTREACHED(); }
15055
mmenkebd84c392015-09-02 14:12:3415056 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415057
sclittle4de1bab92015-09-22 21:28:2415058 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415059 NOTREACHED();
15060 return 0;
15061 }
15062
sclittlebe1ccf62015-09-02 19:40:3615063 int64_t GetTotalSentBytes() const override {
15064 NOTREACHED();
15065 return 0;
15066 }
15067
Adam Rice425cf122015-01-19 06:18:2415068 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15069 NOTREACHED();
15070 return false;
15071 }
15072
Adam Ricecb76ac62015-02-20 05:33:2515073 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415074
15075 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15076 NOTREACHED();
15077 }
15078
ttuttled9dbc652015-09-29 20:00:5915079 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15080
nharper78e6d2b2016-09-21 05:42:3515081 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15082 TokenBindingType tb_type,
15083 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415084 ADD_FAILURE();
15085 return ERR_NOT_IMPLEMENTED;
15086 }
15087
Adam Rice425cf122015-01-19 06:18:2415088 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15089
zhongyica364fbb2015-12-12 03:39:1215090 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15091
Adam Rice425cf122015-01-19 06:18:2415092 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15093
Adam Rice425cf122015-01-19 06:18:2415094 HttpStream* RenewStreamForAuth() override {
15095 NOTREACHED();
15096 return nullptr;
15097 }
15098
15099 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915100 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415101 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915102 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415103 }
15104
15105 private:
15106 HttpStreamParser* parser() const { return state_.parser(); }
15107 HttpBasicState state_;
15108
15109 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15110};
15111
[email protected]831e4a32013-11-14 02:14:4415112// TODO(yhirano): Split this class out into a net/websockets file, if it is
15113// worth doing.
15114class FakeWebSocketStreamCreateHelper :
15115 public WebSocketHandshakeStreamBase::CreateHelper {
15116 public:
dchengb03027d2014-10-21 12:00:2015117 WebSocketHandshakeStreamBase* CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915118 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315119 bool using_proxy) override {
dchengc7eeda422015-12-26 03:56:4815120 return new FakeWebSocketBasicHandshakeStream(std::move(connection),
Adam Rice425cf122015-01-19 06:18:2415121 using_proxy);
[email protected]831e4a32013-11-14 02:14:4415122 }
15123
dchengb03027d2014-10-21 12:00:2015124 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4415125 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1315126 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4415127 NOTREACHED();
15128 return NULL;
15129 };
15130
dchengb03027d2014-10-21 12:00:2015131 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415132
danakj1fd259a02016-04-16 03:17:0915133 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415134 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915135 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415136 }
15137};
15138
[email protected]bf828982013-08-14 18:01:4715139} // namespace
15140
15141// Make sure that HttpNetworkTransaction passes on its priority to its
15142// stream request on start.
bncd16676a2016-07-20 16:23:0115143TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915144 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215145 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715146 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915147 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715148
krasinc06a72a2016-12-21 03:42:4615149 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115150 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715151
wezca1070932016-05-26 20:30:5215152 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715153
[email protected]bf828982013-08-14 18:01:4715154 TestCompletionCallback callback;
15155 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015156 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715157
15158 base::WeakPtr<FakeStreamRequest> fake_request =
15159 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215160 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715161 EXPECT_EQ(LOW, fake_request->priority());
15162}
15163
15164// Make sure that HttpNetworkTransaction passes on its priority
15165// updates to its stream request.
bncd16676a2016-07-20 16:23:0115166TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915167 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215168 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715169 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915170 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715171
krasinc06a72a2016-12-21 03:42:4615172 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115173 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715174
[email protected]bf828982013-08-14 18:01:4715175 TestCompletionCallback callback;
15176 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015177 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715178
15179 base::WeakPtr<FakeStreamRequest> fake_request =
15180 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215181 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715182 EXPECT_EQ(LOW, fake_request->priority());
15183
15184 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215185 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715186 EXPECT_EQ(LOWEST, fake_request->priority());
15187}
15188
[email protected]e86839fd2013-08-14 18:29:0315189// Make sure that HttpNetworkTransaction passes on its priority
15190// updates to its stream.
bncd16676a2016-07-20 16:23:0115191TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915192 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215193 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315194 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915195 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315196
krasinc06a72a2016-12-21 03:42:4615197 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115198 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315199
[email protected]e86839fd2013-08-14 18:29:0315200 TestCompletionCallback callback;
15201 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015202 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315203
15204 base::WeakPtr<FakeStreamRequest> fake_request =
15205 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215206 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315207 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215208 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315209 EXPECT_EQ(LOW, fake_stream->priority());
15210
15211 trans.SetPriority(LOWEST);
15212 EXPECT_EQ(LOWEST, fake_stream->priority());
15213}
15214
bncd16676a2016-07-20 16:23:0115215TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415216 // The same logic needs to be tested for both ws: and wss: schemes, but this
15217 // test is already parameterised on NextProto, so it uses a loop to verify
15218 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315219 std::string test_cases[] = {"ws://www.example.org/",
15220 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415221 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915222 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215223 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415224 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15225 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315226 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915227 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415228
krasinc06a72a2016-12-21 03:42:4615229 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115230 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415231 trans.SetWebSocketHandshakeStreamCreateHelper(
15232 &websocket_stream_create_helper);
15233
[email protected]831e4a32013-11-14 02:14:4415234 TestCompletionCallback callback;
15235 request.method = "GET";
15236 request.url = GURL(test_cases[i]);
15237
15238 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015239 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415240
15241 base::WeakPtr<FakeStreamRequest> fake_request =
15242 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215243 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415244 EXPECT_EQ(&websocket_stream_create_helper,
15245 fake_request->websocket_stream_create_helper());
15246 }
15247}
15248
[email protected]043b68c82013-08-22 23:41:5215249// Tests that when a used socket is returned to the SSL socket pool, it's closed
15250// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115251TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215252 ClientSocketPoolManager::set_max_sockets_per_group(
15253 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15254 ClientSocketPoolManager::set_max_sockets_per_pool(
15255 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15256
15257 // Set up SSL request.
15258
15259 HttpRequestInfo ssl_request;
15260 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315261 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215262
15263 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315264 MockWrite(
15265 "GET / HTTP/1.1\r\n"
15266 "Host: www.example.org\r\n"
15267 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215268 };
15269 MockRead ssl_reads[] = {
15270 MockRead("HTTP/1.1 200 OK\r\n"),
15271 MockRead("Content-Length: 11\r\n\r\n"),
15272 MockRead("hello world"),
15273 MockRead(SYNCHRONOUS, OK),
15274 };
15275 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15276 ssl_writes, arraysize(ssl_writes));
15277 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15278
15279 SSLSocketDataProvider ssl(ASYNC, OK);
15280 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15281
15282 // Set up HTTP request.
15283
15284 HttpRequestInfo http_request;
15285 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315286 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215287
15288 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315289 MockWrite(
15290 "GET / HTTP/1.1\r\n"
15291 "Host: www.example.org\r\n"
15292 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215293 };
15294 MockRead http_reads[] = {
15295 MockRead("HTTP/1.1 200 OK\r\n"),
15296 MockRead("Content-Length: 7\r\n\r\n"),
15297 MockRead("falafel"),
15298 MockRead(SYNCHRONOUS, OK),
15299 };
15300 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15301 http_writes, arraysize(http_writes));
15302 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15303
danakj1fd259a02016-04-16 03:17:0915304 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215305
15306 // Start the SSL request.
15307 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615308 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015309 ASSERT_EQ(ERR_IO_PENDING,
15310 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15311 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215312
15313 // Start the HTTP request. Pool should stall.
15314 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615315 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015316 ASSERT_EQ(ERR_IO_PENDING,
15317 http_trans.Start(&http_request, http_callback.callback(),
15318 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115319 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215320
15321 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115322 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215323 std::string response_data;
bnc691fda62016-08-12 00:43:1615324 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215325 EXPECT_EQ("hello world", response_data);
15326
15327 // The SSL socket should automatically be closed, so the HTTP request can
15328 // start.
dcheng48459ac22014-08-26 00:46:4115329 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15330 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215331
15332 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115333 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615334 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215335 EXPECT_EQ("falafel", response_data);
15336
dcheng48459ac22014-08-26 00:46:4115337 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215338}
15339
15340// Tests that when a SSL connection is established but there's no corresponding
15341// request that needs it, the new socket is closed if the transport socket pool
15342// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115343TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215344 ClientSocketPoolManager::set_max_sockets_per_group(
15345 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15346 ClientSocketPoolManager::set_max_sockets_per_pool(
15347 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15348
15349 // Set up an ssl request.
15350
15351 HttpRequestInfo ssl_request;
15352 ssl_request.method = "GET";
15353 ssl_request.url = GURL("https://www.foopy.com/");
15354
15355 // No data will be sent on the SSL socket.
15356 StaticSocketDataProvider ssl_data;
15357 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15358
15359 SSLSocketDataProvider ssl(ASYNC, OK);
15360 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15361
15362 // Set up HTTP request.
15363
15364 HttpRequestInfo http_request;
15365 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315366 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215367
15368 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315369 MockWrite(
15370 "GET / HTTP/1.1\r\n"
15371 "Host: www.example.org\r\n"
15372 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215373 };
15374 MockRead http_reads[] = {
15375 MockRead("HTTP/1.1 200 OK\r\n"),
15376 MockRead("Content-Length: 7\r\n\r\n"),
15377 MockRead("falafel"),
15378 MockRead(SYNCHRONOUS, OK),
15379 };
15380 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15381 http_writes, arraysize(http_writes));
15382 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15383
danakj1fd259a02016-04-16 03:17:0915384 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215385
15386 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15387 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915388 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915389 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115390 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215391
15392 // Start the HTTP request. Pool should stall.
15393 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615394 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015395 ASSERT_EQ(ERR_IO_PENDING,
15396 http_trans.Start(&http_request, http_callback.callback(),
15397 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115398 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215399
15400 // The SSL connection will automatically be closed once the connection is
15401 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0115402 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215403 std::string response_data;
bnc691fda62016-08-12 00:43:1615404 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215405 EXPECT_EQ("falafel", response_data);
15406
dcheng48459ac22014-08-26 00:46:4115407 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215408}
15409
bncd16676a2016-07-20 16:23:0115410TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915411 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215412 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715413 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215414 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415415
15416 HttpRequestInfo request;
15417 request.method = "POST";
15418 request.url = GURL("http://www.foo.com/");
15419 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415420
danakj1fd259a02016-04-16 03:17:0915421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615422 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415423 // Send headers successfully, but get an error while sending the body.
15424 MockWrite data_writes[] = {
15425 MockWrite("POST / HTTP/1.1\r\n"
15426 "Host: www.foo.com\r\n"
15427 "Connection: keep-alive\r\n"
15428 "Content-Length: 3\r\n\r\n"),
15429 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15430 };
15431
15432 MockRead data_reads[] = {
15433 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15434 MockRead("hello world"),
15435 MockRead(SYNCHRONOUS, OK),
15436 };
15437 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15438 arraysize(data_writes));
15439 session_deps_.socket_factory->AddSocketDataProvider(&data);
15440
15441 TestCompletionCallback callback;
15442
tfarina42834112016-09-22 13:38:2015443 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115444 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415445
15446 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115447 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415448
bnc691fda62016-08-12 00:43:1615449 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215450 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415451
wezca1070932016-05-26 20:30:5215452 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415453 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15454
15455 std::string response_data;
bnc691fda62016-08-12 00:43:1615456 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115457 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415458 EXPECT_EQ("hello world", response_data);
15459}
15460
15461// This test makes sure the retry logic doesn't trigger when reading an error
15462// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0115463TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415464 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915465 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415466 MockWrite data_writes[] = {
15467 MockWrite("GET / HTTP/1.1\r\n"
15468 "Host: www.foo.com\r\n"
15469 "Connection: keep-alive\r\n\r\n"),
15470 MockWrite("POST / HTTP/1.1\r\n"
15471 "Host: www.foo.com\r\n"
15472 "Connection: keep-alive\r\n"
15473 "Content-Length: 3\r\n\r\n"),
15474 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15475 };
15476
15477 MockRead data_reads[] = {
15478 MockRead("HTTP/1.1 200 Peachy\r\n"
15479 "Content-Length: 14\r\n\r\n"),
15480 MockRead("first response"),
15481 MockRead("HTTP/1.1 400 Not OK\r\n"
15482 "Content-Length: 15\r\n\r\n"),
15483 MockRead("second response"),
15484 MockRead(SYNCHRONOUS, OK),
15485 };
15486 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15487 arraysize(data_writes));
15488 session_deps_.socket_factory->AddSocketDataProvider(&data);
15489
15490 TestCompletionCallback callback;
15491 HttpRequestInfo request1;
15492 request1.method = "GET";
15493 request1.url = GURL("http://www.foo.com/");
15494 request1.load_flags = 0;
15495
bnc691fda62016-08-12 00:43:1615496 std::unique_ptr<HttpNetworkTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4115497 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:2015498 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115499 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415500
15501 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115502 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415503
15504 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215505 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415506
wezca1070932016-05-26 20:30:5215507 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415508 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15509
15510 std::string response_data1;
15511 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0115512 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415513 EXPECT_EQ("first response", response_data1);
15514 // Delete the transaction to release the socket back into the socket pool.
15515 trans1.reset();
15516
danakj1fd259a02016-04-16 03:17:0915517 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215518 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915519 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215520 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415521
15522 HttpRequestInfo request2;
15523 request2.method = "POST";
15524 request2.url = GURL("http://www.foo.com/");
15525 request2.upload_data_stream = &upload_data_stream;
15526 request2.load_flags = 0;
15527
bnc691fda62016-08-12 00:43:1615528 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015529 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115530 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415531
15532 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115533 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415534
bnc691fda62016-08-12 00:43:1615535 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215536 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415537
wezca1070932016-05-26 20:30:5215538 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415539 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15540
15541 std::string response_data2;
bnc691fda62016-08-12 00:43:1615542 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0115543 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415544 EXPECT_EQ("second response", response_data2);
15545}
15546
bncd16676a2016-07-20 16:23:0115547TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415548 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915549 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215550 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715551 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215552 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415553
15554 HttpRequestInfo request;
15555 request.method = "POST";
15556 request.url = GURL("http://www.foo.com/");
15557 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415558
danakj1fd259a02016-04-16 03:17:0915559 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615560 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415561 // Send headers successfully, but get an error while sending the body.
15562 MockWrite data_writes[] = {
15563 MockWrite("POST / HTTP/1.1\r\n"
15564 "Host: www.foo.com\r\n"
15565 "Connection: keep-alive\r\n"
15566 "Content-Length: 3\r\n\r\n"
15567 "fo"),
15568 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15569 };
15570
15571 MockRead data_reads[] = {
15572 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15573 MockRead("hello world"),
15574 MockRead(SYNCHRONOUS, OK),
15575 };
15576 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15577 arraysize(data_writes));
15578 session_deps_.socket_factory->AddSocketDataProvider(&data);
15579
15580 TestCompletionCallback callback;
15581
tfarina42834112016-09-22 13:38:2015582 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415584
15585 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115586 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415587
bnc691fda62016-08-12 00:43:1615588 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215589 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415590
wezca1070932016-05-26 20:30:5215591 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415592 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15593
15594 std::string response_data;
bnc691fda62016-08-12 00:43:1615595 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115596 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415597 EXPECT_EQ("hello world", response_data);
15598}
15599
15600// This tests the more common case than the previous test, where headers and
15601// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0115602TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715603 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415604
15605 HttpRequestInfo request;
15606 request.method = "POST";
15607 request.url = GURL("http://www.foo.com/");
15608 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415609
danakj1fd259a02016-04-16 03:17:0915610 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615611 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415612 // Send headers successfully, but get an error while sending the body.
15613 MockWrite data_writes[] = {
15614 MockWrite("POST / HTTP/1.1\r\n"
15615 "Host: www.foo.com\r\n"
15616 "Connection: keep-alive\r\n"
15617 "Transfer-Encoding: chunked\r\n\r\n"),
15618 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15619 };
15620
15621 MockRead data_reads[] = {
15622 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15623 MockRead("hello world"),
15624 MockRead(SYNCHRONOUS, OK),
15625 };
15626 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15627 arraysize(data_writes));
15628 session_deps_.socket_factory->AddSocketDataProvider(&data);
15629
15630 TestCompletionCallback callback;
15631
tfarina42834112016-09-22 13:38:2015632 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115633 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415634 // Make sure the headers are sent before adding a chunk. This ensures that
15635 // they can't be merged with the body in a single send. Not currently
15636 // necessary since a chunked body is never merged with headers, but this makes
15637 // the test more future proof.
15638 base::RunLoop().RunUntilIdle();
15639
mmenkecbc2b712014-10-09 20:29:0715640 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415641
15642 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115643 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415644
bnc691fda62016-08-12 00:43:1615645 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215646 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415647
wezca1070932016-05-26 20:30:5215648 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415649 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15650
15651 std::string response_data;
bnc691fda62016-08-12 00:43:1615652 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115653 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415654 EXPECT_EQ("hello world", response_data);
15655}
15656
bncd16676a2016-07-20 16:23:0115657TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915658 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215659 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715660 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215661 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415662
15663 HttpRequestInfo request;
15664 request.method = "POST";
15665 request.url = GURL("http://www.foo.com/");
15666 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415667
danakj1fd259a02016-04-16 03:17:0915668 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615669 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415670
15671 MockWrite data_writes[] = {
15672 MockWrite("POST / HTTP/1.1\r\n"
15673 "Host: www.foo.com\r\n"
15674 "Connection: keep-alive\r\n"
15675 "Content-Length: 3\r\n\r\n"),
15676 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15677 };
15678
15679 MockRead data_reads[] = {
15680 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15681 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15682 MockRead("hello world"),
15683 MockRead(SYNCHRONOUS, OK),
15684 };
15685 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15686 arraysize(data_writes));
15687 session_deps_.socket_factory->AddSocketDataProvider(&data);
15688
15689 TestCompletionCallback callback;
15690
tfarina42834112016-09-22 13:38:2015691 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115692 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415693
15694 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115695 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415696
bnc691fda62016-08-12 00:43:1615697 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215698 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415699
wezca1070932016-05-26 20:30:5215700 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415701 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15702
15703 std::string response_data;
bnc691fda62016-08-12 00:43:1615704 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115705 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415706 EXPECT_EQ("hello world", response_data);
15707}
15708
bncd16676a2016-07-20 16:23:0115709TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915710 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215711 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715712 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215713 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415714
15715 HttpRequestInfo request;
15716 request.method = "POST";
15717 request.url = GURL("http://www.foo.com/");
15718 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415719
danakj1fd259a02016-04-16 03:17:0915720 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615721 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415722 // Send headers successfully, but get an error while sending the body.
15723 MockWrite data_writes[] = {
15724 MockWrite("POST / HTTP/1.1\r\n"
15725 "Host: www.foo.com\r\n"
15726 "Connection: keep-alive\r\n"
15727 "Content-Length: 3\r\n\r\n"),
15728 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15729 };
15730
15731 MockRead data_reads[] = {
15732 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15733 MockRead("hello world"),
15734 MockRead(SYNCHRONOUS, OK),
15735 };
15736 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15737 arraysize(data_writes));
15738 session_deps_.socket_factory->AddSocketDataProvider(&data);
15739
15740 TestCompletionCallback callback;
15741
tfarina42834112016-09-22 13:38:2015742 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115743 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415744
15745 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115746 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415747}
15748
bncd16676a2016-07-20 16:23:0115749TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415750 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915751 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215752 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715753 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215754 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415755
15756 HttpRequestInfo request;
15757 request.method = "POST";
15758 request.url = GURL("http://www.foo.com/");
15759 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415760
danakj1fd259a02016-04-16 03:17:0915761 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615762 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415763 // Send headers successfully, but get an error while sending the body.
15764 MockWrite data_writes[] = {
15765 MockWrite("POST / HTTP/1.1\r\n"
15766 "Host: www.foo.com\r\n"
15767 "Connection: keep-alive\r\n"
15768 "Content-Length: 3\r\n\r\n"),
15769 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15770 };
15771
15772 MockRead data_reads[] = {
15773 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15774 MockRead("HTTP/1.0 302 Redirect\r\n"),
15775 MockRead("Location: http://somewhere-else.com/\r\n"),
15776 MockRead("Content-Length: 0\r\n\r\n"),
15777 MockRead(SYNCHRONOUS, OK),
15778 };
15779 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15780 arraysize(data_writes));
15781 session_deps_.socket_factory->AddSocketDataProvider(&data);
15782
15783 TestCompletionCallback callback;
15784
tfarina42834112016-09-22 13:38:2015785 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115786 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415787
15788 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115789 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415790}
15791
bncd16676a2016-07-20 16:23:0115792TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915793 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215794 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715795 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215796 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415797
15798 HttpRequestInfo request;
15799 request.method = "POST";
15800 request.url = GURL("http://www.foo.com/");
15801 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415802
danakj1fd259a02016-04-16 03:17:0915803 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615804 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415805 // Send headers successfully, but get an error while sending the body.
15806 MockWrite data_writes[] = {
15807 MockWrite("POST / HTTP/1.1\r\n"
15808 "Host: www.foo.com\r\n"
15809 "Connection: keep-alive\r\n"
15810 "Content-Length: 3\r\n\r\n"),
15811 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15812 };
15813
15814 MockRead data_reads[] = {
15815 MockRead("HTTP 0.9 rocks!"),
15816 MockRead(SYNCHRONOUS, OK),
15817 };
15818 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15819 arraysize(data_writes));
15820 session_deps_.socket_factory->AddSocketDataProvider(&data);
15821
15822 TestCompletionCallback callback;
15823
tfarina42834112016-09-22 13:38:2015824 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415826
15827 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115828 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415829}
15830
bncd16676a2016-07-20 16:23:0115831TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0915832 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215833 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715834 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215835 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415836
15837 HttpRequestInfo request;
15838 request.method = "POST";
15839 request.url = GURL("http://www.foo.com/");
15840 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415841
danakj1fd259a02016-04-16 03:17:0915842 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615843 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415844 // Send headers successfully, but get an error while sending the body.
15845 MockWrite data_writes[] = {
15846 MockWrite("POST / HTTP/1.1\r\n"
15847 "Host: www.foo.com\r\n"
15848 "Connection: keep-alive\r\n"
15849 "Content-Length: 3\r\n\r\n"),
15850 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15851 };
15852
15853 MockRead data_reads[] = {
15854 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15855 MockRead(SYNCHRONOUS, OK),
15856 };
15857 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15858 arraysize(data_writes));
15859 session_deps_.socket_factory->AddSocketDataProvider(&data);
15860
15861 TestCompletionCallback callback;
15862
tfarina42834112016-09-22 13:38:2015863 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115864 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415865
15866 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115867 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415868}
15869
Adam Rice425cf122015-01-19 06:18:2415870// Verify that proxy headers are not sent to the destination server when
15871// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0115872TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2415873 HttpRequestInfo request;
15874 request.method = "GET";
bncce36dca22015-04-21 22:11:2315875 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415876 AddWebSocketHeaders(&request.extra_headers);
15877
15878 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315879 session_deps_.proxy_service =
15880 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415881
danakj1fd259a02016-04-16 03:17:0915882 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415883
15884 // Since a proxy is configured, try to establish a tunnel.
15885 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1715886 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15887 "Host: www.example.org:443\r\n"
15888 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415889
15890 // After calling trans->RestartWithAuth(), this is the request we should
15891 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1715892 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15893 "Host: www.example.org:443\r\n"
15894 "Proxy-Connection: keep-alive\r\n"
15895 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415896
rsleevidb16bb02015-11-12 23:47:1715897 MockWrite("GET / HTTP/1.1\r\n"
15898 "Host: www.example.org\r\n"
15899 "Connection: Upgrade\r\n"
15900 "Upgrade: websocket\r\n"
15901 "Origin: http://www.example.org\r\n"
15902 "Sec-WebSocket-Version: 13\r\n"
15903 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415904 };
15905
15906 // The proxy responds to the connect with a 407, using a persistent
15907 // connection.
15908 MockRead data_reads[] = {
15909 // No credentials.
15910 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15911 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415912 MockRead("Content-Length: 0\r\n"),
15913 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415914
15915 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15916
15917 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15918 MockRead("Upgrade: websocket\r\n"),
15919 MockRead("Connection: Upgrade\r\n"),
15920 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15921 };
15922
15923 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15924 arraysize(data_writes));
15925 session_deps_.socket_factory->AddSocketDataProvider(&data);
15926 SSLSocketDataProvider ssl(ASYNC, OK);
15927 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15928
bnc691fda62016-08-12 00:43:1615929 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415930 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15931 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15932 trans->SetWebSocketHandshakeStreamCreateHelper(
15933 &websocket_stream_create_helper);
15934
15935 {
15936 TestCompletionCallback callback;
15937
tfarina42834112016-09-22 13:38:2015938 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115939 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2415940
15941 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115942 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2415943 }
15944
15945 const HttpResponseInfo* response = trans->GetResponseInfo();
15946 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215947 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415948 EXPECT_EQ(407, response->headers->response_code());
15949
15950 {
15951 TestCompletionCallback callback;
15952
15953 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15954 callback.callback());
robpercival214763f2016-07-01 23:27:0115955 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2415956
15957 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115958 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2415959 }
15960
15961 response = trans->GetResponseInfo();
15962 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215963 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415964
15965 EXPECT_EQ(101, response->headers->response_code());
15966
15967 trans.reset();
15968 session->CloseAllConnections();
15969}
15970
15971// Verify that proxy headers are not sent to the destination server when
15972// establishing a tunnel for an insecure WebSocket connection.
15973// This requires the authentication info to be injected into the auth cache
15974// due to crbug.com/395064
15975// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0115976TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2415977 HttpRequestInfo request;
15978 request.method = "GET";
bncce36dca22015-04-21 22:11:2315979 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415980 AddWebSocketHeaders(&request.extra_headers);
15981
15982 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315983 session_deps_.proxy_service =
15984 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415985
danakj1fd259a02016-04-16 03:17:0915986 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415987
15988 MockWrite data_writes[] = {
15989 // Try to establish a tunnel for the WebSocket connection, with
15990 // credentials. Because WebSockets have a separate set of socket pools,
15991 // they cannot and will not use the same TCP/IP connection as the
15992 // preflight HTTP request.
15993 MockWrite(
bncce36dca22015-04-21 22:11:2315994 "CONNECT www.example.org:80 HTTP/1.1\r\n"
15995 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2415996 "Proxy-Connection: keep-alive\r\n"
15997 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15998
15999 MockWrite(
16000 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316001 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416002 "Connection: Upgrade\r\n"
16003 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316004 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416005 "Sec-WebSocket-Version: 13\r\n"
16006 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16007 };
16008
16009 MockRead data_reads[] = {
16010 // HTTP CONNECT with credentials.
16011 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16012
16013 // WebSocket connection established inside tunnel.
16014 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16015 MockRead("Upgrade: websocket\r\n"),
16016 MockRead("Connection: Upgrade\r\n"),
16017 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16018 };
16019
16020 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16021 arraysize(data_writes));
16022 session_deps_.socket_factory->AddSocketDataProvider(&data);
16023
16024 session->http_auth_cache()->Add(
16025 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16026 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16027
bnc691fda62016-08-12 00:43:1616028 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2416029 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16030 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16031 trans->SetWebSocketHandshakeStreamCreateHelper(
16032 &websocket_stream_create_helper);
16033
16034 TestCompletionCallback callback;
16035
tfarina42834112016-09-22 13:38:2016036 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116037 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416038
16039 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116040 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416041
16042 const HttpResponseInfo* response = trans->GetResponseInfo();
16043 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216044 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416045
16046 EXPECT_EQ(101, response->headers->response_code());
16047
16048 trans.reset();
16049 session->CloseAllConnections();
16050}
16051
bncd16676a2016-07-20 16:23:0116052TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916053 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216054 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716055 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216056 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216057
16058 HttpRequestInfo request;
16059 request.method = "POST";
16060 request.url = GURL("http://www.foo.com/");
16061 request.upload_data_stream = &upload_data_stream;
16062
danakj1fd259a02016-04-16 03:17:0916063 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616064 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216065 MockWrite data_writes[] = {
16066 MockWrite("POST / HTTP/1.1\r\n"
16067 "Host: www.foo.com\r\n"
16068 "Connection: keep-alive\r\n"
16069 "Content-Length: 3\r\n\r\n"),
16070 MockWrite("foo"),
16071 };
16072
16073 MockRead data_reads[] = {
16074 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16075 MockRead(SYNCHRONOUS, OK),
16076 };
16077 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16078 arraysize(data_writes));
16079 session_deps_.socket_factory->AddSocketDataProvider(&data);
16080
16081 TestCompletionCallback callback;
16082
16083 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016084 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116085 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216086
16087 std::string response_data;
bnc691fda62016-08-12 00:43:1616088 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216089
16090 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616091 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216092 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616093 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216094}
16095
bncd16676a2016-07-20 16:23:0116096TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916097 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216098 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716099 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216100 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216101
16102 HttpRequestInfo request;
16103 request.method = "POST";
16104 request.url = GURL("http://www.foo.com/");
16105 request.upload_data_stream = &upload_data_stream;
16106
danakj1fd259a02016-04-16 03:17:0916107 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616108 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216109 MockWrite data_writes[] = {
16110 MockWrite("POST / HTTP/1.1\r\n"
16111 "Host: www.foo.com\r\n"
16112 "Connection: keep-alive\r\n"
16113 "Content-Length: 3\r\n\r\n"),
16114 MockWrite("foo"),
16115 };
16116
16117 MockRead data_reads[] = {
16118 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16119 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16120 MockRead(SYNCHRONOUS, OK),
16121 };
16122 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16123 arraysize(data_writes));
16124 session_deps_.socket_factory->AddSocketDataProvider(&data);
16125
16126 TestCompletionCallback callback;
16127
16128 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016129 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116130 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216131
16132 std::string response_data;
bnc691fda62016-08-12 00:43:1616133 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216134
16135 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616136 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216137 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616138 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216139}
16140
bncd16676a2016-07-20 16:23:0116141TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216142 ChunkedUploadDataStream upload_data_stream(0);
16143
16144 HttpRequestInfo request;
16145 request.method = "POST";
16146 request.url = GURL("http://www.foo.com/");
16147 request.upload_data_stream = &upload_data_stream;
16148
danakj1fd259a02016-04-16 03:17:0916149 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616150 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216151 // Send headers successfully, but get an error while sending the body.
16152 MockWrite data_writes[] = {
16153 MockWrite("POST / HTTP/1.1\r\n"
16154 "Host: www.foo.com\r\n"
16155 "Connection: keep-alive\r\n"
16156 "Transfer-Encoding: chunked\r\n\r\n"),
16157 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16158 };
16159
16160 MockRead data_reads[] = {
16161 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16162 MockRead(SYNCHRONOUS, OK),
16163 };
16164 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16165 arraysize(data_writes));
16166 session_deps_.socket_factory->AddSocketDataProvider(&data);
16167
16168 TestCompletionCallback callback;
16169
16170 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016171 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216172
16173 base::RunLoop().RunUntilIdle();
16174 upload_data_stream.AppendData("f", 1, false);
16175
16176 base::RunLoop().RunUntilIdle();
16177 upload_data_stream.AppendData("oo", 2, true);
16178
robpercival214763f2016-07-01 23:27:0116179 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216180
16181 std::string response_data;
bnc691fda62016-08-12 00:43:1616182 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216183
16184 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616185 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216186 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616187 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216188}
16189
rdsmith1d343be52016-10-21 20:37:5016190// Confirm that transactions whose throttle is created in (and stays in)
16191// the unthrottled state are not blocked.
16192TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16193 TestNetworkStreamThrottler* throttler(nullptr);
16194 std::unique_ptr<HttpNetworkSession> session(
16195 CreateSessionWithThrottler(&session_deps_, &throttler));
16196
16197 // Send a simple request and make sure it goes through.
16198 HttpRequestInfo request;
16199 request.method = "GET";
16200 request.url = GURL("http://www.example.org/");
16201
16202 std::unique_ptr<HttpTransaction> trans(
16203 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16204
16205 MockWrite data_writes[] = {
16206 MockWrite("GET / HTTP/1.1\r\n"
16207 "Host: www.example.org\r\n"
16208 "Connection: keep-alive\r\n\r\n"),
16209 };
16210 MockRead data_reads[] = {
16211 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16212 MockRead(SYNCHRONOUS, OK),
16213 };
16214 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16215 arraysize(data_writes));
16216 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16217
16218 TestCompletionCallback callback;
16219 trans->Start(&request, callback.callback(), NetLogWithSource());
16220 EXPECT_EQ(OK, callback.WaitForResult());
16221}
16222
16223// Confirm requests can be blocked by a throttler, and are resumed
16224// when the throttle is unblocked.
16225TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16226 TestNetworkStreamThrottler* throttler(nullptr);
16227 std::unique_ptr<HttpNetworkSession> session(
16228 CreateSessionWithThrottler(&session_deps_, &throttler));
16229
16230 // Send a simple request and make sure it goes through.
16231 HttpRequestInfo request;
16232 request.method = "GET";
16233 request.url = GURL("http://www.example.org/");
16234
16235 MockWrite data_writes[] = {
16236 MockWrite("GET / HTTP/1.1\r\n"
16237 "Host: www.example.org\r\n"
16238 "Connection: keep-alive\r\n\r\n"),
16239 };
16240 MockRead data_reads[] = {
16241 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16242 MockRead(SYNCHRONOUS, OK),
16243 };
16244 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16245 arraysize(data_writes));
16246 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16247
16248 // Start a request that will be throttled at start; confirm it
16249 // doesn't complete.
16250 throttler->set_throttle_new_requests(true);
16251 std::unique_ptr<HttpTransaction> trans(
16252 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16253
16254 TestCompletionCallback callback;
16255 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16256 EXPECT_EQ(ERR_IO_PENDING, rv);
16257
16258 base::RunLoop().RunUntilIdle();
16259 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16260 EXPECT_FALSE(callback.have_result());
16261
16262 // Confirm the request goes on to complete when unthrottled.
16263 throttler->UnthrottleAllRequests();
16264 base::RunLoop().RunUntilIdle();
16265 ASSERT_TRUE(callback.have_result());
16266 EXPECT_EQ(OK, callback.WaitForResult());
16267}
16268
16269// Destroy a request while it's throttled.
16270TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16271 TestNetworkStreamThrottler* throttler(nullptr);
16272 std::unique_ptr<HttpNetworkSession> session(
16273 CreateSessionWithThrottler(&session_deps_, &throttler));
16274
16275 // Send a simple request and make sure it goes through.
16276 HttpRequestInfo request;
16277 request.method = "GET";
16278 request.url = GURL("http://www.example.org/");
16279
16280 MockWrite data_writes[] = {
16281 MockWrite("GET / HTTP/1.1\r\n"
16282 "Host: www.example.org\r\n"
16283 "Connection: keep-alive\r\n\r\n"),
16284 };
16285 MockRead data_reads[] = {
16286 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16287 MockRead(SYNCHRONOUS, OK),
16288 };
16289 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16290 arraysize(data_writes));
16291 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16292
16293 // Start a request that will be throttled at start; confirm it
16294 // doesn't complete.
16295 throttler->set_throttle_new_requests(true);
16296 std::unique_ptr<HttpTransaction> trans(
16297 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16298
16299 TestCompletionCallback callback;
16300 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16301 EXPECT_EQ(ERR_IO_PENDING, rv);
16302
16303 base::RunLoop().RunUntilIdle();
16304 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16305 EXPECT_FALSE(callback.have_result());
16306
16307 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16308 trans.reset();
16309 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16310}
16311
16312// Confirm the throttler receives SetPriority calls.
16313TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16314 TestNetworkStreamThrottler* throttler(nullptr);
16315 std::unique_ptr<HttpNetworkSession> session(
16316 CreateSessionWithThrottler(&session_deps_, &throttler));
16317
16318 // Send a simple request and make sure it goes through.
16319 HttpRequestInfo request;
16320 request.method = "GET";
16321 request.url = GURL("http://www.example.org/");
16322
16323 MockWrite data_writes[] = {
16324 MockWrite("GET / HTTP/1.1\r\n"
16325 "Host: www.example.org\r\n"
16326 "Connection: keep-alive\r\n\r\n"),
16327 };
16328 MockRead data_reads[] = {
16329 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16330 MockRead(SYNCHRONOUS, OK),
16331 };
16332 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16333 arraysize(data_writes));
16334 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16335
16336 throttler->set_throttle_new_requests(true);
16337 std::unique_ptr<HttpTransaction> trans(
16338 new HttpNetworkTransaction(IDLE, session.get()));
16339 // Start the transaction to associate a throttle with it.
16340 TestCompletionCallback callback;
16341 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16342 EXPECT_EQ(ERR_IO_PENDING, rv);
16343
16344 EXPECT_EQ(0, throttler->num_set_priority_calls());
16345 trans->SetPriority(LOW);
16346 EXPECT_EQ(1, throttler->num_set_priority_calls());
16347 EXPECT_EQ(LOW, throttler->last_priority_set());
16348
16349 throttler->UnthrottleAllRequests();
16350 base::RunLoop().RunUntilIdle();
16351 ASSERT_TRUE(callback.have_result());
16352 EXPECT_EQ(OK, callback.WaitForResult());
16353}
16354
16355// Confirm that unthrottling from a SetPriority call by the
16356// throttler works properly.
16357TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16358 TestNetworkStreamThrottler* throttler(nullptr);
16359 std::unique_ptr<HttpNetworkSession> session(
16360 CreateSessionWithThrottler(&session_deps_, &throttler));
16361
16362 // Send a simple request and make sure it goes through.
16363 HttpRequestInfo request;
16364 request.method = "GET";
16365 request.url = GURL("http://www.example.org/");
16366
16367 MockWrite data_writes[] = {
16368 MockWrite("GET / HTTP/1.1\r\n"
16369 "Host: www.example.org\r\n"
16370 "Connection: keep-alive\r\n\r\n"),
16371 };
16372 MockRead data_reads[] = {
16373 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16374 MockRead(SYNCHRONOUS, OK),
16375 };
16376 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16377 arraysize(data_writes));
16378 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16379
16380 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16381 data_writes, arraysize(data_writes));
16382 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16383
16384 // Start a request that will be throttled at start; confirm it
16385 // doesn't complete.
16386 throttler->set_throttle_new_requests(true);
16387 std::unique_ptr<HttpTransaction> trans(
16388 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16389
16390 TestCompletionCallback callback;
16391 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16392 EXPECT_EQ(ERR_IO_PENDING, rv);
16393
16394 base::RunLoop().RunUntilIdle();
16395 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16396 EXPECT_FALSE(callback.have_result());
16397
16398 // Create a new request, call SetPriority on it to unthrottle,
16399 // and make sure that allows the original request to complete.
16400 std::unique_ptr<HttpTransaction> trans1(
16401 new HttpNetworkTransaction(LOW, session.get()));
16402 throttler->set_priority_change_closure(
16403 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
16404 base::Unretained(throttler)));
16405
16406 // Start the transaction to associate a throttle with it.
16407 TestCompletionCallback callback1;
16408 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
16409 EXPECT_EQ(ERR_IO_PENDING, rv);
16410
16411 trans1->SetPriority(IDLE);
16412
16413 base::RunLoop().RunUntilIdle();
16414 ASSERT_TRUE(callback.have_result());
16415 EXPECT_EQ(OK, callback.WaitForResult());
16416 ASSERT_TRUE(callback1.have_result());
16417 EXPECT_EQ(OK, callback1.WaitForResult());
16418}
16419
16420// Transaction will be destroyed when the unique_ptr goes out of scope.
16421void DestroyTransaction(std::unique_ptr<HttpTransaction> transaction) {}
16422
16423// Confirm that destroying a transaction from a SetPriority call by the
16424// throttler works properly.
16425TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
16426 TestNetworkStreamThrottler* throttler(nullptr);
16427 std::unique_ptr<HttpNetworkSession> session(
16428 CreateSessionWithThrottler(&session_deps_, &throttler));
16429
16430 // Send a simple request and make sure it goes through.
16431 HttpRequestInfo request;
16432 request.method = "GET";
16433 request.url = GURL("http://www.example.org/");
16434
16435 MockWrite data_writes[] = {
16436 MockWrite("GET / HTTP/1.1\r\n"
16437 "Host: www.example.org\r\n"
16438 "Connection: keep-alive\r\n\r\n"),
16439 };
16440 MockRead data_reads[] = {
16441 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16442 MockRead(SYNCHRONOUS, OK),
16443 };
16444 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16445 arraysize(data_writes));
16446 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16447
16448 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16449 data_writes, arraysize(data_writes));
16450 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16451
16452 // Start a request that will be throttled at start; confirm it
16453 // doesn't complete.
16454 throttler->set_throttle_new_requests(true);
16455 std::unique_ptr<HttpTransaction> trans(
16456 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16457
16458 TestCompletionCallback callback;
16459 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16460 EXPECT_EQ(ERR_IO_PENDING, rv);
16461
16462 base::RunLoop().RunUntilIdle();
16463 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16464 EXPECT_FALSE(callback.have_result());
16465
16466 // Arrange for the set priority call on the above transaction to delete
16467 // the transaction.
16468 HttpTransaction* trans_ptr(trans.get());
16469 throttler->set_priority_change_closure(
16470 base::Bind(&DestroyTransaction, base::Passed(&trans)));
16471
16472 // Call it and check results (partially a "doesn't crash" test).
16473 trans_ptr->SetPriority(IDLE);
16474 trans_ptr = nullptr; // No longer a valid pointer.
16475
16476 base::RunLoop().RunUntilIdle();
16477 ASSERT_FALSE(callback.have_result());
16478}
16479
nharperb7441ef2016-01-25 23:54:1416480#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0116481TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1416482 const std::string https_url = "https://www.example.com";
16483 HttpRequestInfo request;
16484 request.url = GURL(https_url);
16485 request.method = "GET";
16486
16487 SSLSocketDataProvider ssl(ASYNC, OK);
16488 ssl.token_binding_negotiated = true;
16489 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3616490 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1416491 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16492
bnc42331402016-07-25 13:36:1516493 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4116494 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
16495 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1416496 MockRead(ASYNC, ERR_IO_PENDING)};
16497 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16498 session_deps_.socket_factory->AddSocketDataProvider(&data);
16499 session_deps_.channel_id_service.reset(new ChannelIDService(
16500 new DefaultChannelIDStore(nullptr), base::ThreadTaskRunnerHandle::Get()));
danakj1fd259a02016-04-16 03:17:0916501 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416502
16503 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16504 TestCompletionCallback callback;
16505 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016506 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516507 base::RunLoop().RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416508
16509 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16510 HttpRequestHeaders headers;
16511 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16512 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16513}
16514#endif // !defined(OS_IOS)
16515
[email protected]89ceba9a2009-03-21 03:46:0616516} // namespace net