blob: d691aaf616da070e896d23d8f5977e688842c2f5 [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
850 std::unique_ptr<HttpTransaction> trans(
851 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
852
853 HttpRequestInfo request;
854 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
873 std::unique_ptr<HttpTransaction> trans(
874 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
875
876 HttpRequestInfo request;
877 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),
4795 CreateMockRead(body_authentication, 2),
4796 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),
5258 CreateMockRead(wrapped_body1, 4, ASYNC),
5259 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
5260 CreateMockRead(wrapped_body2, 7, ASYNC),
5261 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
tbansal28e68f82016-02-04 02:56:158160 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[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));
[email protected]7c6f7ba2012-04-03 04:09:298166
8167 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418168 CreateMockWrite(stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298169 };
8170
bncdf80d44fd2016-07-15 20:27:418171 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158172 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298173
bncdf80d44fd2016-07-15 20:27:418174 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298175
bncdf80d44fd2016-07-15 20:27:418176 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558177 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438178 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418179 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8180 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298181
8182 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418183 CreateMockRead(stream1_reply, 1, ASYNC),
8184 CreateMockRead(stream2_syn, 2, ASYNC),
8185 CreateMockRead(stream1_body, 3, ASYNC),
8186 CreateMockRead(stream2_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598187 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298188 };
8189
rch8e6c6c42015-05-01 14:05:138190 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8191 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078192 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298193 // Negotiate SPDY to the proxy
8194 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368195 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078196 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298197
bnc691fda62016-08-12 00:43:168198 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508199 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:298200 TestCompletionCallback callback;
8201 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018202 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298203
8204 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018205 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298206 const HttpResponseInfo* response = trans->GetResponseInfo();
8207
bnc691fda62016-08-12 00:43:168208 std::unique_ptr<HttpNetworkTransaction> push_trans(
[email protected]90499482013-06-01 00:39:508209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8210 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018211 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298212
8213 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018214 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298215 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8216
wezca1070932016-05-26 20:30:528217 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298218 EXPECT_TRUE(response->headers->IsKeepAlive());
8219
8220 EXPECT_EQ(200, response->headers->response_code());
8221 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8222
8223 std::string response_data;
8224 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018225 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298226 EXPECT_EQ("hello!", response_data);
8227
[email protected]029c83b62013-01-24 05:28:208228 LoadTimingInfo load_timing_info;
8229 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8230 TestLoadTimingNotReusedWithPac(load_timing_info,
8231 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8232
[email protected]7c6f7ba2012-04-03 04:09:298233 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528234 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298235 EXPECT_EQ(200, push_response->headers->response_code());
8236
8237 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018238 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298239 EXPECT_EQ("pushed", response_data);
8240
[email protected]029c83b62013-01-24 05:28:208241 LoadTimingInfo push_load_timing_info;
8242 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8243 TestLoadTimingReusedWithPac(push_load_timing_info);
8244 // The transactions should share a socket ID, despite being for different
8245 // origins.
8246 EXPECT_EQ(load_timing_info.socket_log_id,
8247 push_load_timing_info.socket_log_id);
8248
[email protected]7c6f7ba2012-04-03 04:09:298249 trans.reset();
8250 push_trans.reset();
8251 session->CloseAllConnections();
8252}
8253
[email protected]8c843192012-04-05 07:15:008254// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018255TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158256 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098257 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158258 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8259 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008260 HttpRequestInfo request;
8261
8262 request.method = "GET";
bncce36dca22015-04-21 22:11:238263 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008264
tbansal28e68f82016-02-04 02:56:158265 session_deps_.proxy_service =
8266 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518267 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078268 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508269
8270 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:158271 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:508272
danakj1fd259a02016-04-16 03:17:098273 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008274
bncdf80d44fd2016-07-15 20:27:418275 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458276 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008277
bncdf80d44fd2016-07-15 20:27:418278 SpdySerializedFrame push_rst(
[email protected]c10b20852013-05-15 21:29:208279 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008280
8281 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418282 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008283 };
8284
bncdf80d44fd2016-07-15 20:27:418285 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158286 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008287
bncdf80d44fd2016-07-15 20:27:418288 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008289
bncdf80d44fd2016-07-15 20:27:418290 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558291 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008292
8293 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418294 CreateMockRead(stream1_reply, 1, ASYNC),
8295 CreateMockRead(stream2_syn, 2, ASYNC),
8296 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598297 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008298 };
8299
rch8e6c6c42015-05-01 14:05:138300 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8301 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078302 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008303 // Negotiate SPDY to the proxy
8304 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368305 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078306 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008307
bnc691fda62016-08-12 00:43:168308 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:508309 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:008310 TestCompletionCallback callback;
8311 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018312 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008313
8314 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018315 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008316 const HttpResponseInfo* response = trans->GetResponseInfo();
8317
wezca1070932016-05-26 20:30:528318 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008319 EXPECT_TRUE(response->headers->IsKeepAlive());
8320
8321 EXPECT_EQ(200, response->headers->response_code());
8322 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8323
8324 std::string response_data;
8325 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018326 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008327 EXPECT_EQ("hello!", response_data);
8328
8329 trans.reset();
8330 session->CloseAllConnections();
8331}
8332
tbansal8ef1d3e2016-02-03 04:05:428333// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8334// resources.
bncd16676a2016-07-20 16:23:018335TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158336 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098337 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158338 proxy_delegate->set_trusted_spdy_proxy(
8339 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8340
tbansal8ef1d3e2016-02-03 04:05:428341 HttpRequestInfo request;
8342
8343 request.method = "GET";
8344 request.url = GURL("http://www.example.org/");
8345
8346 // Configure against https proxy server "myproxy:70".
8347 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8348 BoundTestNetLog log;
8349 session_deps_.net_log = log.bound().net_log();
8350
8351 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:158352 session_deps_.proxy_delegate.reset(proxy_delegate.release());
tbansal8ef1d3e2016-02-03 04:05:428353
danakj1fd259a02016-04-16 03:17:098354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428355
bncdf80d44fd2016-07-15 20:27:418356 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458357 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tbansal8ef1d3e2016-02-03 04:05:428358
8359 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418360 CreateMockWrite(stream1_syn, 0, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428361 };
8362
bncdf80d44fd2016-07-15 20:27:418363 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158364 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428365
bncdf80d44fd2016-07-15 20:27:418366 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:498367 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
8368
bncdf80d44fd2016-07-15 20:27:418369 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428370
bncdf80d44fd2016-07-15 20:27:418371 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158372 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428373
bncdf80d44fd2016-07-15 20:27:418374 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428375
8376 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418377 CreateMockRead(stream1_reply, 1, ASYNC),
8378 CreateMockRead(stream2_syn, 2, ASYNC),
8379 CreateMockRead(stream1_body, 3, ASYNC),
8380 CreateMockRead(stream2_body, 4, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428381 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
8382 };
8383
8384 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8385 arraysize(spdy_writes));
8386 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8387 // Negotiate SPDY to the proxy
8388 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368389 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428390 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8391
bnc691fda62016-08-12 00:43:168392 std::unique_ptr<HttpNetworkTransaction> trans(
tbansal8ef1d3e2016-02-03 04:05:428393 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8394 TestCompletionCallback callback;
8395 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018396 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428397
8398 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018399 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428400 const HttpResponseInfo* response = trans->GetResponseInfo();
8401
wezca1070932016-05-26 20:30:528402 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428403 EXPECT_TRUE(response->headers->IsKeepAlive());
8404
8405 EXPECT_EQ(200, response->headers->response_code());
8406 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8407
8408 std::string response_data;
8409 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018410 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428411 EXPECT_EQ("hello!", response_data);
8412
8413 trans.reset();
8414 session->CloseAllConnections();
8415}
8416
[email protected]2df19bb2010-08-25 20:13:468417// Test HTTPS connections to a site with a bad certificate, going through an
8418// HTTPS proxy
bncd16676a2016-07-20 16:23:018419TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038420 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468421
8422 HttpRequestInfo request;
8423 request.method = "GET";
bncce36dca22015-04-21 22:11:238424 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468425
8426 // Attempt to fetch the URL from a server with a bad cert
8427 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178428 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8429 "Host: www.example.org:443\r\n"
8430 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468431 };
8432
8433 MockRead bad_cert_reads[] = {
8434 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068435 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468436 };
8437
8438 // Attempt to fetch the URL with a good cert
8439 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178440 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8441 "Host: www.example.org:443\r\n"
8442 "Proxy-Connection: keep-alive\r\n\r\n"),
8443 MockWrite("GET / HTTP/1.1\r\n"
8444 "Host: www.example.org\r\n"
8445 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468446 };
8447
8448 MockRead good_cert_reads[] = {
8449 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8450 MockRead("HTTP/1.0 200 OK\r\n"),
8451 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8452 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068453 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468454 };
8455
8456 StaticSocketDataProvider ssl_bad_certificate(
8457 bad_cert_reads, arraysize(bad_cert_reads),
8458 bad_cert_writes, arraysize(bad_cert_writes));
8459 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8460 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068461 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8462 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468463
8464 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078465 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8466 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8467 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468468
8469 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078470 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8471 session_deps_.socket_factory->AddSocketDataProvider(&data);
8472 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468473
[email protected]49639fa2011-12-20 23:22:418474 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468475
danakj1fd259a02016-04-16 03:17:098476 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168477 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468478
tfarina42834112016-09-22 13:38:208479 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468481
8482 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018483 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468484
bnc691fda62016-08-12 00:43:168485 rv = trans.RestartIgnoringLastError(callback.callback());
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, IsOk());
[email protected]2df19bb2010-08-25 20:13:468490
bnc691fda62016-08-12 00:43:168491 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468492
wezca1070932016-05-26 20:30:528493 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468494 EXPECT_EQ(100, response->headers->GetContentLength());
8495}
8496
bncd16676a2016-07-20 16:23:018497TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428498 HttpRequestInfo request;
8499 request.method = "GET";
bncce36dca22015-04-21 22:11:238500 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438501 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8502 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428503
danakj1fd259a02016-04-16 03:17:098504 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168505 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278506
[email protected]1c773ea12009-04-28 19:58:428507 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238508 MockWrite(
8509 "GET / HTTP/1.1\r\n"
8510 "Host: www.example.org\r\n"
8511 "Connection: keep-alive\r\n"
8512 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428513 };
8514
8515 // Lastly, the server responds with the actual content.
8516 MockRead data_reads[] = {
8517 MockRead("HTTP/1.0 200 OK\r\n"),
8518 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8519 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068520 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428521 };
8522
[email protected]31a2bfe2010-02-09 08:03:398523 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8524 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078525 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428526
[email protected]49639fa2011-12-20 23:22:418527 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428528
tfarina42834112016-09-22 13:38:208529 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018530 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428531
8532 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018533 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428534}
8535
bncd16676a2016-07-20 16:23:018536TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298537 HttpRequestInfo request;
8538 request.method = "GET";
bncce36dca22015-04-21 22:11:238539 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298540 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8541 "Chromium Ultra Awesome X Edition");
8542
rdsmith82957ad2015-09-16 19:42:038543 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098544 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168545 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278546
[email protected]da81f132010-08-18 23:39:298547 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178548 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8549 "Host: www.example.org:443\r\n"
8550 "Proxy-Connection: keep-alive\r\n"
8551 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298552 };
8553 MockRead data_reads[] = {
8554 // Return an error, so the transaction stops here (this test isn't
8555 // interested in the rest).
8556 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8557 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8558 MockRead("Proxy-Connection: close\r\n\r\n"),
8559 };
8560
8561 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8562 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078563 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298564
[email protected]49639fa2011-12-20 23:22:418565 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298566
tfarina42834112016-09-22 13:38:208567 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018568 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298569
8570 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018571 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298572}
8573
bncd16676a2016-07-20 16:23:018574TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428575 HttpRequestInfo request;
8576 request.method = "GET";
bncce36dca22015-04-21 22:11:238577 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168578 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8579 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428580
danakj1fd259a02016-04-16 03:17:098581 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168582 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278583
[email protected]1c773ea12009-04-28 19:58:428584 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238585 MockWrite(
8586 "GET / HTTP/1.1\r\n"
8587 "Host: www.example.org\r\n"
8588 "Connection: keep-alive\r\n"
8589 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428590 };
8591
8592 // Lastly, the server responds with the actual content.
8593 MockRead data_reads[] = {
8594 MockRead("HTTP/1.0 200 OK\r\n"),
8595 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8596 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068597 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428598 };
8599
[email protected]31a2bfe2010-02-09 08:03:398600 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8601 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078602 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428603
[email protected]49639fa2011-12-20 23:22:418604 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428605
tfarina42834112016-09-22 13:38:208606 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018607 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428608
8609 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018610 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428611}
8612
bncd16676a2016-07-20 16:23:018613TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428614 HttpRequestInfo request;
8615 request.method = "POST";
bncce36dca22015-04-21 22:11:238616 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428617
danakj1fd259a02016-04-16 03:17:098618 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168619 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278620
[email protected]1c773ea12009-04-28 19:58:428621 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238622 MockWrite(
8623 "POST / HTTP/1.1\r\n"
8624 "Host: www.example.org\r\n"
8625 "Connection: keep-alive\r\n"
8626 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428627 };
8628
8629 // Lastly, the server responds with the actual content.
8630 MockRead data_reads[] = {
8631 MockRead("HTTP/1.0 200 OK\r\n"),
8632 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8633 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068634 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428635 };
8636
[email protected]31a2bfe2010-02-09 08:03:398637 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8638 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078639 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428640
[email protected]49639fa2011-12-20 23:22:418641 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428642
tfarina42834112016-09-22 13:38:208643 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018644 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428645
8646 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018647 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428648}
8649
bncd16676a2016-07-20 16:23:018650TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428651 HttpRequestInfo request;
8652 request.method = "PUT";
bncce36dca22015-04-21 22:11:238653 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428654
danakj1fd259a02016-04-16 03:17:098655 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168656 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278657
[email protected]1c773ea12009-04-28 19:58:428658 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238659 MockWrite(
8660 "PUT / HTTP/1.1\r\n"
8661 "Host: www.example.org\r\n"
8662 "Connection: keep-alive\r\n"
8663 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428664 };
8665
8666 // Lastly, the server responds with the actual content.
8667 MockRead data_reads[] = {
8668 MockRead("HTTP/1.0 200 OK\r\n"),
8669 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8670 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068671 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428672 };
8673
[email protected]31a2bfe2010-02-09 08:03:398674 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8675 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078676 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428677
[email protected]49639fa2011-12-20 23:22:418678 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428679
tfarina42834112016-09-22 13:38:208680 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018681 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428682
8683 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018684 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428685}
8686
bncd16676a2016-07-20 16:23:018687TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428688 HttpRequestInfo request;
8689 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238690 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428691
danakj1fd259a02016-04-16 03:17:098692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278694
[email protected]1c773ea12009-04-28 19:58:428695 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138696 MockWrite("HEAD / HTTP/1.1\r\n"
8697 "Host: www.example.org\r\n"
8698 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428699 };
8700
8701 // Lastly, the server responds with the actual content.
8702 MockRead data_reads[] = {
8703 MockRead("HTTP/1.0 200 OK\r\n"),
8704 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8705 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068706 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428707 };
8708
[email protected]31a2bfe2010-02-09 08:03:398709 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8710 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078711 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428712
[email protected]49639fa2011-12-20 23:22:418713 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428714
tfarina42834112016-09-22 13:38:208715 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428717
8718 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018719 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428720}
8721
bncd16676a2016-07-20 16:23:018722TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428723 HttpRequestInfo request;
8724 request.method = "GET";
bncce36dca22015-04-21 22:11:238725 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428726 request.load_flags = LOAD_BYPASS_CACHE;
8727
danakj1fd259a02016-04-16 03:17:098728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278730
[email protected]1c773ea12009-04-28 19:58:428731 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238732 MockWrite(
8733 "GET / HTTP/1.1\r\n"
8734 "Host: www.example.org\r\n"
8735 "Connection: keep-alive\r\n"
8736 "Pragma: no-cache\r\n"
8737 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428738 };
8739
8740 // Lastly, the server responds with the actual content.
8741 MockRead data_reads[] = {
8742 MockRead("HTTP/1.0 200 OK\r\n"),
8743 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8744 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068745 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428746 };
8747
[email protected]31a2bfe2010-02-09 08:03:398748 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8749 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078750 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428751
[email protected]49639fa2011-12-20 23:22:418752 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428753
tfarina42834112016-09-22 13:38:208754 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018755 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428756
8757 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018758 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428759}
8760
bncd16676a2016-07-20 16:23:018761TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428762 HttpRequestInfo request;
8763 request.method = "GET";
bncce36dca22015-04-21 22:11:238764 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428765 request.load_flags = LOAD_VALIDATE_CACHE;
8766
danakj1fd259a02016-04-16 03:17:098767 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168768 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278769
[email protected]1c773ea12009-04-28 19:58:428770 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238771 MockWrite(
8772 "GET / HTTP/1.1\r\n"
8773 "Host: www.example.org\r\n"
8774 "Connection: keep-alive\r\n"
8775 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428776 };
8777
8778 // Lastly, the server responds with the actual content.
8779 MockRead data_reads[] = {
8780 MockRead("HTTP/1.0 200 OK\r\n"),
8781 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8782 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068783 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428784 };
8785
[email protected]31a2bfe2010-02-09 08:03:398786 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8787 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078788 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428789
[email protected]49639fa2011-12-20 23:22:418790 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428791
tfarina42834112016-09-22 13:38:208792 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428794
8795 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018796 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428797}
8798
bncd16676a2016-07-20 16:23:018799TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428800 HttpRequestInfo request;
8801 request.method = "GET";
bncce36dca22015-04-21 22:11:238802 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438803 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428804
danakj1fd259a02016-04-16 03:17:098805 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168806 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278807
[email protected]1c773ea12009-04-28 19:58:428808 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238809 MockWrite(
8810 "GET / HTTP/1.1\r\n"
8811 "Host: www.example.org\r\n"
8812 "Connection: keep-alive\r\n"
8813 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428814 };
8815
8816 // Lastly, the server responds with the actual content.
8817 MockRead data_reads[] = {
8818 MockRead("HTTP/1.0 200 OK\r\n"),
8819 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8820 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068821 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428822 };
8823
[email protected]31a2bfe2010-02-09 08:03:398824 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8825 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078826 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428827
[email protected]49639fa2011-12-20 23:22:418828 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428829
tfarina42834112016-09-22 13:38:208830 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018831 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428832
8833 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018834 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428835}
8836
bncd16676a2016-07-20 16:23:018837TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478838 HttpRequestInfo request;
8839 request.method = "GET";
bncce36dca22015-04-21 22:11:238840 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438841 request.extra_headers.SetHeader("referer", "www.foo.com");
8842 request.extra_headers.SetHeader("hEllo", "Kitty");
8843 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478844
danakj1fd259a02016-04-16 03:17:098845 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168846 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278847
[email protected]270c6412010-03-29 22:02:478848 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238849 MockWrite(
8850 "GET / HTTP/1.1\r\n"
8851 "Host: www.example.org\r\n"
8852 "Connection: keep-alive\r\n"
8853 "referer: www.foo.com\r\n"
8854 "hEllo: Kitty\r\n"
8855 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478856 };
8857
8858 // Lastly, the server responds with the actual content.
8859 MockRead data_reads[] = {
8860 MockRead("HTTP/1.0 200 OK\r\n"),
8861 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8862 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068863 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478864 };
8865
8866 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8867 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078868 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478869
[email protected]49639fa2011-12-20 23:22:418870 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478871
tfarina42834112016-09-22 13:38:208872 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018873 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:478874
8875 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018876 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:478877}
8878
bncd16676a2016-07-20 16:23:018879TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278880 HttpRequestInfo request;
8881 request.method = "GET";
bncce36dca22015-04-21 22:11:238882 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278883
rdsmith82957ad2015-09-16 19:42:038884 session_deps_.proxy_service =
8885 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518886 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078887 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028888
danakj1fd259a02016-04-16 03:17:098889 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168890 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028891
[email protected]3cd17242009-06-23 02:59:028892 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8893 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8894
8895 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238896 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8897 MockWrite(
8898 "GET / HTTP/1.1\r\n"
8899 "Host: www.example.org\r\n"
8900 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028901
8902 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068903 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028904 MockRead("HTTP/1.0 200 OK\r\n"),
8905 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8906 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068907 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028908 };
8909
[email protected]31a2bfe2010-02-09 08:03:398910 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8911 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078912 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028913
[email protected]49639fa2011-12-20 23:22:418914 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028915
tfarina42834112016-09-22 13:38:208916 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018917 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:028918
8919 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018920 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028921
bnc691fda62016-08-12 00:43:168922 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528923 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028924
tbansal2ecbbc72016-10-06 17:15:478925 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:208926 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168927 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208928 TestLoadTimingNotReusedWithPac(load_timing_info,
8929 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8930
[email protected]3cd17242009-06-23 02:59:028931 std::string response_text;
bnc691fda62016-08-12 00:43:168932 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018933 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:028934 EXPECT_EQ("Payload", response_text);
8935}
8936
bncd16676a2016-07-20 16:23:018937TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278938 HttpRequestInfo request;
8939 request.method = "GET";
bncce36dca22015-04-21 22:11:238940 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278941
rdsmith82957ad2015-09-16 19:42:038942 session_deps_.proxy_service =
8943 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518944 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078945 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028946
danakj1fd259a02016-04-16 03:17:098947 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168948 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:028949
[email protected]3cd17242009-06-23 02:59:028950 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8951 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8952
8953 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238954 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8955 arraysize(write_buffer)),
8956 MockWrite(
8957 "GET / HTTP/1.1\r\n"
8958 "Host: www.example.org\r\n"
8959 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028960
8961 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018962 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8963 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358964 MockRead("HTTP/1.0 200 OK\r\n"),
8965 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8966 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068967 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358968 };
8969
[email protected]31a2bfe2010-02-09 08:03:398970 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8971 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078972 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358973
[email protected]8ddf8322012-02-23 18:08:068974 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078975 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358976
[email protected]49639fa2011-12-20 23:22:418977 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358978
tfarina42834112016-09-22 13:38:208979 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018980 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:358981
8982 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018983 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:358984
[email protected]029c83b62013-01-24 05:28:208985 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168986 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208987 TestLoadTimingNotReusedWithPac(load_timing_info,
8988 CONNECT_TIMING_HAS_SSL_TIMES);
8989
bnc691fda62016-08-12 00:43:168990 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528991 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:478992 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:358993
8994 std::string response_text;
bnc691fda62016-08-12 00:43:168995 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:018996 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:358997 EXPECT_EQ("Payload", response_text);
8998}
8999
bncd16676a2016-07-20 16:23:019000TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209001 HttpRequestInfo request;
9002 request.method = "GET";
bncce36dca22015-04-21 22:11:239003 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209004
rdsmith82957ad2015-09-16 19:42:039005 session_deps_.proxy_service =
9006 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519007 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079008 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209009
danakj1fd259a02016-04-16 03:17:099010 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169011 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209012
9013 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9014 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9015
9016 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239017 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9018 MockWrite(
9019 "GET / HTTP/1.1\r\n"
9020 "Host: www.example.org\r\n"
9021 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209022
9023 MockRead data_reads[] = {
9024 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9025 MockRead("HTTP/1.0 200 OK\r\n"),
9026 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9027 MockRead("Payload"),
9028 MockRead(SYNCHRONOUS, OK)
9029 };
9030
9031 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9032 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079033 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209034
9035 TestCompletionCallback callback;
9036
tfarina42834112016-09-22 13:38:209037 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019038 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209039
9040 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019041 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209042
bnc691fda62016-08-12 00:43:169043 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529044 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209045
9046 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169047 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209048 TestLoadTimingNotReused(load_timing_info,
9049 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9050
9051 std::string response_text;
bnc691fda62016-08-12 00:43:169052 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019053 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209054 EXPECT_EQ("Payload", response_text);
9055}
9056
bncd16676a2016-07-20 16:23:019057TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279058 HttpRequestInfo request;
9059 request.method = "GET";
bncce36dca22015-04-21 22:11:239060 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279061
rdsmith82957ad2015-09-16 19:42:039062 session_deps_.proxy_service =
9063 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519064 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079065 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359066
danakj1fd259a02016-04-16 03:17:099067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169068 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359069
[email protected]e0c27be2009-07-15 13:09:359070 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9071 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379072 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239073 0x05, // Version
9074 0x01, // Command (CONNECT)
9075 0x00, // Reserved.
9076 0x03, // Address type (DOMAINNAME).
9077 0x0F, // Length of domain (15)
9078 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9079 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379080 };
[email protected]e0c27be2009-07-15 13:09:359081 const char kSOCKS5OkResponse[] =
9082 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9083
9084 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239085 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9086 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9087 MockWrite(
9088 "GET / HTTP/1.1\r\n"
9089 "Host: www.example.org\r\n"
9090 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359091
9092 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019093 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9094 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359095 MockRead("HTTP/1.0 200 OK\r\n"),
9096 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9097 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069098 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359099 };
9100
[email protected]31a2bfe2010-02-09 08:03:399101 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9102 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079103 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359104
[email protected]49639fa2011-12-20 23:22:419105 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359106
tfarina42834112016-09-22 13:38:209107 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019108 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359109
9110 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019111 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359112
bnc691fda62016-08-12 00:43:169113 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529114 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479115 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359116
[email protected]029c83b62013-01-24 05:28:209117 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169118 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209119 TestLoadTimingNotReusedWithPac(load_timing_info,
9120 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9121
[email protected]e0c27be2009-07-15 13:09:359122 std::string response_text;
bnc691fda62016-08-12 00:43:169123 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019124 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359125 EXPECT_EQ("Payload", response_text);
9126}
9127
bncd16676a2016-07-20 16:23:019128TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279129 HttpRequestInfo request;
9130 request.method = "GET";
bncce36dca22015-04-21 22:11:239131 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279132
rdsmith82957ad2015-09-16 19:42:039133 session_deps_.proxy_service =
9134 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519135 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079136 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359137
danakj1fd259a02016-04-16 03:17:099138 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169139 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359140
[email protected]e0c27be2009-07-15 13:09:359141 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9142 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379143 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239144 0x05, // Version
9145 0x01, // Command (CONNECT)
9146 0x00, // Reserved.
9147 0x03, // Address type (DOMAINNAME).
9148 0x0F, // Length of domain (15)
9149 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9150 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379151 };
9152
[email protected]e0c27be2009-07-15 13:09:359153 const char kSOCKS5OkResponse[] =
9154 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9155
9156 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239157 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9158 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9159 arraysize(kSOCKS5OkRequest)),
9160 MockWrite(
9161 "GET / HTTP/1.1\r\n"
9162 "Host: www.example.org\r\n"
9163 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359164
9165 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019166 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9167 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029168 MockRead("HTTP/1.0 200 OK\r\n"),
9169 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9170 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069171 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029172 };
9173
[email protected]31a2bfe2010-02-09 08:03:399174 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9175 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079176 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029177
[email protected]8ddf8322012-02-23 18:08:069178 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079179 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029180
[email protected]49639fa2011-12-20 23:22:419181 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029182
tfarina42834112016-09-22 13:38:209183 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019184 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029185
9186 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019187 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029188
bnc691fda62016-08-12 00:43:169189 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529190 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479191 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029192
[email protected]029c83b62013-01-24 05:28:209193 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169194 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209195 TestLoadTimingNotReusedWithPac(load_timing_info,
9196 CONNECT_TIMING_HAS_SSL_TIMES);
9197
[email protected]3cd17242009-06-23 02:59:029198 std::string response_text;
bnc691fda62016-08-12 00:43:169199 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019200 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029201 EXPECT_EQ("Payload", response_text);
9202}
9203
[email protected]448d4ca52012-03-04 04:12:239204namespace {
9205
[email protected]04e5be32009-06-26 20:00:319206// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069207
9208struct GroupNameTest {
9209 std::string proxy_server;
9210 std::string url;
9211 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189212 bool ssl;
[email protected]2d731a32010-04-29 01:04:069213};
9214
danakj1fd259a02016-04-16 03:17:099215std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079216 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099217 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069218
bnc525e175a2016-06-20 12:36:409219 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539220 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219221 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129222 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229223 http_server_properties->SetAlternativeService(
bncaa60ff402016-06-22 19:12:429224 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469225 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069226
9227 return session;
9228}
9229
mmenkee65e7af2015-10-13 17:16:429230int GroupNameTransactionHelper(const std::string& url,
9231 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069232 HttpRequestInfo request;
9233 request.method = "GET";
9234 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069235
bnc691fda62016-08-12 00:43:169236 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279237
[email protected]49639fa2011-12-20 23:22:419238 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069239
9240 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209241 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069242}
9243
[email protected]448d4ca52012-03-04 04:12:239244} // namespace
9245
bncd16676a2016-07-20 16:23:019246TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069247 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239248 {
9249 "", // unused
9250 "http://www.example.org/direct",
9251 "www.example.org:80",
9252 false,
9253 },
9254 {
9255 "", // unused
9256 "http://[2001:1418:13:1::25]/direct",
9257 "[2001:1418:13:1::25]:80",
9258 false,
9259 },
[email protected]04e5be32009-06-26 20:00:319260
bncce36dca22015-04-21 22:11:239261 // SSL Tests
9262 {
9263 "", // unused
9264 "https://www.example.org/direct_ssl",
9265 "ssl/www.example.org:443",
9266 true,
9267 },
9268 {
9269 "", // unused
9270 "https://[2001:1418:13:1::25]/direct",
9271 "ssl/[2001:1418:13:1::25]:443",
9272 true,
9273 },
9274 {
9275 "", // unused
bncaa60ff402016-06-22 19:12:429276 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239277 "ssl/host.with.alternate:443",
9278 true,
9279 },
[email protected]2d731a32010-04-29 01:04:069280 };
[email protected]2ff8b312010-04-26 22:20:549281
viettrungluue4a8b882014-10-16 06:17:389282 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039283 session_deps_.proxy_service =
9284 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099285 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409286 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069287
mmenkee65e7af2015-10-13 17:16:429288 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289289 CaptureGroupNameTransportSocketPool* transport_conn_pool =
9290 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139291 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349292 new CaptureGroupNameSSLSocketPool(NULL, NULL);
danakj1fd259a02016-04-16 03:17:099293 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449294 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029295 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9296 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489297 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069298
9299 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429300 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189301 if (tests[i].ssl)
9302 EXPECT_EQ(tests[i].expected_group_name,
9303 ssl_conn_pool->last_group_name_received());
9304 else
9305 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289306 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069307 }
[email protected]2d731a32010-04-29 01:04:069308}
9309
bncd16676a2016-07-20 16:23:019310TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069311 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239312 {
9313 "http_proxy",
9314 "http://www.example.org/http_proxy_normal",
9315 "www.example.org:80",
9316 false,
9317 },
[email protected]2d731a32010-04-29 01:04:069318
bncce36dca22015-04-21 22:11:239319 // SSL Tests
9320 {
9321 "http_proxy",
9322 "https://www.example.org/http_connect_ssl",
9323 "ssl/www.example.org:443",
9324 true,
9325 },
[email protected]af3490e2010-10-16 21:02:299326
bncce36dca22015-04-21 22:11:239327 {
9328 "http_proxy",
bncaa60ff402016-06-22 19:12:429329 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239330 "ssl/host.with.alternate:443",
9331 true,
9332 },
[email protected]45499252013-01-23 17:12:569333
bncce36dca22015-04-21 22:11:239334 {
9335 "http_proxy",
9336 "ftp://ftp.google.com/http_proxy_normal",
9337 "ftp/ftp.google.com:21",
9338 false,
9339 },
[email protected]2d731a32010-04-29 01:04:069340 };
9341
viettrungluue4a8b882014-10-16 06:17:389342 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039343 session_deps_.proxy_service =
9344 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099345 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409346 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069347
mmenkee65e7af2015-10-13 17:16:429348 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069349
[email protected]e60e47a2010-07-14 03:37:189350 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139351 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349352 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139353 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349354 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029355
danakj1fd259a02016-04-16 03:17:099356 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449357 new MockClientSocketPoolManager);
aviadef3442016-10-03 18:50:399358 mock_pool_manager->SetSocketPoolForHTTPProxy(
9359 proxy_host, base::WrapUnique(http_proxy_pool));
9360 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9361 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489362 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069363
9364 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429365 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189366 if (tests[i].ssl)
9367 EXPECT_EQ(tests[i].expected_group_name,
9368 ssl_conn_pool->last_group_name_received());
9369 else
9370 EXPECT_EQ(tests[i].expected_group_name,
9371 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069372 }
[email protected]2d731a32010-04-29 01:04:069373}
9374
bncd16676a2016-07-20 16:23:019375TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069376 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239377 {
9378 "socks4://socks_proxy:1080",
9379 "http://www.example.org/socks4_direct",
9380 "socks4/www.example.org:80",
9381 false,
9382 },
9383 {
9384 "socks5://socks_proxy:1080",
9385 "http://www.example.org/socks5_direct",
9386 "socks5/www.example.org:80",
9387 false,
9388 },
[email protected]2d731a32010-04-29 01:04:069389
bncce36dca22015-04-21 22:11:239390 // SSL Tests
9391 {
9392 "socks4://socks_proxy:1080",
9393 "https://www.example.org/socks4_ssl",
9394 "socks4/ssl/www.example.org:443",
9395 true,
9396 },
9397 {
9398 "socks5://socks_proxy:1080",
9399 "https://www.example.org/socks5_ssl",
9400 "socks5/ssl/www.example.org:443",
9401 true,
9402 },
[email protected]af3490e2010-10-16 21:02:299403
bncce36dca22015-04-21 22:11:239404 {
9405 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429406 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239407 "socks4/ssl/host.with.alternate:443",
9408 true,
9409 },
[email protected]04e5be32009-06-26 20:00:319410 };
9411
viettrungluue4a8b882014-10-16 06:17:389412 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039413 session_deps_.proxy_service =
9414 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099415 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409416 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029417
mmenkee65e7af2015-10-13 17:16:429418 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319419
[email protected]e60e47a2010-07-14 03:37:189420 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139421 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349422 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139423 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349424 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029425
danakj1fd259a02016-04-16 03:17:099426 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449427 new MockClientSocketPoolManager);
aviadef3442016-10-03 18:50:399428 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9429 proxy_host, base::WrapUnique(socks_conn_pool));
9430 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9431 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489432 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319433
bnc691fda62016-08-12 00:43:169434 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319435
[email protected]2d731a32010-04-29 01:04:069436 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429437 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189438 if (tests[i].ssl)
9439 EXPECT_EQ(tests[i].expected_group_name,
9440 ssl_conn_pool->last_group_name_received());
9441 else
9442 EXPECT_EQ(tests[i].expected_group_name,
9443 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319444 }
9445}
9446
bncd16676a2016-07-20 16:23:019447TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279448 HttpRequestInfo request;
9449 request.method = "GET";
bncce36dca22015-04-21 22:11:239450 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279451
rdsmith82957ad2015-09-16 19:42:039452 session_deps_.proxy_service =
9453 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329454
[email protected]69719062010-01-05 20:09:219455 // This simulates failure resolving all hostnames; that means we will fail
9456 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079457 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329458
danakj1fd259a02016-04-16 03:17:099459 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169460 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259461
[email protected]49639fa2011-12-20 23:22:419462 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259463
tfarina42834112016-09-22 13:38:209464 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019465 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259466
[email protected]9172a982009-06-06 00:30:259467 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019468 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259469}
9470
[email protected]685af592010-05-11 19:31:249471// Base test to make sure that when the load flags for a request specify to
9472// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029473void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079474 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279475 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109476 HttpRequestInfo request_info;
9477 request_info.method = "GET";
9478 request_info.load_flags = load_flags;
9479 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279480
[email protected]a2c2fb92009-07-18 07:31:049481 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:079482 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:329483
danakj1fd259a02016-04-16 03:17:099484 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289486
bncce36dca22015-04-21 22:11:239487 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289488 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299489 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109490 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079491 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239492 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109493 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209494 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019495 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479496 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019497 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289498
9499 // Verify that it was added to host cache, by doing a subsequent async lookup
9500 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109501 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079502 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239503 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109504 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209505 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019506 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289507
bncce36dca22015-04-21 22:11:239508 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289509 // we can tell if the next lookup hit the cache, or the "network".
9510 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239511 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289512
9513 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9514 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069515 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399516 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079517 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289518
[email protected]3b9cca42009-06-16 01:08:289519 // Run the request.
tfarina42834112016-09-22 13:38:209520 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019521 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419522 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289523
9524 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239525 // "www.example.org".
robpercival214763f2016-07-01 23:27:019526 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289527}
9528
[email protected]685af592010-05-11 19:31:249529// There are multiple load flags that should trigger the host cache bypass.
9530// Test each in isolation:
bncd16676a2016-07-20 16:23:019531TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249532 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9533}
9534
bncd16676a2016-07-20 16:23:019535TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249536 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9537}
9538
bncd16676a2016-07-20 16:23:019539TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249540 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9541}
9542
[email protected]0877e3d2009-10-17 22:29:579543// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019544TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579545 HttpRequestInfo request;
9546 request.method = "GET";
9547 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579548
9549 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069550 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579551 };
[email protected]31a2bfe2010-02-09 08:03:399552 StaticSocketDataProvider data(NULL, 0,
9553 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079554 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099555 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579556
[email protected]49639fa2011-12-20 23:22:419557 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579558
bnc691fda62016-08-12 00:43:169559 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579560
tfarina42834112016-09-22 13:38:209561 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019562 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579563
9564 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019565 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599566
9567 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169568 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599569 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579570}
9571
zmo9528c9f42015-08-04 22:12:089572// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019573TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579574 HttpRequestInfo request;
9575 request.method = "GET";
9576 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579577
9578 MockRead data_reads[] = {
9579 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069580 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579581 };
9582
[email protected]31a2bfe2010-02-09 08:03:399583 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079584 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099585 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579586
[email protected]49639fa2011-12-20 23:22:419587 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579588
bnc691fda62016-08-12 00:43:169589 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579590
tfarina42834112016-09-22 13:38:209591 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019592 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579593
9594 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019595 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089596
bnc691fda62016-08-12 00:43:169597 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529598 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089599
wezca1070932016-05-26 20:30:529600 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089601 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9602
9603 std::string response_data;
bnc691fda62016-08-12 00:43:169604 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019605 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089606 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599607
9608 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169609 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599610 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579611}
9612
9613// Make sure that a dropped connection while draining the body for auth
9614// restart does the right thing.
bncd16676a2016-07-20 16:23:019615TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579616 HttpRequestInfo request;
9617 request.method = "GET";
bncce36dca22015-04-21 22:11:239618 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579619
9620 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239621 MockWrite(
9622 "GET / HTTP/1.1\r\n"
9623 "Host: www.example.org\r\n"
9624 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579625 };
9626
9627 MockRead data_reads1[] = {
9628 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9629 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9630 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9631 MockRead("Content-Length: 14\r\n\r\n"),
9632 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069633 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579634 };
9635
[email protected]31a2bfe2010-02-09 08:03:399636 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9637 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079638 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579639
bnc691fda62016-08-12 00:43:169640 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579641 // be issuing -- the final header line contains the credentials.
9642 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239643 MockWrite(
9644 "GET / HTTP/1.1\r\n"
9645 "Host: www.example.org\r\n"
9646 "Connection: keep-alive\r\n"
9647 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579648 };
9649
9650 // Lastly, the server responds with the actual content.
9651 MockRead data_reads2[] = {
9652 MockRead("HTTP/1.1 200 OK\r\n"),
9653 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9654 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069655 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579656 };
9657
[email protected]31a2bfe2010-02-09 08:03:399658 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9659 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079660 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099661 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579662
[email protected]49639fa2011-12-20 23:22:419663 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579664
bnc691fda62016-08-12 00:43:169665 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509666
tfarina42834112016-09-22 13:38:209667 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019668 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579669
9670 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019671 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579672
bnc691fda62016-08-12 00:43:169673 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529674 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049675 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579676
[email protected]49639fa2011-12-20 23:22:419677 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579678
bnc691fda62016-08-12 00:43:169679 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019680 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579681
9682 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019683 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579684
bnc691fda62016-08-12 00:43:169685 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529686 ASSERT_TRUE(response);
9687 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579688 EXPECT_EQ(100, response->headers->GetContentLength());
9689}
9690
9691// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019692TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039693 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579694
9695 HttpRequestInfo request;
9696 request.method = "GET";
bncce36dca22015-04-21 22:11:239697 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579698
9699 MockRead proxy_reads[] = {
9700 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069701 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579702 };
9703
[email protected]31a2bfe2010-02-09 08:03:399704 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069705 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579706
[email protected]bb88e1d32013-05-03 23:11:079707 session_deps_.socket_factory->AddSocketDataProvider(&data);
9708 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579709
[email protected]49639fa2011-12-20 23:22:419710 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579711
[email protected]bb88e1d32013-05-03 23:11:079712 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579713
danakj1fd259a02016-04-16 03:17:099714 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169715 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579716
tfarina42834112016-09-22 13:38:209717 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579719
9720 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019721 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:579722}
9723
bncd16676a2016-07-20 16:23:019724TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469725 HttpRequestInfo request;
9726 request.method = "GET";
bncce36dca22015-04-21 22:11:239727 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469728
danakj1fd259a02016-04-16 03:17:099729 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279731
[email protected]e22e1362009-11-23 21:31:129732 MockRead data_reads[] = {
9733 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069734 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129735 };
[email protected]9492e4a2010-02-24 00:58:469736
9737 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079738 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469739
[email protected]49639fa2011-12-20 23:22:419740 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469741
tfarina42834112016-09-22 13:38:209742 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019743 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:469744
robpercival214763f2016-07-01 23:27:019745 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:469746
bnc691fda62016-08-12 00:43:169747 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529748 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469749
wezca1070932016-05-26 20:30:529750 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469751 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9752
9753 std::string response_data;
bnc691fda62016-08-12 00:43:169754 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019755 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:129756}
9757
bncd16676a2016-07-20 16:23:019758TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159759 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529760 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149761 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219762 UploadFileElementReader::ScopedOverridingContentLengthForTests
9763 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339764
danakj1fd259a02016-04-16 03:17:099765 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079766 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149767 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:079768 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229769 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279770
9771 HttpRequestInfo request;
9772 request.method = "POST";
bncce36dca22015-04-21 22:11:239773 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279774 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279775
danakj1fd259a02016-04-16 03:17:099776 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:339778
9779 MockRead data_reads[] = {
9780 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9781 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069782 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339783 };
[email protected]31a2bfe2010-02-09 08:03:399784 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079785 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339786
[email protected]49639fa2011-12-20 23:22:419787 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339788
tfarina42834112016-09-22 13:38:209789 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019790 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:339791
9792 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019793 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:339794
bnc691fda62016-08-12 00:43:169795 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529796 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339797
maksim.sisove869bf52016-06-23 17:11:529798 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339799
[email protected]dd3aa792013-07-16 19:10:239800 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339801}
9802
bncd16676a2016-07-20 16:23:019803TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159804 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529805 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369806 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:309807 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:369808 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119809 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369810
danakj1fd259a02016-04-16 03:17:099811 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:079812 element_readers.push_back(base::MakeUnique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:149813 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:079814 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:229815 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279816
9817 HttpRequestInfo request;
9818 request.method = "POST";
bncce36dca22015-04-21 22:11:239819 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279820 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:279821
[email protected]999dd8c2013-11-12 06:45:549822 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099823 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169824 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:369825
[email protected]999dd8c2013-11-12 06:45:549826 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079827 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369828
[email protected]49639fa2011-12-20 23:22:419829 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369830
tfarina42834112016-09-22 13:38:209831 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:369833
9834 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019835 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:369836
[email protected]dd3aa792013-07-16 19:10:239837 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369838}
9839
bncd16676a2016-07-20 16:23:019840TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:039841 class FakeUploadElementReader : public UploadElementReader {
9842 public:
9843 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209844 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039845
9846 const CompletionCallback& callback() const { return callback_; }
9847
9848 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209849 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039850 callback_ = callback;
9851 return ERR_IO_PENDING;
9852 }
avibf0746c2015-12-09 19:53:149853 uint64_t GetContentLength() const override { return 0; }
9854 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209855 int Read(IOBuffer* buf,
9856 int buf_length,
9857 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039858 return ERR_FAILED;
9859 }
9860
9861 private:
9862 CompletionCallback callback_;
9863 };
9864
9865 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099866 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9867 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229868 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039869
9870 HttpRequestInfo request;
9871 request.method = "POST";
bncce36dca22015-04-21 22:11:239872 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039873 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:039874
danakj1fd259a02016-04-16 03:17:099875 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169876 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:419877 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039878
9879 StaticSocketDataProvider data;
9880 session_deps_.socket_factory->AddSocketDataProvider(&data);
9881
9882 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:209883 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:559885 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039886
9887 // Transaction is pending on request body initialization.
9888 ASSERT_FALSE(fake_reader->callback().is_null());
9889
9890 // Return Init()'s result after the transaction gets destroyed.
9891 trans.reset();
9892 fake_reader->callback().Run(OK); // Should not crash.
9893}
9894
[email protected]aeefc9e82010-02-19 16:18:279895// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:019896TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279897 HttpRequestInfo request;
9898 request.method = "GET";
bncce36dca22015-04-21 22:11:239899 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279900
9901 // First transaction will request a resource and receive a Basic challenge
9902 // with realm="first_realm".
9903 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239904 MockWrite(
9905 "GET / HTTP/1.1\r\n"
9906 "Host: www.example.org\r\n"
9907 "Connection: keep-alive\r\n"
9908 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279909 };
9910 MockRead data_reads1[] = {
9911 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9912 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9913 "\r\n"),
9914 };
9915
bnc691fda62016-08-12 00:43:169916 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:279917 // for first_realm. The server will reject and provide a challenge with
9918 // second_realm.
9919 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239920 MockWrite(
9921 "GET / HTTP/1.1\r\n"
9922 "Host: www.example.org\r\n"
9923 "Connection: keep-alive\r\n"
9924 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9925 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279926 };
9927 MockRead data_reads2[] = {
9928 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9929 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9930 "\r\n"),
9931 };
9932
9933 // This again fails, and goes back to first_realm. Make sure that the
9934 // entry is removed from cache.
9935 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239936 MockWrite(
9937 "GET / HTTP/1.1\r\n"
9938 "Host: www.example.org\r\n"
9939 "Connection: keep-alive\r\n"
9940 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9941 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279942 };
9943 MockRead data_reads3[] = {
9944 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9945 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9946 "\r\n"),
9947 };
9948
9949 // Try one last time (with the correct password) and get the resource.
9950 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239951 MockWrite(
9952 "GET / HTTP/1.1\r\n"
9953 "Host: www.example.org\r\n"
9954 "Connection: keep-alive\r\n"
9955 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9956 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279957 };
9958 MockRead data_reads4[] = {
9959 MockRead("HTTP/1.1 200 OK\r\n"
9960 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509961 "Content-Length: 5\r\n"
9962 "\r\n"
9963 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279964 };
9965
9966 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9967 data_writes1, arraysize(data_writes1));
9968 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9969 data_writes2, arraysize(data_writes2));
9970 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9971 data_writes3, arraysize(data_writes3));
9972 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9973 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079974 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9975 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9976 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9977 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279978
[email protected]49639fa2011-12-20 23:22:419979 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279980
danakj1fd259a02016-04-16 03:17:099981 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169982 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509983
[email protected]aeefc9e82010-02-19 16:18:279984 // Issue the first request with Authorize headers. There should be a
9985 // password prompt for first_realm waiting to be filled in after the
9986 // transaction completes.
tfarina42834112016-09-22 13:38:209987 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019988 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:279989 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019990 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169991 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529992 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049993 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529994 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049995 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:439996 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:049997 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199998 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279999
10000 // Issue the second request with an incorrect password. There should be a
10001 // password prompt for second_realm waiting to be filled in after the
10002 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110003 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610004 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10005 callback2.callback());
robpercival214763f2016-07-01 23:27:0110006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710007 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110008 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610009 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210010 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410011 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210012 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410013 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310014 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410015 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910016 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710017
10018 // Issue the third request with another incorrect password. There should be
10019 // a password prompt for first_realm waiting to be filled in. If the password
10020 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10021 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110022 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610023 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10024 callback3.callback());
robpercival214763f2016-07-01 23:27:0110025 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710026 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110027 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610028 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210029 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410030 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210031 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410032 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310033 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410034 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910035 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710036
10037 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110038 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610039 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10040 callback4.callback());
robpercival214763f2016-07-01 23:27:0110041 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710042 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110043 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610044 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210045 ASSERT_TRUE(response);
10046 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710047}
10048
bncd16676a2016-07-20 16:23:0110049TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210050 MockRead data_reads[] = {
10051 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310052 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210053 MockRead("\r\n"),
10054 MockRead("hello world"),
10055 MockRead(SYNCHRONOUS, OK),
10056 };
10057
10058 HttpRequestInfo request;
10059 request.method = "GET";
bncb26024382016-06-29 02:39:4510060 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210061
10062 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210063 session_deps_.socket_factory->AddSocketDataProvider(&data);
10064
bncb26024382016-06-29 02:39:4510065 SSLSocketDataProvider ssl(ASYNC, OK);
10066 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10067
bncc958faa2015-07-31 18:14:5210068 TestCompletionCallback callback;
10069
danakj1fd259a02016-04-16 03:17:0910070 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610071 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210072
tfarina42834112016-09-22 13:38:2010073 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110074 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210075
bncb26024382016-06-29 02:39:4510076 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010077 HttpServerProperties* http_server_properties =
10078 session->http_server_properties();
bncc958faa2015-07-31 18:14:5210079 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010080 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210081 EXPECT_TRUE(alternative_service_vector.empty());
10082
robpercival214763f2016-07-01 23:27:0110083 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210084
bnc691fda62016-08-12 00:43:1610085 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210086 ASSERT_TRUE(response);
10087 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210088 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10089 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210090 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210091
10092 std::string response_data;
bnc691fda62016-08-12 00:43:1610093 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210094 EXPECT_EQ("hello world", response_data);
10095
10096 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010097 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210098 ASSERT_EQ(1u, alternative_service_vector.size());
bnc3472afd2016-11-17 15:27:2110099 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[0].protocol);
bncb26024382016-06-29 02:39:4510100 EXPECT_EQ("mail.example.org", alternative_service_vector[0].host);
bncc958faa2015-07-31 18:14:5210101 EXPECT_EQ(443, alternative_service_vector[0].port);
10102}
10103
bnce3dd56f2016-06-01 10:37:1110104// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110105TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110106 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110107 MockRead data_reads[] = {
10108 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310109 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110110 MockRead("\r\n"),
10111 MockRead("hello world"),
10112 MockRead(SYNCHRONOUS, OK),
10113 };
10114
10115 HttpRequestInfo request;
10116 request.method = "GET";
10117 request.url = GURL("http://www.example.org/");
10118 request.load_flags = 0;
10119
10120 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10121 session_deps_.socket_factory->AddSocketDataProvider(&data);
10122
10123 TestCompletionCallback callback;
10124
10125 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610126 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110127
10128 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010129 HttpServerProperties* http_server_properties =
10130 session->http_server_properties();
bnce3dd56f2016-06-01 10:37:1110131 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010132 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:1110133 EXPECT_TRUE(alternative_service_vector.empty());
10134
tfarina42834112016-09-22 13:38:2010135 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110136 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10137 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110138
bnc691fda62016-08-12 00:43:1610139 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110140 ASSERT_TRUE(response);
10141 ASSERT_TRUE(response->headers);
10142 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10143 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210144 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110145
10146 std::string response_data;
bnc691fda62016-08-12 00:43:1610147 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110148 EXPECT_EQ("hello world", response_data);
10149
10150 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010151 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:1110152 EXPECT_TRUE(alternative_service_vector.empty());
10153}
10154
bnc8bef8da22016-05-30 01:28:2510155// HTTP/2 Alternative Services should be disabled if alternative service
10156// hostname is different from that of origin.
10157// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110158TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510159 DisableHTTP2AlternativeServicesWithDifferentHost) {
bncb26024382016-06-29 02:39:4510160 session_deps_.enable_http2_alternative_service_with_different_host = false;
10161
bnc8bef8da22016-05-30 01:28:2510162 HttpRequestInfo request;
10163 request.method = "GET";
bncb26024382016-06-29 02:39:4510164 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510165 request.load_flags = 0;
10166
10167 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10168 StaticSocketDataProvider first_data;
10169 first_data.set_connect_data(mock_connect);
10170 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510171 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610172 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510173 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510174
10175 MockRead data_reads[] = {
10176 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10177 MockRead(ASYNC, OK),
10178 };
10179 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10180 0);
10181 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10182
10183 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10184
bnc525e175a2016-06-20 12:36:4010185 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510186 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110187 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10188 444);
bnc8bef8da22016-05-30 01:28:2510189 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10190 http_server_properties->SetAlternativeService(
10191 url::SchemeHostPort(request.url), alternative_service, expiration);
10192
bnc691fda62016-08-12 00:43:1610193 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510194 TestCompletionCallback callback;
10195
tfarina42834112016-09-22 13:38:2010196 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510197 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110198 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510199}
10200
bnce3dd56f2016-06-01 10:37:1110201// Regression test for https://crbug.com/615497:
10202// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110203TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110204 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110205 HttpRequestInfo request;
10206 request.method = "GET";
10207 request.url = GURL("http://www.example.org/");
10208 request.load_flags = 0;
10209
10210 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10211 StaticSocketDataProvider first_data;
10212 first_data.set_connect_data(mock_connect);
10213 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10214
10215 MockRead data_reads[] = {
10216 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10217 MockRead(ASYNC, OK),
10218 };
10219 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10220 0);
10221 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10222
10223 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10224
bnc525e175a2016-06-20 12:36:4010225 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110226 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110227 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110228 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10229 http_server_properties->SetAlternativeService(
10230 url::SchemeHostPort(request.url), alternative_service, expiration);
10231
bnc691fda62016-08-12 00:43:1610232 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110233 TestCompletionCallback callback;
10234
tfarina42834112016-09-22 13:38:2010235 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110236 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110237 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110238}
10239
bncd16676a2016-07-20 16:23:0110240TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810241 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910242 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010243 HttpServerProperties* http_server_properties =
10244 session->http_server_properties();
bncb26024382016-06-29 02:39:4510245 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110246 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810247 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc525e175a2016-06-20 12:36:4010248 http_server_properties->SetAlternativeService(
10249 test_server, alternative_service, expiration);
bnc4f575852015-10-14 18:35:0810250 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010251 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810252 EXPECT_EQ(1u, alternative_service_vector.size());
10253
10254 // Send a clear header.
10255 MockRead data_reads[] = {
10256 MockRead("HTTP/1.1 200 OK\r\n"),
10257 MockRead("Alt-Svc: clear\r\n"),
10258 MockRead("\r\n"),
10259 MockRead("hello world"),
10260 MockRead(SYNCHRONOUS, OK),
10261 };
10262 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10263 session_deps_.socket_factory->AddSocketDataProvider(&data);
10264
bncb26024382016-06-29 02:39:4510265 SSLSocketDataProvider ssl(ASYNC, OK);
10266 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10267
bnc4f575852015-10-14 18:35:0810268 HttpRequestInfo request;
10269 request.method = "GET";
bncb26024382016-06-29 02:39:4510270 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810271
10272 TestCompletionCallback callback;
10273
bnc691fda62016-08-12 00:43:1610274 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810275
tfarina42834112016-09-22 13:38:2010276 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110277 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810278
bnc691fda62016-08-12 00:43:1610279 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210280 ASSERT_TRUE(response);
10281 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810282 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10283 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210284 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810285
10286 std::string response_data;
bnc691fda62016-08-12 00:43:1610287 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810288 EXPECT_EQ("hello world", response_data);
10289
10290 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010291 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810292 EXPECT_TRUE(alternative_service_vector.empty());
10293}
10294
bncd16676a2016-07-20 16:23:0110295TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210296 MockRead data_reads[] = {
10297 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310298 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10299 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210300 MockRead("hello world"),
10301 MockRead(SYNCHRONOUS, OK),
10302 };
10303
10304 HttpRequestInfo request;
10305 request.method = "GET";
bncb26024382016-06-29 02:39:4510306 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210307
10308 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210309 session_deps_.socket_factory->AddSocketDataProvider(&data);
10310
bncb26024382016-06-29 02:39:4510311 SSLSocketDataProvider ssl(ASYNC, OK);
10312 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10313
bncc958faa2015-07-31 18:14:5210314 TestCompletionCallback callback;
10315
danakj1fd259a02016-04-16 03:17:0910316 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610317 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210318
tfarina42834112016-09-22 13:38:2010319 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110320 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210321
bncb26024382016-06-29 02:39:4510322 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010323 HttpServerProperties* http_server_properties =
10324 session->http_server_properties();
bncc958faa2015-07-31 18:14:5210325 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010326 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210327 EXPECT_TRUE(alternative_service_vector.empty());
10328
robpercival214763f2016-07-01 23:27:0110329 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210330
bnc691fda62016-08-12 00:43:1610331 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210332 ASSERT_TRUE(response);
10333 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210334 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10335 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210336 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210337
10338 std::string response_data;
bnc691fda62016-08-12 00:43:1610339 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210340 EXPECT_EQ("hello world", response_data);
10341
10342 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010343 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210344 ASSERT_EQ(2u, alternative_service_vector.size());
bnc3472afd2016-11-17 15:27:2110345 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[0].protocol);
bncc958faa2015-07-31 18:14:5210346 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
10347 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc3472afd2016-11-17 15:27:2110348 EXPECT_EQ(kProtoHTTP2, alternative_service_vector[1].protocol);
bncc958faa2015-07-31 18:14:5210349 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
10350 EXPECT_EQ(1234, alternative_service_vector[1].port);
10351}
10352
bncd16676a2016-07-20 16:23:0110353TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610354 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210355 HostPortPair alternative("alternative.example.org", 443);
10356 std::string origin_url = "https://origin.example.org:443";
10357 std::string alternative_url = "https://alternative.example.org:443";
10358
10359 // Negotiate HTTP/1.1 with alternative.example.org.
10360 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610361 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10363
10364 // HTTP/1.1 data for request.
10365 MockWrite http_writes[] = {
10366 MockWrite("GET / HTTP/1.1\r\n"
10367 "Host: alternative.example.org\r\n"
10368 "Connection: keep-alive\r\n\r\n"),
10369 };
10370
10371 MockRead http_reads[] = {
10372 MockRead("HTTP/1.1 200 OK\r\n"
10373 "Content-Type: text/html; charset=iso-8859-1\r\n"
10374 "Content-Length: 40\r\n\r\n"
10375 "first HTTP/1.1 response from alternative"),
10376 };
10377 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10378 http_writes, arraysize(http_writes));
10379 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10380
10381 StaticSocketDataProvider data_refused;
10382 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10383 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10384
zhongyi3d4a55e72016-04-22 20:36:4610385 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910386 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010387 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210388 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110389 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0210390 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610391 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5010392 expiration);
zhongyi48704c182015-12-07 07:52:0210393 // Mark the QUIC alternative service as broken.
10394 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10395
bnc691fda62016-08-12 00:43:1610396 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210397 HttpRequestInfo request;
10398 request.method = "GET";
10399 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210400 TestCompletionCallback callback;
10401 NetErrorDetails details;
10402 EXPECT_FALSE(details.quic_broken);
10403
tfarina42834112016-09-22 13:38:2010404 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610405 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210406 EXPECT_TRUE(details.quic_broken);
10407}
10408
bncd16676a2016-07-20 16:23:0110409TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610410 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210411 HostPortPair alternative1("alternative1.example.org", 443);
10412 HostPortPair alternative2("alternative2.example.org", 443);
10413 std::string origin_url = "https://origin.example.org:443";
10414 std::string alternative_url1 = "https://alternative1.example.org:443";
10415 std::string alternative_url2 = "https://alternative2.example.org:443";
10416
10417 // Negotiate HTTP/1.1 with alternative1.example.org.
10418 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610419 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210420 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10421
10422 // HTTP/1.1 data for request.
10423 MockWrite http_writes[] = {
10424 MockWrite("GET / HTTP/1.1\r\n"
10425 "Host: alternative1.example.org\r\n"
10426 "Connection: keep-alive\r\n\r\n"),
10427 };
10428
10429 MockRead http_reads[] = {
10430 MockRead("HTTP/1.1 200 OK\r\n"
10431 "Content-Type: text/html; charset=iso-8859-1\r\n"
10432 "Content-Length: 40\r\n\r\n"
10433 "first HTTP/1.1 response from alternative1"),
10434 };
10435 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10436 http_writes, arraysize(http_writes));
10437 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10438
10439 StaticSocketDataProvider data_refused;
10440 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10441 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10442
danakj1fd259a02016-04-16 03:17:0910443 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010444 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210445 session->http_server_properties();
10446
zhongyi3d4a55e72016-04-22 20:36:4610447 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210448 AlternativeServiceInfoVector alternative_service_info_vector;
10449 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10450
bnc3472afd2016-11-17 15:27:2110451 AlternativeService alternative_service1(kProtoQUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010452 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210453 expiration);
10454 alternative_service_info_vector.push_back(alternative_service_info1);
bnc3472afd2016-11-17 15:27:2110455 AlternativeService alternative_service2(kProtoQUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010456 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210457 expiration);
10458 alternative_service_info_vector.push_back(alternative_service_info2);
10459
10460 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610461 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210462
10463 // Mark one of the QUIC alternative service as broken.
10464 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
10465
10466 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610467 http_server_properties->GetAlternativeServices(server);
zhongyi48704c182015-12-07 07:52:0210468
bnc691fda62016-08-12 00:43:1610469 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210470 HttpRequestInfo request;
10471 request.method = "GET";
10472 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210473 TestCompletionCallback callback;
10474 NetErrorDetails details;
10475 EXPECT_FALSE(details.quic_broken);
10476
tfarina42834112016-09-22 13:38:2010477 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610478 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210479 EXPECT_FALSE(details.quic_broken);
10480}
10481
bncd16676a2016-07-20 16:23:0110482TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210483 HttpRequestInfo request;
10484 request.method = "GET";
bncb26024382016-06-29 02:39:4510485 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210486
[email protected]d973e99a2012-02-17 21:02:3610487 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210488 StaticSocketDataProvider first_data;
10489 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710490 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510491 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610492 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510493 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210494
10495 MockRead data_reads[] = {
10496 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10497 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610498 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210499 };
10500 StaticSocketDataProvider second_data(
10501 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710502 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210503
danakj1fd259a02016-04-16 03:17:0910504 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210505
bnc525e175a2016-06-20 12:36:4010506 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310507 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610508 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110509 // Port must be < 1024, or the header will be ignored (since initial port was
10510 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010511 const AlternativeService alternative_service(
bnc3472afd2016-11-17 15:27:2110512 kProtoHTTP2, "www.example.org",
bncd9b132e2015-07-08 05:16:1010513 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210514 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610515 http_server_properties->SetAlternativeService(server, alternative_service,
10516 expiration);
[email protected]564b4912010-03-09 16:30:4210517
bnc691fda62016-08-12 00:43:1610518 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110519 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210520
tfarina42834112016-09-22 13:38:2010521 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110522 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10523 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210524
bnc691fda62016-08-12 00:43:1610525 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210526 ASSERT_TRUE(response);
10527 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210528 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10529
10530 std::string response_data;
bnc691fda62016-08-12 00:43:1610531 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210532 EXPECT_EQ("hello world", response_data);
10533
bncd9b132e2015-07-08 05:16:1010534 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610535 http_server_properties->GetAlternativeServices(server);
bncd9b132e2015-07-08 05:16:1010536 ASSERT_EQ(1u, alternative_service_vector.size());
10537 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
10538 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
10539 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:4210540}
10541
bnc55ff9da2015-08-19 18:42:3510542// Ensure that we are not allowed to redirect traffic via an alternate protocol
10543// to an unrestricted (port >= 1024) when the original traffic was on a
10544// restricted port (port < 1024). Ensure that we can redirect in all other
10545// cases.
bncd16676a2016-07-20 16:23:0110546TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110547 HttpRequestInfo restricted_port_request;
10548 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510549 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110550 restricted_port_request.load_flags = 0;
10551
[email protected]d973e99a2012-02-17 21:02:3610552 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110553 StaticSocketDataProvider first_data;
10554 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710555 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110556
10557 MockRead data_reads[] = {
10558 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10559 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610560 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110561 };
10562 StaticSocketDataProvider second_data(
10563 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710564 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510565 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610566 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510567 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110568
danakj1fd259a02016-04-16 03:17:0910569 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110570
bnc525e175a2016-06-20 12:36:4010571 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310572 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110573 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110574 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10575 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210576 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210577 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610578 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010579 expiration);
[email protected]3912662a32011-10-04 00:51:1110580
bnc691fda62016-08-12 00:43:1610581 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110582 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110583
tfarina42834112016-09-22 13:38:2010584 int rv = trans.Start(&restricted_port_request, callback.callback(),
10585 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110586 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110587 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110588 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910589}
[email protected]3912662a32011-10-04 00:51:1110590
bnc55ff9da2015-08-19 18:42:3510591// Ensure that we are allowed to redirect traffic via an alternate protocol to
10592// an unrestricted (port >= 1024) when the original traffic was on a restricted
10593// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110594TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710595 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910596
10597 HttpRequestInfo restricted_port_request;
10598 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510599 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910600 restricted_port_request.load_flags = 0;
10601
10602 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10603 StaticSocketDataProvider first_data;
10604 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710605 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910606
10607 MockRead data_reads[] = {
10608 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10609 MockRead("hello world"),
10610 MockRead(ASYNC, OK),
10611 };
10612 StaticSocketDataProvider second_data(
10613 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710614 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510615 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610616 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510617 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910618
danakj1fd259a02016-04-16 03:17:0910619 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910620
bnc525e175a2016-06-20 12:36:4010621 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910622 session->http_server_properties();
10623 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110624 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10625 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210626 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210627 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610628 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010629 expiration);
[email protected]c54c6962013-02-01 04:53:1910630
bnc691fda62016-08-12 00:43:1610631 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910632 TestCompletionCallback callback;
10633
tfarina42834112016-09-22 13:38:2010634 EXPECT_EQ(ERR_IO_PENDING,
10635 trans.Start(&restricted_port_request, callback.callback(),
10636 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910637 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110638 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110639}
10640
bnc55ff9da2015-08-19 18:42:3510641// Ensure that we are not allowed to redirect traffic via an alternate protocol
10642// to an unrestricted (port >= 1024) when the original traffic was on a
10643// restricted port (port < 1024). Ensure that we can redirect in all other
10644// cases.
bncd16676a2016-07-20 16:23:0110645TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110646 HttpRequestInfo restricted_port_request;
10647 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510648 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110649 restricted_port_request.load_flags = 0;
10650
[email protected]d973e99a2012-02-17 21:02:3610651 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110652 StaticSocketDataProvider first_data;
10653 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710654 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110655
10656 MockRead data_reads[] = {
10657 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10658 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610659 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110660 };
10661 StaticSocketDataProvider second_data(
10662 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710663 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110664
bncb26024382016-06-29 02:39:4510665 SSLSocketDataProvider ssl(ASYNC, OK);
10666 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10667
danakj1fd259a02016-04-16 03:17:0910668 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110669
bnc525e175a2016-06-20 12:36:4010670 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310671 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110672 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110673 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10674 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210675 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210676 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610677 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010678 expiration);
[email protected]3912662a32011-10-04 00:51:1110679
bnc691fda62016-08-12 00:43:1610680 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110681 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110682
tfarina42834112016-09-22 13:38:2010683 int rv = trans.Start(&restricted_port_request, callback.callback(),
10684 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110685 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110686 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110687 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110688}
10689
bnc55ff9da2015-08-19 18:42:3510690// Ensure that we are not allowed to redirect traffic via an alternate protocol
10691// to an unrestricted (port >= 1024) when the original traffic was on a
10692// restricted port (port < 1024). Ensure that we can redirect in all other
10693// cases.
bncd16676a2016-07-20 16:23:0110694TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1110695 HttpRequestInfo unrestricted_port_request;
10696 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510697 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110698 unrestricted_port_request.load_flags = 0;
10699
[email protected]d973e99a2012-02-17 21:02:3610700 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110701 StaticSocketDataProvider first_data;
10702 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710703 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110704
10705 MockRead data_reads[] = {
10706 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10707 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610708 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110709 };
10710 StaticSocketDataProvider second_data(
10711 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710712 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510713 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610714 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510715 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110716
danakj1fd259a02016-04-16 03:17:0910717 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110718
bnc525e175a2016-06-20 12:36:4010719 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310720 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110721 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2110722 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10723 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210724 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210725 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610726 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010727 expiration);
[email protected]3912662a32011-10-04 00:51:1110728
bnc691fda62016-08-12 00:43:1610729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110730 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110731
bnc691fda62016-08-12 00:43:1610732 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010733 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110734 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110735 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0110736 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110737}
10738
bnc55ff9da2015-08-19 18:42:3510739// Ensure that we are not allowed to redirect traffic via an alternate protocol
10740// to an unrestricted (port >= 1024) when the original traffic was on a
10741// restricted port (port < 1024). Ensure that we can redirect in all other
10742// cases.
bncd16676a2016-07-20 16:23:0110743TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1110744 HttpRequestInfo unrestricted_port_request;
10745 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510746 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110747 unrestricted_port_request.load_flags = 0;
10748
[email protected]d973e99a2012-02-17 21:02:3610749 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110750 StaticSocketDataProvider first_data;
10751 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710752 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110753
10754 MockRead data_reads[] = {
10755 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10756 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610757 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110758 };
10759 StaticSocketDataProvider second_data(
10760 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710761 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110762
bncb26024382016-06-29 02:39:4510763 SSLSocketDataProvider ssl(ASYNC, OK);
10764 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10765
danakj1fd259a02016-04-16 03:17:0910766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110767
bnc525e175a2016-06-20 12:36:4010768 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310769 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210770 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2110771 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10772 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210773 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210774 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610775 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010776 expiration);
[email protected]3912662a32011-10-04 00:51:1110777
bnc691fda62016-08-12 00:43:1610778 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110779 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110780
bnc691fda62016-08-12 00:43:1610781 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2010782 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110784 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0110785 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110786}
10787
bnc55ff9da2015-08-19 18:42:3510788// Ensure that we are not allowed to redirect traffic via an alternate protocol
10789// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10790// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0110791TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0210792 HttpRequestInfo request;
10793 request.method = "GET";
bncce36dca22015-04-21 22:11:2310794 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210795
10796 // The alternate protocol request will error out before we attempt to connect,
10797 // so only the standard HTTP request will try to connect.
10798 MockRead data_reads[] = {
10799 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10800 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610801 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210802 };
10803 StaticSocketDataProvider data(
10804 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710805 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210806
danakj1fd259a02016-04-16 03:17:0910807 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210808
bnc525e175a2016-06-20 12:36:4010809 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210810 session->http_server_properties();
10811 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2110812 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10813 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210814 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210815 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610816 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210817
bnc691fda62016-08-12 00:43:1610818 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0210819 TestCompletionCallback callback;
10820
tfarina42834112016-09-22 13:38:2010821 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110822 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0210823 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0110824 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210825
bnc691fda62016-08-12 00:43:1610826 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210827 ASSERT_TRUE(response);
10828 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210829 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10830
10831 std::string response_data;
bnc691fda62016-08-12 00:43:1610832 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0210833 EXPECT_EQ("hello world", response_data);
10834}
10835
bncd16676a2016-07-20 16:23:0110836TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5410837 HttpRequestInfo request;
10838 request.method = "GET";
bncb26024382016-06-29 02:39:4510839 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410840
10841 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210842 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310843 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210844 MockRead("\r\n"),
10845 MockRead("hello world"),
10846 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10847 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410848
10849 StaticSocketDataProvider first_transaction(
10850 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710851 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4510852 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610853 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510854 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5410855
bnc032658ba2016-09-26 18:17:1510856 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5410857
bncdf80d44fd2016-07-15 20:27:4110858 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4510859 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110860 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410861
bnc42331402016-07-25 13:36:1510862 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110863 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410864 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110865 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410866 };
10867
rch8e6c6c42015-05-01 14:05:1310868 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10869 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710870 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410871
[email protected]d973e99a2012-02-17 21:02:3610872 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510873 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10874 NULL, 0, NULL, 0);
10875 hanging_non_alternate_protocol_socket.set_connect_data(
10876 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710877 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510878 &hanging_non_alternate_protocol_socket);
10879
[email protected]49639fa2011-12-20 23:22:4110880 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410881
danakj1fd259a02016-04-16 03:17:0910882 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610883 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5010884 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410885
tfarina42834112016-09-22 13:38:2010886 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110887 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10888 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410889
10890 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210891 ASSERT_TRUE(response);
10892 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410893 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10894
10895 std::string response_data;
robpercival214763f2016-07-01 23:27:0110896 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410897 EXPECT_EQ("hello world", response_data);
10898
[email protected]90499482013-06-01 00:39:5010899 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410900
tfarina42834112016-09-22 13:38:2010901 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110902 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10903 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410904
10905 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210906 ASSERT_TRUE(response);
10907 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210908 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310909 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210910 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410911
robpercival214763f2016-07-01 23:27:0110912 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5410913 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410914}
10915
bncd16676a2016-07-20 16:23:0110916TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5510917 HttpRequestInfo request;
10918 request.method = "GET";
bncb26024382016-06-29 02:39:4510919 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510920
bncb26024382016-06-29 02:39:4510921 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5510922 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210923 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310924 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210925 MockRead("\r\n"),
10926 MockRead("hello world"),
10927 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10928 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510929 };
10930
bncb26024382016-06-29 02:39:4510931 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
10932 0);
10933 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5510934
bncb26024382016-06-29 02:39:4510935 SSLSocketDataProvider ssl_http11(ASYNC, OK);
10936 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
10937
10938 // Second transaction starts an alternative and a non-alternative Job.
10939 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3610940 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810941 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10942 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1810943 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10944
10945 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10946 hanging_socket2.set_connect_data(never_finishing_connect);
10947 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510948
bncb26024382016-06-29 02:39:4510949 // Third transaction starts an alternative and a non-alternative job.
10950 // The non-alternative job hangs, but the alternative one succeeds.
10951 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4110952 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4510953 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4110954 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4510955 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5510956 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110957 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5510958 };
bnc42331402016-07-25 13:36:1510959 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4110960 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1510961 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4110962 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510963 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110964 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
10965 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1310966 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510967 };
10968
rch8e6c6c42015-05-01 14:05:1310969 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10970 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710971 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510972
bnc032658ba2016-09-26 18:17:1510973 AddSSLSocketData();
bncb26024382016-06-29 02:39:4510974
mmenkecc2298e2015-12-07 18:20:1810975 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10976 hanging_socket3.set_connect_data(never_finishing_connect);
10977 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510978
danakj1fd259a02016-04-16 03:17:0910979 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110980 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010981 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510982
tfarina42834112016-09-22 13:38:2010983 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110984 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10985 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5510986
10987 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5210988 ASSERT_TRUE(response);
10989 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510990 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10991
10992 std::string response_data;
robpercival214763f2016-07-01 23:27:0110993 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5510994 EXPECT_EQ("hello world", response_data);
10995
[email protected]49639fa2011-12-20 23:22:4110996 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5010997 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2010998 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110999 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511000
[email protected]49639fa2011-12-20 23:22:4111001 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011002 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011003 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511005
robpercival214763f2016-07-01 23:27:0111006 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11007 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511008
11009 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211010 ASSERT_TRUE(response);
11011 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211012 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511013 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211014 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111015 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511016 EXPECT_EQ("hello!", response_data);
11017
11018 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211019 ASSERT_TRUE(response);
11020 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211021 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511022 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211023 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111024 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511025 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511026}
11027
bncd16676a2016-07-20 16:23:0111028TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511029 HttpRequestInfo request;
11030 request.method = "GET";
bncb26024382016-06-29 02:39:4511031 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511032
11033 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211034 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311035 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211036 MockRead("\r\n"),
11037 MockRead("hello world"),
11038 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11039 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511040 };
11041
11042 StaticSocketDataProvider first_transaction(
11043 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711044 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511045
[email protected]8ddf8322012-02-23 18:08:0611046 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711047 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511048
[email protected]d973e99a2012-02-17 21:02:3611049 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511050 StaticSocketDataProvider hanging_alternate_protocol_socket(
11051 NULL, 0, NULL, 0);
11052 hanging_alternate_protocol_socket.set_connect_data(
11053 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711054 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511055 &hanging_alternate_protocol_socket);
11056
bncb26024382016-06-29 02:39:4511057 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811058 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11059 NULL, 0);
11060 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511061 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511062
[email protected]49639fa2011-12-20 23:22:4111063 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511064
danakj1fd259a02016-04-16 03:17:0911065 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611066 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011067 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511068
tfarina42834112016-09-22 13:38:2011069 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111070 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11071 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511072
11073 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211074 ASSERT_TRUE(response);
11075 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511076 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11077
11078 std::string response_data;
robpercival214763f2016-07-01 23:27:0111079 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511080 EXPECT_EQ("hello world", response_data);
11081
[email protected]90499482013-06-01 00:39:5011082 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511083
tfarina42834112016-09-22 13:38:2011084 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11086 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511087
11088 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211089 ASSERT_TRUE(response);
11090 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511091 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11092 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211093 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511094
robpercival214763f2016-07-01 23:27:0111095 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511096 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511097}
11098
[email protected]631f1322010-04-30 17:59:1111099class CapturingProxyResolver : public ProxyResolver {
11100 public:
sammce90c9212015-05-27 23:43:3511101 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011102 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111103
dchengb03027d2014-10-21 12:00:2011104 int GetProxyForURL(const GURL& url,
11105 ProxyInfo* results,
11106 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511107 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011108 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011109 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11110 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211111 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111112 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211113 return OK;
[email protected]631f1322010-04-30 17:59:1111114 }
11115
[email protected]24476402010-07-20 20:55:1711116 const std::vector<GURL>& resolved() const { return resolved_; }
11117
11118 private:
[email protected]631f1322010-04-30 17:59:1111119 std::vector<GURL> resolved_;
11120
11121 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11122};
11123
sammce64b2362015-04-29 03:50:2311124class CapturingProxyResolverFactory : public ProxyResolverFactory {
11125 public:
11126 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11127 : ProxyResolverFactory(false), resolver_(resolver) {}
11128
11129 int CreateProxyResolver(
11130 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911131 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311132 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911133 std::unique_ptr<Request>* request) override {
sammce64b2362015-04-29 03:50:2311134 resolver->reset(new ForwardingProxyResolver(resolver_));
11135 return OK;
11136 }
11137
11138 private:
11139 ProxyResolver* resolver_;
11140};
11141
bnc2e884782016-08-11 19:45:1911142// Test that proxy is resolved using the origin url,
11143// regardless of the alternative server.
11144TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11145 // Configure proxy to bypass www.example.org, which is the origin URL.
11146 ProxyConfig proxy_config;
11147 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11148 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11149 auto proxy_config_service =
11150 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config);
11151
11152 CapturingProxyResolver capturing_proxy_resolver;
11153 auto proxy_resolver_factory = base::MakeUnique<CapturingProxyResolverFactory>(
11154 &capturing_proxy_resolver);
11155
11156 TestNetLog net_log;
11157
11158 session_deps_.proxy_service = base::MakeUnique<ProxyService>(
11159 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11160 &net_log);
11161
11162 session_deps_.net_log = &net_log;
11163
11164 // Configure alternative service with a hostname that is not bypassed by the
11165 // proxy.
11166 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11167 HttpServerProperties* http_server_properties =
11168 session->http_server_properties();
11169 url::SchemeHostPort server("https", "www.example.org", 443);
11170 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111171 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911172 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11173 http_server_properties->SetAlternativeService(server, alternative_service,
11174 expiration);
11175
11176 // Non-alternative job should hang.
11177 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11178 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11179 nullptr, 0);
11180 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11181 session_deps_.socket_factory->AddSocketDataProvider(
11182 &hanging_alternate_protocol_socket);
11183
bnc032658ba2016-09-26 18:17:1511184 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911185
11186 HttpRequestInfo request;
11187 request.method = "GET";
11188 request.url = GURL("https://www.example.org/");
11189 request.load_flags = 0;
11190
11191 SpdySerializedFrame req(
11192 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11193
11194 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11195
11196 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11197 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11198 MockRead spdy_reads[] = {
11199 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11200 };
11201
11202 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11203 arraysize(spdy_writes));
11204 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11205
11206 TestCompletionCallback callback;
11207
11208 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11209
tfarina42834112016-09-22 13:38:2011210 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911211 EXPECT_THAT(callback.GetResult(rv), IsOk());
11212
11213 const HttpResponseInfo* response = trans.GetResponseInfo();
11214 ASSERT_TRUE(response);
11215 ASSERT_TRUE(response->headers);
11216 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11217 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211218 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911219
11220 std::string response_data;
11221 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11222 EXPECT_EQ("hello!", response_data);
11223
11224 // Origin host bypasses proxy, no resolution should have happened.
11225 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11226}
11227
bncd16676a2016-07-20 16:23:0111228TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111229 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211230 proxy_config.set_auto_detect(true);
11231 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111232
sammc5dd160c2015-04-02 02:43:1311233 CapturingProxyResolver capturing_proxy_resolver;
ricea2deef682016-09-09 08:04:0711234 session_deps_.proxy_service.reset(
11235 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
11236 base::MakeUnique<CapturingProxyResolverFactory>(
11237 &capturing_proxy_resolver),
11238 NULL));
vishal.b62985ca92015-04-17 08:45:5111239 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711240 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111241
11242 HttpRequestInfo request;
11243 request.method = "GET";
bncb26024382016-06-29 02:39:4511244 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111245
11246 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211247 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311248 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211249 MockRead("\r\n"),
11250 MockRead("hello world"),
11251 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11252 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111253 };
11254
11255 StaticSocketDataProvider first_transaction(
11256 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711257 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511258 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611259 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511260 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111261
bnc032658ba2016-09-26 18:17:1511262 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111263
bncdf80d44fd2016-07-15 20:27:4111264 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511265 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111266 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311267 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511268 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11269 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311270 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111271 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111272 };
11273
[email protected]d911f1b2010-05-05 22:39:4211274 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11275
bnc42331402016-07-25 13:36:1511276 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111277 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111278 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111279 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11280 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111281 };
11282
rch8e6c6c42015-05-01 14:05:1311283 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11284 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711285 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111286
[email protected]d973e99a2012-02-17 21:02:3611287 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511288 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11289 NULL, 0, NULL, 0);
11290 hanging_non_alternate_protocol_socket.set_connect_data(
11291 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711292 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511293 &hanging_non_alternate_protocol_socket);
11294
[email protected]49639fa2011-12-20 23:22:4111295 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111296
danakj1fd259a02016-04-16 03:17:0911297 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611298 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011299 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111300
tfarina42834112016-09-22 13:38:2011301 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111302 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11303 EXPECT_THAT(callback.WaitForResult(), IsOk());
11304
11305 const HttpResponseInfo* response = trans->GetResponseInfo();
11306 ASSERT_TRUE(response);
11307 ASSERT_TRUE(response->headers);
11308 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11309 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211310 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111311
11312 std::string response_data;
11313 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11314 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111315
[email protected]90499482013-06-01 00:39:5011316 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111317
tfarina42834112016-09-22 13:38:2011318 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111319 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11320 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111321
mmenkea2dcd3bf2016-08-16 21:49:4111322 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211323 ASSERT_TRUE(response);
11324 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211325 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311326 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211327 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111328
robpercival214763f2016-07-01 23:27:0111329 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111330 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511331 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11332 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311333 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311334 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311335 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111336
[email protected]029c83b62013-01-24 05:28:2011337 LoadTimingInfo load_timing_info;
11338 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11339 TestLoadTimingNotReusedWithPac(load_timing_info,
11340 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111341}
[email protected]631f1322010-04-30 17:59:1111342
bncd16676a2016-07-20 16:23:0111343TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811344 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411345 HttpRequestInfo request;
11346 request.method = "GET";
bncb26024382016-06-29 02:39:4511347 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411348
11349 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211350 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311351 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211352 MockRead("\r\n"),
11353 MockRead("hello world"),
11354 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411355 };
11356
11357 StaticSocketDataProvider first_transaction(
11358 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711359 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511360 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611361 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411363
bnc032658ba2016-09-26 18:17:1511364 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411365
bncdf80d44fd2016-07-15 20:27:4111366 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511367 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111368 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411369
bnc42331402016-07-25 13:36:1511370 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111371 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411372 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111373 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411374 };
11375
rch8e6c6c42015-05-01 14:05:1311376 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11377 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711378 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411379
[email protected]83039bb2011-12-09 18:43:5511380 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411381
danakj1fd259a02016-04-16 03:17:0911382 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411383
bnc691fda62016-08-12 00:43:1611384 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011385 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411386
tfarina42834112016-09-22 13:38:2011387 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111388 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11389 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411390
11391 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211392 ASSERT_TRUE(response);
11393 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411394 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11395
11396 std::string response_data;
robpercival214763f2016-07-01 23:27:0111397 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411398 EXPECT_EQ("hello world", response_data);
11399
11400 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511401 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011402 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311403 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711404 base::WeakPtr<SpdySession> spdy_session =
tfarina42834112016-09-22 13:38:2011405 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811406
[email protected]90499482013-06-01 00:39:5011407 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411408
tfarina42834112016-09-22 13:38:2011409 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111410 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11411 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411412
11413 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211414 ASSERT_TRUE(response);
11415 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211416 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311417 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211418 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411419
robpercival214763f2016-07-01 23:27:0111420 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411421 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211422}
11423
[email protected]044de0642010-06-17 10:42:1511424// GenerateAuthToken is a mighty big test.
11425// It tests all permutation of GenerateAuthToken behavior:
11426// - Synchronous and Asynchronous completion.
11427// - OK or error on completion.
11428// - Direct connection, non-authenticating proxy, and authenticating proxy.
11429// - HTTP or HTTPS backend (to include proxy tunneling).
11430// - Non-authenticating and authenticating backend.
11431//
[email protected]fe3b7dc2012-02-03 19:52:0911432// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511433// problems generating an auth token for an authenticating proxy, we don't
11434// need to test all permutations of the backend server).
11435//
11436// The test proceeds by going over each of the configuration cases, and
11437// potentially running up to three rounds in each of the tests. The TestConfig
11438// specifies both the configuration for the test as well as the expectations
11439// for the results.
bncd16676a2016-07-20 16:23:0111440TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011441 static const char kServer[] = "http://www.example.com";
11442 static const char kSecureServer[] = "https://www.example.com";
11443 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511444
11445 enum AuthTiming {
11446 AUTH_NONE,
11447 AUTH_SYNC,
11448 AUTH_ASYNC,
11449 };
11450
11451 const MockWrite kGet(
11452 "GET / HTTP/1.1\r\n"
11453 "Host: www.example.com\r\n"
11454 "Connection: keep-alive\r\n\r\n");
11455 const MockWrite kGetProxy(
11456 "GET http://www.example.com/ HTTP/1.1\r\n"
11457 "Host: www.example.com\r\n"
11458 "Proxy-Connection: keep-alive\r\n\r\n");
11459 const MockWrite kGetAuth(
11460 "GET / HTTP/1.1\r\n"
11461 "Host: www.example.com\r\n"
11462 "Connection: keep-alive\r\n"
11463 "Authorization: auth_token\r\n\r\n");
11464 const MockWrite kGetProxyAuth(
11465 "GET http://www.example.com/ HTTP/1.1\r\n"
11466 "Host: www.example.com\r\n"
11467 "Proxy-Connection: keep-alive\r\n"
11468 "Proxy-Authorization: auth_token\r\n\r\n");
11469 const MockWrite kGetAuthThroughProxy(
11470 "GET http://www.example.com/ HTTP/1.1\r\n"
11471 "Host: www.example.com\r\n"
11472 "Proxy-Connection: keep-alive\r\n"
11473 "Authorization: auth_token\r\n\r\n");
11474 const MockWrite kGetAuthWithProxyAuth(
11475 "GET http://www.example.com/ HTTP/1.1\r\n"
11476 "Host: www.example.com\r\n"
11477 "Proxy-Connection: keep-alive\r\n"
11478 "Proxy-Authorization: auth_token\r\n"
11479 "Authorization: auth_token\r\n\r\n");
11480 const MockWrite kConnect(
11481 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711482 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511483 "Proxy-Connection: keep-alive\r\n\r\n");
11484 const MockWrite kConnectProxyAuth(
11485 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711486 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511487 "Proxy-Connection: keep-alive\r\n"
11488 "Proxy-Authorization: auth_token\r\n\r\n");
11489
11490 const MockRead kSuccess(
11491 "HTTP/1.1 200 OK\r\n"
11492 "Content-Type: text/html; charset=iso-8859-1\r\n"
11493 "Content-Length: 3\r\n\r\n"
11494 "Yes");
11495 const MockRead kFailure(
11496 "Should not be called.");
11497 const MockRead kServerChallenge(
11498 "HTTP/1.1 401 Unauthorized\r\n"
11499 "WWW-Authenticate: Mock realm=server\r\n"
11500 "Content-Type: text/html; charset=iso-8859-1\r\n"
11501 "Content-Length: 14\r\n\r\n"
11502 "Unauthorized\r\n");
11503 const MockRead kProxyChallenge(
11504 "HTTP/1.1 407 Unauthorized\r\n"
11505 "Proxy-Authenticate: Mock realm=proxy\r\n"
11506 "Proxy-Connection: close\r\n"
11507 "Content-Type: text/html; charset=iso-8859-1\r\n"
11508 "Content-Length: 14\r\n\r\n"
11509 "Unauthorized\r\n");
11510 const MockRead kProxyConnected(
11511 "HTTP/1.1 200 Connection Established\r\n\r\n");
11512
11513 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11514 // no constructors, but the C++ compiler on Windows warns about
11515 // unspecified data in compound literals. So, moved to using constructors,
11516 // and TestRound's created with the default constructor should not be used.
11517 struct TestRound {
11518 TestRound()
11519 : expected_rv(ERR_UNEXPECTED),
11520 extra_write(NULL),
11521 extra_read(NULL) {
11522 }
11523 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11524 int expected_rv_arg)
11525 : write(write_arg),
11526 read(read_arg),
11527 expected_rv(expected_rv_arg),
11528 extra_write(NULL),
11529 extra_read(NULL) {
11530 }
11531 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11532 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111533 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511534 : write(write_arg),
11535 read(read_arg),
11536 expected_rv(expected_rv_arg),
11537 extra_write(extra_write_arg),
11538 extra_read(extra_read_arg) {
11539 }
11540 MockWrite write;
11541 MockRead read;
11542 int expected_rv;
11543 const MockWrite* extra_write;
11544 const MockRead* extra_read;
11545 };
11546
11547 static const int kNoSSL = 500;
11548
11549 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111550 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111551 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511552 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111553 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111554 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511555 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111556 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511557 int num_auth_rounds;
11558 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611559 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511560 } test_configs[] = {
asankac93076192016-10-03 15:46:0211561 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111562 {__LINE__,
11563 nullptr,
asankac93076192016-10-03 15:46:0211564 AUTH_NONE,
11565 OK,
11566 kServer,
11567 AUTH_NONE,
11568 OK,
11569 1,
11570 kNoSSL,
11571 {TestRound(kGet, kSuccess, OK)}},
11572 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111573 {__LINE__,
11574 nullptr,
asankac93076192016-10-03 15:46:0211575 AUTH_NONE,
11576 OK,
11577 kServer,
11578 AUTH_SYNC,
11579 OK,
11580 2,
11581 kNoSSL,
11582 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511583 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111584 {__LINE__,
11585 nullptr,
asankac93076192016-10-03 15:46:0211586 AUTH_NONE,
11587 OK,
11588 kServer,
11589 AUTH_SYNC,
11590 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611591 3,
11592 kNoSSL,
11593 {TestRound(kGet, kServerChallenge, OK),
11594 TestRound(kGet, kServerChallenge, OK),
11595 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111596 {__LINE__,
11597 nullptr,
asankae2257db2016-10-11 22:03:1611598 AUTH_NONE,
11599 OK,
11600 kServer,
11601 AUTH_SYNC,
11602 ERR_UNSUPPORTED_AUTH_SCHEME,
11603 2,
11604 kNoSSL,
11605 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111606 {__LINE__,
11607 nullptr,
asankae2257db2016-10-11 22:03:1611608 AUTH_NONE,
11609 OK,
11610 kServer,
11611 AUTH_SYNC,
11612 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11613 2,
11614 kNoSSL,
11615 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111616 {__LINE__,
11617 kProxy,
asankae2257db2016-10-11 22:03:1611618 AUTH_SYNC,
11619 ERR_FAILED,
11620 kServer,
11621 AUTH_NONE,
11622 OK,
11623 2,
11624 kNoSSL,
11625 {TestRound(kGetProxy, kProxyChallenge, OK),
11626 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111627 {__LINE__,
11628 kProxy,
asankae2257db2016-10-11 22:03:1611629 AUTH_ASYNC,
11630 ERR_FAILED,
11631 kServer,
11632 AUTH_NONE,
11633 OK,
11634 2,
11635 kNoSSL,
11636 {TestRound(kGetProxy, kProxyChallenge, OK),
11637 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111638 {__LINE__,
11639 nullptr,
asankae2257db2016-10-11 22:03:1611640 AUTH_NONE,
11641 OK,
11642 kServer,
11643 AUTH_SYNC,
11644 ERR_FAILED,
asankac93076192016-10-03 15:46:0211645 2,
11646 kNoSSL,
11647 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611648 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111649 {__LINE__,
11650 nullptr,
asankae2257db2016-10-11 22:03:1611651 AUTH_NONE,
11652 OK,
11653 kServer,
11654 AUTH_ASYNC,
11655 ERR_FAILED,
11656 2,
11657 kNoSSL,
11658 {TestRound(kGet, kServerChallenge, OK),
11659 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111660 {__LINE__,
11661 nullptr,
asankac93076192016-10-03 15:46:0211662 AUTH_NONE,
11663 OK,
11664 kServer,
11665 AUTH_ASYNC,
11666 OK,
11667 2,
11668 kNoSSL,
11669 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511670 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111671 {__LINE__,
11672 nullptr,
asankac93076192016-10-03 15:46:0211673 AUTH_NONE,
11674 OK,
11675 kServer,
11676 AUTH_ASYNC,
11677 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611678 3,
asankac93076192016-10-03 15:46:0211679 kNoSSL,
11680 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611681 // The second round uses a HttpAuthHandlerMock that always succeeds.
11682 TestRound(kGet, kServerChallenge, OK),
11683 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211684 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111685 {__LINE__,
11686 kProxy,
asankac93076192016-10-03 15:46:0211687 AUTH_NONE,
11688 OK,
11689 kServer,
11690 AUTH_NONE,
11691 OK,
11692 1,
11693 kNoSSL,
11694 {TestRound(kGetProxy, kSuccess, OK)}},
11695 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111696 {__LINE__,
11697 kProxy,
asankac93076192016-10-03 15:46:0211698 AUTH_NONE,
11699 OK,
11700 kServer,
11701 AUTH_SYNC,
11702 OK,
11703 2,
11704 kNoSSL,
11705 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511706 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111707 {__LINE__,
11708 kProxy,
asankac93076192016-10-03 15:46:0211709 AUTH_NONE,
11710 OK,
11711 kServer,
11712 AUTH_SYNC,
11713 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611714 3,
asankac93076192016-10-03 15:46:0211715 kNoSSL,
11716 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611717 TestRound(kGetProxy, kServerChallenge, OK),
11718 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111719 {__LINE__,
11720 kProxy,
asankac93076192016-10-03 15:46:0211721 AUTH_NONE,
11722 OK,
11723 kServer,
11724 AUTH_ASYNC,
11725 OK,
11726 2,
11727 kNoSSL,
11728 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511729 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111730 {__LINE__,
11731 kProxy,
asankac93076192016-10-03 15:46:0211732 AUTH_NONE,
11733 OK,
11734 kServer,
11735 AUTH_ASYNC,
11736 ERR_INVALID_AUTH_CREDENTIALS,
11737 2,
11738 kNoSSL,
11739 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611740 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211741 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111742 {__LINE__,
11743 kProxy,
asankac93076192016-10-03 15:46:0211744 AUTH_SYNC,
11745 OK,
11746 kServer,
11747 AUTH_NONE,
11748 OK,
11749 2,
11750 kNoSSL,
11751 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511752 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111753 {__LINE__,
11754 kProxy,
asankac93076192016-10-03 15:46:0211755 AUTH_SYNC,
11756 ERR_INVALID_AUTH_CREDENTIALS,
11757 kServer,
11758 AUTH_NONE,
11759 OK,
11760 2,
11761 kNoSSL,
11762 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611763 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111764 {__LINE__,
11765 kProxy,
asankac93076192016-10-03 15:46:0211766 AUTH_ASYNC,
11767 OK,
11768 kServer,
11769 AUTH_NONE,
11770 OK,
11771 2,
11772 kNoSSL,
11773 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511774 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111775 {__LINE__,
11776 kProxy,
asankac93076192016-10-03 15:46:0211777 AUTH_ASYNC,
11778 ERR_INVALID_AUTH_CREDENTIALS,
11779 kServer,
11780 AUTH_NONE,
11781 OK,
11782 2,
11783 kNoSSL,
11784 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1611785 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111786 {__LINE__,
11787 kProxy,
11788 AUTH_ASYNC,
11789 ERR_INVALID_AUTH_CREDENTIALS,
11790 kServer,
11791 AUTH_NONE,
11792 OK,
11793 3,
11794 kNoSSL,
11795 {TestRound(kGetProxy, kProxyChallenge, OK),
11796 TestRound(kGetProxy, kProxyChallenge, OK),
11797 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211798 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3111799 {__LINE__,
11800 kProxy,
asankac93076192016-10-03 15:46:0211801 AUTH_SYNC,
11802 OK,
11803 kServer,
11804 AUTH_SYNC,
11805 OK,
11806 3,
11807 kNoSSL,
11808 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511809 TestRound(kGetProxyAuth, kServerChallenge, OK),
11810 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111811 {__LINE__,
11812 kProxy,
asankac93076192016-10-03 15:46:0211813 AUTH_SYNC,
11814 OK,
11815 kServer,
11816 AUTH_SYNC,
11817 ERR_INVALID_AUTH_CREDENTIALS,
11818 3,
11819 kNoSSL,
11820 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511821 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611822 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111823 {__LINE__,
11824 kProxy,
asankac93076192016-10-03 15:46:0211825 AUTH_ASYNC,
11826 OK,
11827 kServer,
11828 AUTH_SYNC,
11829 OK,
11830 3,
11831 kNoSSL,
11832 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511833 TestRound(kGetProxyAuth, kServerChallenge, OK),
11834 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111835 {__LINE__,
11836 kProxy,
asankac93076192016-10-03 15:46:0211837 AUTH_ASYNC,
11838 OK,
11839 kServer,
11840 AUTH_SYNC,
11841 ERR_INVALID_AUTH_CREDENTIALS,
11842 3,
11843 kNoSSL,
11844 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511845 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611846 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111847 {__LINE__,
11848 kProxy,
asankac93076192016-10-03 15:46:0211849 AUTH_SYNC,
11850 OK,
11851 kServer,
11852 AUTH_ASYNC,
11853 OK,
11854 3,
11855 kNoSSL,
11856 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511857 TestRound(kGetProxyAuth, kServerChallenge, OK),
11858 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111859 {__LINE__,
11860 kProxy,
11861 AUTH_SYNC,
11862 ERR_INVALID_AUTH_CREDENTIALS,
11863 kServer,
11864 AUTH_ASYNC,
11865 OK,
11866 4,
11867 kNoSSL,
11868 {TestRound(kGetProxy, kProxyChallenge, OK),
11869 TestRound(kGetProxy, kProxyChallenge, OK),
11870 TestRound(kGetProxyAuth, kServerChallenge, OK),
11871 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11872 {__LINE__,
11873 kProxy,
asankac93076192016-10-03 15:46:0211874 AUTH_SYNC,
11875 OK,
11876 kServer,
11877 AUTH_ASYNC,
11878 ERR_INVALID_AUTH_CREDENTIALS,
11879 3,
11880 kNoSSL,
11881 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511882 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611883 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111884 {__LINE__,
11885 kProxy,
asankac93076192016-10-03 15:46:0211886 AUTH_ASYNC,
11887 OK,
11888 kServer,
11889 AUTH_ASYNC,
11890 OK,
11891 3,
11892 kNoSSL,
11893 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511894 TestRound(kGetProxyAuth, kServerChallenge, OK),
11895 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111896 {__LINE__,
11897 kProxy,
asankac93076192016-10-03 15:46:0211898 AUTH_ASYNC,
11899 OK,
11900 kServer,
11901 AUTH_ASYNC,
11902 ERR_INVALID_AUTH_CREDENTIALS,
11903 3,
11904 kNoSSL,
11905 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511906 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611907 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111908 {__LINE__,
11909 kProxy,
11910 AUTH_ASYNC,
11911 ERR_INVALID_AUTH_CREDENTIALS,
11912 kServer,
11913 AUTH_ASYNC,
11914 ERR_INVALID_AUTH_CREDENTIALS,
11915 4,
11916 kNoSSL,
11917 {TestRound(kGetProxy, kProxyChallenge, OK),
11918 TestRound(kGetProxy, kProxyChallenge, OK),
11919 TestRound(kGetProxyAuth, kServerChallenge, OK),
11920 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211921 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111922 {__LINE__,
11923 nullptr,
asankac93076192016-10-03 15:46:0211924 AUTH_NONE,
11925 OK,
11926 kSecureServer,
11927 AUTH_NONE,
11928 OK,
11929 1,
11930 0,
11931 {TestRound(kGet, kSuccess, OK)}},
11932 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3111933 {__LINE__,
11934 nullptr,
asankac93076192016-10-03 15:46:0211935 AUTH_NONE,
11936 OK,
11937 kSecureServer,
11938 AUTH_SYNC,
11939 OK,
11940 2,
11941 0,
11942 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511943 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111944 {__LINE__,
11945 nullptr,
asankac93076192016-10-03 15:46:0211946 AUTH_NONE,
11947 OK,
11948 kSecureServer,
11949 AUTH_SYNC,
11950 ERR_INVALID_AUTH_CREDENTIALS,
11951 2,
11952 0,
asankae2257db2016-10-11 22:03:1611953 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111954 {__LINE__,
11955 nullptr,
asankac93076192016-10-03 15:46:0211956 AUTH_NONE,
11957 OK,
11958 kSecureServer,
11959 AUTH_ASYNC,
11960 OK,
11961 2,
11962 0,
11963 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511964 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111965 {__LINE__,
11966 nullptr,
asankac93076192016-10-03 15:46:0211967 AUTH_NONE,
11968 OK,
11969 kSecureServer,
11970 AUTH_ASYNC,
11971 ERR_INVALID_AUTH_CREDENTIALS,
11972 2,
11973 0,
asankae2257db2016-10-11 22:03:1611974 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0211975 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111976 {__LINE__,
11977 kProxy,
asankac93076192016-10-03 15:46:0211978 AUTH_NONE,
11979 OK,
11980 kSecureServer,
11981 AUTH_NONE,
11982 OK,
11983 1,
11984 0,
11985 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11986 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3111987 {__LINE__,
11988 kProxy,
asankac93076192016-10-03 15:46:0211989 AUTH_NONE,
11990 OK,
11991 kSecureServer,
11992 AUTH_SYNC,
11993 OK,
11994 2,
11995 0,
11996 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1511997 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111998 {__LINE__,
11999 kProxy,
asankac93076192016-10-03 15:46:0212000 AUTH_NONE,
12001 OK,
12002 kSecureServer,
12003 AUTH_SYNC,
12004 ERR_INVALID_AUTH_CREDENTIALS,
12005 2,
12006 0,
12007 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612008 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112009 {__LINE__,
12010 kProxy,
asankac93076192016-10-03 15:46:0212011 AUTH_NONE,
12012 OK,
12013 kSecureServer,
12014 AUTH_ASYNC,
12015 OK,
12016 2,
12017 0,
12018 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512019 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112020 {__LINE__,
12021 kProxy,
asankac93076192016-10-03 15:46:0212022 AUTH_NONE,
12023 OK,
12024 kSecureServer,
12025 AUTH_ASYNC,
12026 ERR_INVALID_AUTH_CREDENTIALS,
12027 2,
12028 0,
12029 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612030 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212031 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112032 {__LINE__,
12033 kProxy,
asankac93076192016-10-03 15:46:0212034 AUTH_SYNC,
12035 OK,
12036 kSecureServer,
12037 AUTH_NONE,
12038 OK,
12039 2,
12040 1,
12041 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512042 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112043 {__LINE__,
12044 kProxy,
asankac93076192016-10-03 15:46:0212045 AUTH_SYNC,
12046 ERR_INVALID_AUTH_CREDENTIALS,
12047 kSecureServer,
12048 AUTH_NONE,
12049 OK,
12050 2,
12051 kNoSSL,
12052 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612053 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112054 {__LINE__,
12055 kProxy,
asankae2257db2016-10-11 22:03:1612056 AUTH_SYNC,
12057 ERR_UNSUPPORTED_AUTH_SCHEME,
12058 kSecureServer,
12059 AUTH_NONE,
12060 OK,
12061 2,
12062 kNoSSL,
12063 {TestRound(kConnect, kProxyChallenge, OK),
12064 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112065 {__LINE__,
12066 kProxy,
asankae2257db2016-10-11 22:03:1612067 AUTH_SYNC,
12068 ERR_UNEXPECTED,
12069 kSecureServer,
12070 AUTH_NONE,
12071 OK,
12072 2,
12073 kNoSSL,
12074 {TestRound(kConnect, kProxyChallenge, OK),
12075 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112076 {__LINE__,
12077 kProxy,
asankac93076192016-10-03 15:46:0212078 AUTH_ASYNC,
12079 OK,
12080 kSecureServer,
12081 AUTH_NONE,
12082 OK,
12083 2,
12084 1,
12085 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512086 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112087 {__LINE__,
12088 kProxy,
asankac93076192016-10-03 15:46:0212089 AUTH_ASYNC,
12090 ERR_INVALID_AUTH_CREDENTIALS,
12091 kSecureServer,
12092 AUTH_NONE,
12093 OK,
12094 2,
12095 kNoSSL,
12096 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612097 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212098 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112099 {__LINE__,
12100 kProxy,
asankac93076192016-10-03 15:46:0212101 AUTH_SYNC,
12102 OK,
12103 kSecureServer,
12104 AUTH_SYNC,
12105 OK,
12106 3,
12107 1,
12108 {TestRound(kConnect, kProxyChallenge, OK),
12109 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12110 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512111 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112112 {__LINE__,
12113 kProxy,
asankac93076192016-10-03 15:46:0212114 AUTH_SYNC,
12115 OK,
12116 kSecureServer,
12117 AUTH_SYNC,
12118 ERR_INVALID_AUTH_CREDENTIALS,
12119 3,
12120 1,
12121 {TestRound(kConnect, kProxyChallenge, OK),
12122 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12123 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612124 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112125 {__LINE__,
12126 kProxy,
asankac93076192016-10-03 15:46:0212127 AUTH_ASYNC,
12128 OK,
12129 kSecureServer,
12130 AUTH_SYNC,
12131 OK,
12132 3,
12133 1,
12134 {TestRound(kConnect, kProxyChallenge, OK),
12135 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12136 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512137 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112138 {__LINE__,
12139 kProxy,
asankac93076192016-10-03 15:46:0212140 AUTH_ASYNC,
12141 OK,
12142 kSecureServer,
12143 AUTH_SYNC,
12144 ERR_INVALID_AUTH_CREDENTIALS,
12145 3,
12146 1,
12147 {TestRound(kConnect, kProxyChallenge, OK),
12148 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12149 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612150 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112151 {__LINE__,
12152 kProxy,
asankac93076192016-10-03 15:46:0212153 AUTH_SYNC,
12154 OK,
12155 kSecureServer,
12156 AUTH_ASYNC,
12157 OK,
12158 3,
12159 1,
12160 {TestRound(kConnect, kProxyChallenge, OK),
12161 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12162 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512163 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112164 {__LINE__,
12165 kProxy,
asankac93076192016-10-03 15:46:0212166 AUTH_SYNC,
12167 OK,
12168 kSecureServer,
12169 AUTH_ASYNC,
12170 ERR_INVALID_AUTH_CREDENTIALS,
12171 3,
12172 1,
12173 {TestRound(kConnect, kProxyChallenge, OK),
12174 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12175 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612176 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112177 {__LINE__,
12178 kProxy,
asankac93076192016-10-03 15:46:0212179 AUTH_ASYNC,
12180 OK,
12181 kSecureServer,
12182 AUTH_ASYNC,
12183 OK,
12184 3,
12185 1,
12186 {TestRound(kConnect, kProxyChallenge, OK),
12187 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12188 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512189 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112190 {__LINE__,
12191 kProxy,
asankac93076192016-10-03 15:46:0212192 AUTH_ASYNC,
12193 OK,
12194 kSecureServer,
12195 AUTH_ASYNC,
12196 ERR_INVALID_AUTH_CREDENTIALS,
12197 3,
12198 1,
12199 {TestRound(kConnect, kProxyChallenge, OK),
12200 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12201 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612202 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112203 {__LINE__,
12204 kProxy,
12205 AUTH_ASYNC,
12206 ERR_INVALID_AUTH_CREDENTIALS,
12207 kSecureServer,
12208 AUTH_ASYNC,
12209 ERR_INVALID_AUTH_CREDENTIALS,
12210 4,
12211 2,
12212 {TestRound(kConnect, kProxyChallenge, OK),
12213 TestRound(kConnect, kProxyChallenge, OK),
12214 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12215 &kServerChallenge),
12216 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512217 };
12218
asanka463ca4262016-11-16 02:34:3112219 for (const auto& test_config : test_configs) {
12220 SCOPED_TRACE(::testing::Message() << "Test config at "
12221 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812222 HttpAuthHandlerMock::Factory* auth_factory(
12223 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712224 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912225 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612226
12227 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512228 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112229 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812230 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12231 std::string auth_challenge = "Mock realm=proxy";
12232 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412233 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12234 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812235 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012236 empty_ssl_info, origin,
12237 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812238 auth_handler->SetGenerateExpectation(
12239 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112240 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812241 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12242 }
[email protected]044de0642010-06-17 10:42:1512243 }
12244 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012245 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512246 std::string auth_challenge = "Mock realm=server";
12247 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412248 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12249 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512250 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012251 empty_ssl_info, origin,
12252 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512253 auth_handler->SetGenerateExpectation(
12254 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112255 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812256 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612257
12258 // The second handler always succeeds. It should only be used where there
12259 // are multiple auth sessions for server auth in the same network
12260 // transaction using the same auth scheme.
12261 std::unique_ptr<HttpAuthHandlerMock> second_handler =
12262 base::MakeUnique<HttpAuthHandlerMock>();
12263 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12264 empty_ssl_info, origin,
12265 NetLogWithSource());
12266 second_handler->SetGenerateExpectation(true, OK);
12267 auth_factory->AddMockHandler(second_handler.release(),
12268 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512269 }
12270 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312271 session_deps_.proxy_service =
12272 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512273 } else {
rdsmith82957ad2015-09-16 19:42:0312274 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512275 }
12276
12277 HttpRequestInfo request;
12278 request.method = "GET";
12279 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512280
danakj1fd259a02016-04-16 03:17:0912281 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512282
rchcb68dc62015-05-21 04:45:3612283 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12284
12285 std::vector<std::vector<MockRead>> mock_reads(1);
12286 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512287 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
12288 const TestRound& read_write_round = test_config.rounds[round];
12289
12290 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612291 mock_reads.back().push_back(read_write_round.read);
12292 mock_writes.back().push_back(read_write_round.write);
12293
12294 // kProxyChallenge uses Proxy-Connection: close which means that the
12295 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412296 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612297 mock_reads.push_back(std::vector<MockRead>());
12298 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512299 }
12300
rchcb68dc62015-05-21 04:45:3612301 if (read_write_round.extra_read) {
12302 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512303 }
rchcb68dc62015-05-21 04:45:3612304 if (read_write_round.extra_write) {
12305 mock_writes.back().push_back(*read_write_round.extra_write);
12306 }
[email protected]044de0642010-06-17 10:42:1512307
12308 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512309 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712310 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512311 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612312 }
[email protected]044de0642010-06-17 10:42:1512313
danakj1fd259a02016-04-16 03:17:0912314 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612315 for (size_t i = 0; i < mock_reads.size(); ++i) {
danakj1fd259a02016-04-16 03:17:0912316 data_providers.push_back(base::WrapUnique(new StaticSocketDataProvider(
davidben5f8b6bc2015-11-25 03:19:5412317 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
olli.raula525048c2015-12-10 07:38:3212318 mock_writes[i].size())));
rchcb68dc62015-05-21 04:45:3612319 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212320 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612321 }
12322
mmenkecc2298e2015-12-07 18:20:1812323 // Transaction must be created after DataProviders, so it's destroyed before
12324 // they are as well.
12325 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12326
rchcb68dc62015-05-21 04:45:3612327 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
12328 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512329 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112330 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512331 int rv;
12332 if (round == 0) {
tfarina42834112016-09-22 13:38:2012333 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512334 } else {
[email protected]49639fa2011-12-20 23:22:4112335 rv = trans.RestartWithAuth(
12336 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512337 }
12338 if (rv == ERR_IO_PENDING)
12339 rv = callback.WaitForResult();
12340
12341 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612342 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012343 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512344 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512345 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12346 continue;
12347 }
12348 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212349 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512350 } else {
wezca1070932016-05-26 20:30:5212351 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612352 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512353 }
12354 }
[email protected]e5ae96a2010-04-14 20:12:4512355 }
12356}
12357
bncd16676a2016-07-20 16:23:0112358TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412359 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412360 HttpAuthHandlerMock::Factory* auth_factory(
12361 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712362 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312363 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712364 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12365 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412366
12367 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12368 auth_handler->set_connection_based(true);
12369 std::string auth_challenge = "Mock realm=server";
12370 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412371 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12372 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912373 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412374 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012375 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812376 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412377
[email protected]c871bce92010-07-15 21:51:1412378 int rv = OK;
12379 const HttpResponseInfo* response = NULL;
12380 HttpRequestInfo request;
12381 request.method = "GET";
12382 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712383
danakj1fd259a02016-04-16 03:17:0912384 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012385
12386 // Use a TCP Socket Pool with only one connection per group. This is used
12387 // to validate that the TCP socket is not released to the pool between
12388 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212389 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812390 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012391 50, // Max sockets for pool
12392 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112393 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12394 NULL, session_deps_.net_log);
danakj1fd259a02016-04-16 03:17:0912395 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:4412396 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0212397 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812398 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012399
bnc691fda62016-08-12 00:43:1612400 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112401 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412402
12403 const MockWrite kGet(
12404 "GET / HTTP/1.1\r\n"
12405 "Host: www.example.com\r\n"
12406 "Connection: keep-alive\r\n\r\n");
12407 const MockWrite kGetAuth(
12408 "GET / HTTP/1.1\r\n"
12409 "Host: www.example.com\r\n"
12410 "Connection: keep-alive\r\n"
12411 "Authorization: auth_token\r\n\r\n");
12412
12413 const MockRead kServerChallenge(
12414 "HTTP/1.1 401 Unauthorized\r\n"
12415 "WWW-Authenticate: Mock realm=server\r\n"
12416 "Content-Type: text/html; charset=iso-8859-1\r\n"
12417 "Content-Length: 14\r\n\r\n"
12418 "Unauthorized\r\n");
12419 const MockRead kSuccess(
12420 "HTTP/1.1 200 OK\r\n"
12421 "Content-Type: text/html; charset=iso-8859-1\r\n"
12422 "Content-Length: 3\r\n\r\n"
12423 "Yes");
12424
12425 MockWrite writes[] = {
12426 // First round
12427 kGet,
12428 // Second round
12429 kGetAuth,
12430 // Third round
12431 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012432 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012433 kGetAuth,
12434 // Competing request
12435 kGet,
[email protected]c871bce92010-07-15 21:51:1412436 };
12437 MockRead reads[] = {
12438 // First round
12439 kServerChallenge,
12440 // Second round
12441 kServerChallenge,
12442 // Third round
[email protected]eca50e122010-09-11 14:03:3012443 kServerChallenge,
12444 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412445 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012446 // Competing response
12447 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412448 };
12449 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12450 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712451 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412452
thestig9d3bb0c2015-01-24 00:49:5112453 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012454
12455 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412456 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012457 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412458 if (rv == ERR_IO_PENDING)
12459 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112460 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612461 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212462 ASSERT_TRUE(response);
12463 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812464 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112465 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12466 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412467
[email protected]7ef4cbbb2011-02-06 11:19:1012468 // In between rounds, another request comes in for the same domain.
12469 // It should not be able to grab the TCP socket that trans has already
12470 // claimed.
bnc691fda62016-08-12 00:43:1612471 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112472 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012473 rv = trans_compete.Start(&request, callback_compete.callback(),
12474 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012476 // callback_compete.WaitForResult at this point would stall forever,
12477 // since the HttpNetworkTransaction does not release the request back to
12478 // the pool until after authentication completes.
12479
12480 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412481 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612482 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412483 if (rv == ERR_IO_PENDING)
12484 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112485 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612486 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212487 ASSERT_TRUE(response);
12488 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812489 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112490 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12491 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412492
[email protected]7ef4cbbb2011-02-06 11:19:1012493 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412494 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612495 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412496 if (rv == ERR_IO_PENDING)
12497 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112498 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612499 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212500 ASSERT_TRUE(response);
12501 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812502 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112503 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12504 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012505
[email protected]7ef4cbbb2011-02-06 11:19:1012506 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012507 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612508 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012509 if (rv == ERR_IO_PENDING)
12510 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112511 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612512 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212513 ASSERT_TRUE(response);
12514 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812515 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012516
asanka463ca4262016-11-16 02:34:3112517 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12518 // auth handler should transition to a DONE state in concert with the remote
12519 // server. But that's not something we can test here with a mock handler.
12520 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12521 auth_handler->state());
12522
[email protected]7ef4cbbb2011-02-06 11:19:1012523 // Read the body since the fourth round was successful. This will also
12524 // release the socket back to the pool.
12525 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612526 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012527 if (rv == ERR_IO_PENDING)
12528 rv = callback.WaitForResult();
12529 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612530 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012531 EXPECT_EQ(0, rv);
12532 // There are still 0 idle sockets, since the trans_compete transaction
12533 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812534 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012535
12536 // The competing request can now finish. Wait for the headers and then
12537 // read the body.
12538 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112539 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612540 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012541 if (rv == ERR_IO_PENDING)
12542 rv = callback.WaitForResult();
12543 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612544 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012545 EXPECT_EQ(0, rv);
12546
12547 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812548 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412549}
12550
[email protected]65041fa2010-05-21 06:56:5312551// This tests the case that a request is issued via http instead of spdy after
12552// npn is negotiated.
bncd16676a2016-07-20 16:23:0112553TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312554 HttpRequestInfo request;
12555 request.method = "GET";
bncce36dca22015-04-21 22:11:2312556 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312557
12558 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312559 MockWrite(
12560 "GET / HTTP/1.1\r\n"
12561 "Host: www.example.org\r\n"
12562 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312563 };
12564
12565 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212566 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312567 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212568 MockRead("\r\n"),
12569 MockRead("hello world"),
12570 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312571 };
12572
[email protected]8ddf8322012-02-23 18:08:0612573 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612574 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312575
[email protected]bb88e1d32013-05-03 23:11:0712576 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312577
12578 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12579 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712580 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312581
[email protected]49639fa2011-12-20 23:22:4112582 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312583
danakj1fd259a02016-04-16 03:17:0912584 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612585 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312586
tfarina42834112016-09-22 13:38:2012587 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312588
robpercival214763f2016-07-01 23:27:0112589 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12590 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312591
bnc691fda62016-08-12 00:43:1612592 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212593 ASSERT_TRUE(response);
12594 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312595 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12596
12597 std::string response_data;
bnc691fda62016-08-12 00:43:1612598 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312599 EXPECT_EQ("hello world", response_data);
12600
12601 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212602 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312603}
[email protected]26ef6582010-06-24 02:30:4712604
bnc55ff9da2015-08-19 18:42:3512605// Simulate the SSL handshake completing with an NPN negotiation followed by an
12606// immediate server closing of the socket.
12607// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112608TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712609 HttpRequestInfo request;
12610 request.method = "GET";
bncce36dca22015-04-21 22:11:2312611 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712612
[email protected]8ddf8322012-02-23 18:08:0612613 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612614 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712615 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712616
bncdf80d44fd2016-07-15 20:27:4112617 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912618 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112619 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712620
12621 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612622 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712623 };
12624
rch8e6c6c42015-05-01 14:05:1312625 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12626 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712627 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712628
[email protected]49639fa2011-12-20 23:22:4112629 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712630
danakj1fd259a02016-04-16 03:17:0912631 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612632 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712633
tfarina42834112016-09-22 13:38:2012634 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12636 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712637}
[email protected]65d34382010-07-01 18:12:2612638
[email protected]795cbf82013-07-22 09:37:2712639// A subclass of HttpAuthHandlerMock that records the request URL when
12640// it gets it. This is needed since the auth handler may get destroyed
12641// before we get a chance to query it.
12642class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12643 public:
12644 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12645
dchengb03027d2014-10-21 12:00:2012646 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712647
12648 protected:
dchengb03027d2014-10-21 12:00:2012649 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12650 const HttpRequestInfo* request,
12651 const CompletionCallback& callback,
12652 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712653 *url_ = request->url;
12654 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12655 credentials, request, callback, auth_token);
12656 }
12657
12658 private:
12659 GURL* url_;
12660};
12661
[email protected]8e6441ca2010-08-19 05:56:3812662// Test that if we cancel the transaction as the connection is completing, that
12663// everything tears down correctly.
bncd16676a2016-07-20 16:23:0112664TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812665 // Setup everything about the connection to complete synchronously, so that
12666 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12667 // for is the callback from the HttpStreamRequest.
12668 // Then cancel the transaction.
12669 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612670 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812671 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612672 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12673 MockRead(SYNCHRONOUS, "hello world"),
12674 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812675 };
12676
[email protected]8e6441ca2010-08-19 05:56:3812677 HttpRequestInfo request;
12678 request.method = "GET";
bncce36dca22015-04-21 22:11:2312679 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812680
[email protected]bb88e1d32013-05-03 23:11:0712681 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912682 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612683 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112684 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2712685
[email protected]8e6441ca2010-08-19 05:56:3812686 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12687 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712688 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812689
[email protected]49639fa2011-12-20 23:22:4112690 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812691
vishal.b62985ca92015-04-17 08:45:5112692 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112693 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112694 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3812695 trans.reset(); // Cancel the transaction here.
12696
fdoray92e35a72016-06-10 15:54:5512697 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012698}
12699
[email protected]ecab6e052014-05-16 14:58:1212700// Test that if a transaction is cancelled after receiving the headers, the
12701// stream is drained properly and added back to the socket pool. The main
12702// purpose of this test is to make sure that an HttpStreamParser can be read
12703// from after the HttpNetworkTransaction and the objects it owns have been
12704// deleted.
12705// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0112706TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1212707 MockRead data_reads[] = {
12708 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12709 MockRead(ASYNC, "Content-Length: 2\r\n"),
12710 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12711 MockRead(ASYNC, "1"),
12712 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12713 // HttpNetworkTransaction has been deleted.
12714 MockRead(ASYNC, "2"),
12715 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12716 };
12717 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12718 session_deps_.socket_factory->AddSocketDataProvider(&data);
12719
danakj1fd259a02016-04-16 03:17:0912720 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212721
12722 {
12723 HttpRequestInfo request;
12724 request.method = "GET";
bncce36dca22015-04-21 22:11:2312725 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212726
dcheng48459ac22014-08-26 00:46:4112727 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212728 TestCompletionCallback callback;
12729
tfarina42834112016-09-22 13:38:2012730 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112731 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1212732 callback.WaitForResult();
12733
12734 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212735 ASSERT_TRUE(response);
12736 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212737 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12738
12739 // The transaction and HttpRequestInfo are deleted.
12740 }
12741
12742 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512743 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212744
12745 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112746 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212747}
12748
[email protected]76a505b2010-08-25 06:23:0012749// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0112750TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312751 session_deps_.proxy_service =
12752 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112753 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712754 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012756
[email protected]76a505b2010-08-25 06:23:0012757 HttpRequestInfo request;
12758 request.method = "GET";
bncce36dca22015-04-21 22:11:2312759 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012760
12761 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312762 MockWrite(
12763 "GET http://www.example.org/ HTTP/1.1\r\n"
12764 "Host: www.example.org\r\n"
12765 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012766 };
12767
12768 MockRead data_reads1[] = {
12769 MockRead("HTTP/1.1 200 OK\r\n"),
12770 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12771 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612772 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012773 };
12774
12775 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12776 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712777 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012778
[email protected]49639fa2011-12-20 23:22:4112779 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012780
bnc691fda62016-08-12 00:43:1612781 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912782 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612783 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912784 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12785 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012786
bnc691fda62016-08-12 00:43:1612787 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112788 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012789
12790 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112791 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0012792
bnc691fda62016-08-12 00:43:1612793 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212794 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012795
12796 EXPECT_TRUE(response->headers->IsKeepAlive());
12797 EXPECT_EQ(200, response->headers->response_code());
12798 EXPECT_EQ(100, response->headers->GetContentLength());
12799 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712800 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12801 HostPortPair::FromString("myproxy:70")),
12802 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912803 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12804 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12805 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012806 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012807
12808 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612809 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012810 TestLoadTimingNotReusedWithPac(load_timing_info,
12811 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012812}
12813
12814// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0112815TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312816 session_deps_.proxy_service =
12817 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112818 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712819 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912820 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012821
[email protected]76a505b2010-08-25 06:23:0012822 HttpRequestInfo request;
12823 request.method = "GET";
bncce36dca22015-04-21 22:11:2312824 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012825
12826 // Since we have proxy, should try to establish tunnel.
12827 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712828 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12829 "Host: www.example.org:443\r\n"
12830 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012831
rsleevidb16bb02015-11-12 23:47:1712832 MockWrite("GET / HTTP/1.1\r\n"
12833 "Host: www.example.org\r\n"
12834 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012835 };
12836
12837 MockRead data_reads1[] = {
12838 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12839
12840 MockRead("HTTP/1.1 200 OK\r\n"),
12841 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12842 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612843 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012844 };
12845
12846 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12847 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712848 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612849 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712850 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012851
[email protected]49639fa2011-12-20 23:22:4112852 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012853
bnc691fda62016-08-12 00:43:1612854 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0912855 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1612856 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0912857 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12858 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012859
bnc691fda62016-08-12 00:43:1612860 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112861 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0012862
12863 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112864 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4612865 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012866 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012867 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012868 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12869 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012870 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012871 entries, pos,
mikecirone8b85c432016-09-08 19:11:0012872 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12873 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0012874
bnc691fda62016-08-12 00:43:1612875 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212876 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012877
12878 EXPECT_TRUE(response->headers->IsKeepAlive());
12879 EXPECT_EQ(200, response->headers->response_code());
12880 EXPECT_EQ(100, response->headers->GetContentLength());
12881 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12882 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712883 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12884 HostPortPair::FromString("myproxy:70")),
12885 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0912886 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12887 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12888 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012889
12890 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612891 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2012892 TestLoadTimingNotReusedWithPac(load_timing_info,
12893 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012894}
12895
rsleevidb16bb02015-11-12 23:47:1712896// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12897// literal host.
bncd16676a2016-07-20 16:23:0112898TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1712899 session_deps_.proxy_service =
12900 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12901 BoundTestNetLog log;
12902 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912903 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712904
12905 HttpRequestInfo request;
12906 request.method = "GET";
12907 request.url = GURL("https://[::1]:443/");
12908
12909 // Since we have proxy, should try to establish tunnel.
12910 MockWrite data_writes1[] = {
12911 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12912 "Host: [::1]:443\r\n"
12913 "Proxy-Connection: keep-alive\r\n\r\n"),
12914
12915 MockWrite("GET / HTTP/1.1\r\n"
12916 "Host: [::1]\r\n"
12917 "Connection: keep-alive\r\n\r\n"),
12918 };
12919
12920 MockRead data_reads1[] = {
12921 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12922
12923 MockRead("HTTP/1.1 200 OK\r\n"),
12924 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12925 MockRead("Content-Length: 100\r\n\r\n"),
12926 MockRead(SYNCHRONOUS, OK),
12927 };
12928
12929 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12930 data_writes1, arraysize(data_writes1));
12931 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12932 SSLSocketDataProvider ssl(ASYNC, OK);
12933 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12934
12935 TestCompletionCallback callback1;
12936
bnc691fda62016-08-12 00:43:1612937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1712938
bnc691fda62016-08-12 00:43:1612939 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0112940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1712941
12942 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0112943 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1712944 TestNetLogEntry::List entries;
12945 log.GetEntries(&entries);
12946 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012947 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12948 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712949 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0012950 entries, pos,
12951 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12952 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1712953
bnc691fda62016-08-12 00:43:1612954 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212955 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712956
12957 EXPECT_TRUE(response->headers->IsKeepAlive());
12958 EXPECT_EQ(200, response->headers->response_code());
12959 EXPECT_EQ(100, response->headers->GetContentLength());
12960 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12961 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4712962 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
12963 HostPortPair::FromString("myproxy:70")),
12964 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1712965
12966 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1612967 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1712968 TestLoadTimingNotReusedWithPac(load_timing_info,
12969 CONNECT_TIMING_HAS_SSL_TIMES);
12970}
12971
[email protected]76a505b2010-08-25 06:23:0012972// Test a basic HTTPS GET request through a proxy, but the server hangs up
12973// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0112974TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312975 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112976 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712977 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912978 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012979
[email protected]76a505b2010-08-25 06:23:0012980 HttpRequestInfo request;
12981 request.method = "GET";
bncce36dca22015-04-21 22:11:2312982 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012983
12984 // Since we have proxy, should try to establish tunnel.
12985 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712986 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12987 "Host: www.example.org:443\r\n"
12988 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012989
rsleevidb16bb02015-11-12 23:47:1712990 MockWrite("GET / HTTP/1.1\r\n"
12991 "Host: www.example.org\r\n"
12992 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012993 };
12994
12995 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0612996 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0012997 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612998 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0012999 };
13000
13001 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13002 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713003 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613004 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713005 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013006
[email protected]49639fa2011-12-20 23:22:4113007 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013008
bnc691fda62016-08-12 00:43:1613009 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013010
bnc691fda62016-08-12 00:43:1613011 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013013
13014 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113015 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613016 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013017 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013018 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013019 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13020 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013021 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013022 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013023 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13024 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013025}
13026
[email protected]749eefa82010-09-13 22:14:0313027// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113028TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113029 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913030 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113031 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313032
bnc42331402016-07-25 13:36:1513033 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113034 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313035 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113036 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313037 };
13038
rch8e6c6c42015-05-01 14:05:1313039 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13040 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713041 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313042
[email protected]8ddf8322012-02-23 18:08:0613043 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613044 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713045 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313046
danakj1fd259a02016-04-16 03:17:0913047 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313048
13049 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313050 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013051 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313052 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713053 base::WeakPtr<SpdySession> spdy_session =
bnc032658ba2016-09-26 18:17:1513054 CreateSecureSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313055
13056 HttpRequestInfo request;
13057 request.method = "GET";
bncce36dca22015-04-21 22:11:2313058 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313059
13060 // This is the important line that marks this as a preconnect.
13061 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13062
bnc691fda62016-08-12 00:43:1613063 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313064
[email protected]41d64e82013-07-03 22:44:2613065 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013066 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13068 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313069}
13070
[email protected]73b8dd222010-11-11 19:55:2413071// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613072// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213073void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713074 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913075 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713076 request_info.url = GURL("https://www.example.com/");
13077 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913078 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713079
[email protected]8ddf8322012-02-23 18:08:0613080 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913081 MockWrite data_writes[] = {
13082 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413083 };
ttuttle859dc7a2015-04-23 19:42:2913084 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713085 session_deps_.socket_factory->AddSocketDataProvider(&data);
13086 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413087
danakj1fd259a02016-04-16 03:17:0913088 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613089 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413090
[email protected]49639fa2011-12-20 23:22:4113091 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013092 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913093 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413094 rv = callback.WaitForResult();
13095 ASSERT_EQ(error, rv);
13096}
13097
bncd16676a2016-07-20 16:23:0113098TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413099 // Just check a grab bag of cert errors.
13100 static const int kErrors[] = {
13101 ERR_CERT_COMMON_NAME_INVALID,
13102 ERR_CERT_AUTHORITY_INVALID,
13103 ERR_CERT_DATE_INVALID,
13104 };
13105 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613106 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13107 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413108 }
13109}
13110
[email protected]bd0b6772011-01-11 19:59:3013111// Ensure that a client certificate is removed from the SSL client auth
13112// cache when:
13113// 1) No proxy is involved.
13114// 2) TLS False Start is disabled.
13115// 3) The initial TLS handshake requests a client certificate.
13116// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113117TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913118 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713119 request_info.url = GURL("https://www.example.com/");
13120 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913121 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713122
[email protected]bd0b6772011-01-11 19:59:3013123 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113124 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013125
13126 // [ssl_]data1 contains the data for the first SSL handshake. When a
13127 // CertificateRequest is received for the first time, the handshake will
13128 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913129 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013130 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713131 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913132 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713133 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013134
13135 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13136 // False Start is not being used, the result of the SSL handshake will be
13137 // returned as part of the SSLClientSocket::Connect() call. This test
13138 // matches the result of a server sending a handshake_failure alert,
13139 // rather than a Finished message, because it requires a client
13140 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913141 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013142 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713143 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913144 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713145 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013146
13147 // [ssl_]data3 contains the data for the third SSL handshake. When a
13148 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213149 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13150 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013151 // of the HttpNetworkTransaction. Because this test failure is due to
13152 // requiring a client certificate, this fallback handshake should also
13153 // fail.
ttuttle859dc7a2015-04-23 19:42:2913154 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013155 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713156 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913157 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713158 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013159
[email protected]80c75f682012-05-26 16:22:1713160 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13161 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213162 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13163 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713164 // of the HttpNetworkTransaction. Because this test failure is due to
13165 // requiring a client certificate, this fallback handshake should also
13166 // fail.
ttuttle859dc7a2015-04-23 19:42:2913167 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713168 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713169 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913170 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713171 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713172
danakj1fd259a02016-04-16 03:17:0913173 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613174 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013175
[email protected]bd0b6772011-01-11 19:59:3013176 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113177 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013178 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113179 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013180
13181 // Complete the SSL handshake, which should abort due to requiring a
13182 // client certificate.
13183 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113184 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013185
13186 // Indicate that no certificate should be supplied. From the perspective
13187 // of SSLClientCertCache, NULL is just as meaningful as a real
13188 // certificate, so this is the same as supply a
13189 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613190 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113191 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013192
13193 // Ensure the certificate was added to the client auth cache before
13194 // allowing the connection to continue restarting.
13195 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413196 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113197 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413198 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213199 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013200
13201 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713202 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13203 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013204 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113205 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013206
13207 // Ensure that the client certificate is removed from the cache on a
13208 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113209 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413210 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013211}
13212
13213// Ensure that a client certificate is removed from the SSL client auth
13214// cache when:
13215// 1) No proxy is involved.
13216// 2) TLS False Start is enabled.
13217// 3) The initial TLS handshake requests a client certificate.
13218// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113219TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913220 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713221 request_info.url = GURL("https://www.example.com/");
13222 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913223 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713224
[email protected]bd0b6772011-01-11 19:59:3013225 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113226 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013227
13228 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13229 // return successfully after reading up to the peer's Certificate message.
13230 // This is to allow the caller to call SSLClientSocket::Write(), which can
13231 // enqueue application data to be sent in the same packet as the
13232 // ChangeCipherSpec and Finished messages.
13233 // The actual handshake will be finished when SSLClientSocket::Read() is
13234 // called, which expects to process the peer's ChangeCipherSpec and
13235 // Finished messages. If there was an error negotiating with the peer,
13236 // such as due to the peer requiring a client certificate when none was
13237 // supplied, the alert sent by the peer won't be processed until Read() is
13238 // called.
13239
13240 // Like the non-False Start case, when a client certificate is requested by
13241 // the peer, the handshake is aborted during the Connect() call.
13242 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913243 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013244 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713245 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913246 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713247 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013248
13249 // When a client certificate is supplied, Connect() will not be aborted
13250 // when the peer requests the certificate. Instead, the handshake will
13251 // artificially succeed, allowing the caller to write the HTTP request to
13252 // the socket. The handshake messages are not processed until Read() is
13253 // called, which then detects that the handshake was aborted, due to the
13254 // peer sending a handshake_failure because it requires a client
13255 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913256 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013257 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713258 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913259 MockRead data2_reads[] = {
13260 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013261 };
ttuttle859dc7a2015-04-23 19:42:2913262 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713263 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013264
13265 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713266 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13267 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913268 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013269 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713270 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913271 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713272 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013273
[email protected]80c75f682012-05-26 16:22:1713274 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13275 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913276 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713277 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713278 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913279 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713280 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713281
[email protected]7799de12013-05-30 05:52:5113282 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913283 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113284 ssl_data5.cert_request_info = cert_request.get();
13285 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913286 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113287 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13288
danakj1fd259a02016-04-16 03:17:0913289 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613290 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013291
[email protected]bd0b6772011-01-11 19:59:3013292 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113293 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013294 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113295 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013296
13297 // Complete the SSL handshake, which should abort due to requiring a
13298 // client certificate.
13299 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113300 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013301
13302 // Indicate that no certificate should be supplied. From the perspective
13303 // of SSLClientCertCache, NULL is just as meaningful as a real
13304 // certificate, so this is the same as supply a
13305 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613306 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113307 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013308
13309 // Ensure the certificate was added to the client auth cache before
13310 // allowing the connection to continue restarting.
13311 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413312 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113313 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413314 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213315 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013316
[email protected]bd0b6772011-01-11 19:59:3013317 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713318 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13319 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013320 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113321 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013322
13323 // Ensure that the client certificate is removed from the cache on a
13324 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113325 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413326 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013327}
13328
[email protected]8c405132011-01-11 22:03:1813329// Ensure that a client certificate is removed from the SSL client auth
13330// cache when:
13331// 1) An HTTPS proxy is involved.
13332// 3) The HTTPS proxy requests a client certificate.
13333// 4) The client supplies an invalid/unacceptable certificate for the
13334// proxy.
13335// The test is repeated twice, first for connecting to an HTTPS endpoint,
13336// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113337TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313338 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113339 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713340 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813341
13342 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113343 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813344
13345 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13346 // [ssl_]data[1-3]. Rather than represending the endpoint
13347 // (www.example.com:443), they represent failures with the HTTPS proxy
13348 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913349 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813350 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713351 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913352 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713353 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813354
ttuttle859dc7a2015-04-23 19:42:2913355 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813356 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713357 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913358 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713359 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813360
[email protected]80c75f682012-05-26 16:22:1713361 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13362#if 0
ttuttle859dc7a2015-04-23 19:42:2913363 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813364 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713365 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913366 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713367 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713368#endif
[email protected]8c405132011-01-11 22:03:1813369
ttuttle859dc7a2015-04-23 19:42:2913370 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813371 requests[0].url = GURL("https://www.example.com/");
13372 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913373 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813374
13375 requests[1].url = GURL("http://www.example.com/");
13376 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913377 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813378
13379 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713380 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913381 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613382 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813383
13384 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113385 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013386 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113387 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813388
13389 // Complete the SSL handshake, which should abort due to requiring a
13390 // client certificate.
13391 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113392 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813393
13394 // Indicate that no certificate should be supplied. From the perspective
13395 // of SSLClientCertCache, NULL is just as meaningful as a real
13396 // certificate, so this is the same as supply a
13397 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613398 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113399 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813400
13401 // Ensure the certificate was added to the client auth cache before
13402 // allowing the connection to continue restarting.
13403 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413404 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113405 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413406 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213407 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813408 // Ensure the certificate was NOT cached for the endpoint. This only
13409 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113410 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413411 HostPortPair("www.example.com", 443), &client_cert,
13412 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813413
13414 // Restart the handshake. This will consume ssl_data2, which fails, and
13415 // then consume ssl_data3, which should also fail. The result code is
13416 // checked against what ssl_data3 should return.
13417 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113418 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813419
13420 // Now that the new handshake has failed, ensure that the client
13421 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113422 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413423 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113424 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413425 HostPortPair("www.example.com", 443), &client_cert,
13426 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813427 }
13428}
13429
bncd16676a2016-07-20 16:23:0113430TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613431 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713432 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913433 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613434
bnc032658ba2016-09-26 18:17:1513435 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613436
bncdf80d44fd2016-07-15 20:27:4113437 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913438 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813439 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113440 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713441 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613442 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113443 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613444 };
bnc42331402016-07-25 13:36:1513445 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113446 SpdySerializedFrame host1_resp_body(
13447 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513448 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113449 SpdySerializedFrame host2_resp_body(
13450 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613451 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113452 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13453 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313454 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613455 };
13456
eroman36d84e54432016-03-17 03:23:0213457 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213458 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313459 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13460 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713461 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613462
[email protected]aa22b242011-11-16 18:58:2913463 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613464 HttpRequestInfo request1;
13465 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313466 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613467 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013468 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613469
tfarina42834112016-09-22 13:38:2013470 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113471 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13472 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613473
13474 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213475 ASSERT_TRUE(response);
13476 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213477 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613478
13479 std::string response_data;
robpercival214763f2016-07-01 23:27:0113480 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613481 EXPECT_EQ("hello!", response_data);
13482
bnca4d611d2016-09-22 19:55:3713483 // Preload mail.example.com into HostCache.
13484 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013485 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613486 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013487 std::unique_ptr<HostResolver::Request> request;
13488 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13489 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013490 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713492 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113493 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613494
13495 HttpRequestInfo request2;
13496 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713497 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613498 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013499 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613500
tfarina42834112016-09-22 13:38:2013501 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113502 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13503 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613504
13505 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213506 ASSERT_TRUE(response);
13507 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213508 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613509 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213510 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113511 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613512 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613513}
13514
bncd16676a2016-07-20 16:23:0113515TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213516 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713517 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913518 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213519
bnc032658ba2016-09-26 18:17:1513520 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213521
bncdf80d44fd2016-07-15 20:27:4113522 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913523 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813524 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113525 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713526 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213527 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113528 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213529 };
bnc42331402016-07-25 13:36:1513530 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113531 SpdySerializedFrame host1_resp_body(
13532 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513533 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113534 SpdySerializedFrame host2_resp_body(
13535 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213536 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113537 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13538 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313539 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213540 };
13541
eroman36d84e54432016-03-17 03:23:0213542 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213543 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313544 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13545 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713546 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213547
13548 TestCompletionCallback callback;
13549 HttpRequestInfo request1;
13550 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313551 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213552 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013553 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213554
tfarina42834112016-09-22 13:38:2013555 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113556 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13557 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213558
13559 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213560 ASSERT_TRUE(response);
13561 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213562 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213563
13564 std::string response_data;
robpercival214763f2016-07-01 23:27:0113565 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213566 EXPECT_EQ("hello!", response_data);
13567
13568 HttpRequestInfo request2;
13569 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713570 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213571 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013572 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213573
tfarina42834112016-09-22 13:38:2013574 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113575 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13576 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213577
13578 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213579 ASSERT_TRUE(response);
13580 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213581 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213582 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213583 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113584 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213585 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213586}
13587
ttuttle859dc7a2015-04-23 19:42:2913588class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4613589 public:
13590 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
13591 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013592 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613593
13594 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
13595
13596 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2013597 int Resolve(const RequestInfo& info,
13598 RequestPriority priority,
13599 AddressList* addresses,
13600 const CompletionCallback& callback,
maksim.sisov31452af2016-07-27 06:38:1013601 std::unique_ptr<Request>* out_req,
tfarina42834112016-09-22 13:38:2013602 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013603 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1013604 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4013605 }
13606
dchengb03027d2014-10-21 12:00:2013607 int ResolveFromCache(const RequestInfo& info,
13608 AddressList* addresses,
tfarina42834112016-09-22 13:38:2013609 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013610 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
13611 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0913612 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613613 return rv;
13614 }
13615
[email protected]46da33be2011-07-19 21:58:0413616 MockCachingHostResolver* GetMockHostResolver() {
13617 return &host_resolver_;
13618 }
13619
[email protected]e3ceb682011-06-28 23:55:4613620 private:
13621 MockCachingHostResolver host_resolver_;
13622 const HostPortPair host_port_;
13623};
13624
bncd16676a2016-07-20 16:23:0113625TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1313626 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4613627 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
bnca4d611d2016-09-22 19:55:3713628 OneTimeCachingHostResolver host_resolver(
13629 HostPortPair("mail.example.com", 443));
[email protected]c6bf8152012-12-02 07:43:3413630 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0713631 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4613632 params.host_resolver = &host_resolver;
danakj1fd259a02016-04-16 03:17:0913633 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613634
bnc032658ba2016-09-26 18:17:1513635 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613636
bncdf80d44fd2016-07-15 20:27:4113637 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913638 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813639 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113640 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713641 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613642 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113643 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613644 };
bnc42331402016-07-25 13:36:1513645 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113646 SpdySerializedFrame host1_resp_body(
13647 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513648 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113649 SpdySerializedFrame host2_resp_body(
13650 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613651 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113652 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13653 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313654 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613655 };
13656
eroman36d84e54432016-03-17 03:23:0213657 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213658 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313659 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13660 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713661 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613662
[email protected]aa22b242011-11-16 18:58:2913663 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613664 HttpRequestInfo request1;
13665 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313666 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613667 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013668 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613669
tfarina42834112016-09-22 13:38:2013670 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113671 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13672 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613673
13674 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213675 ASSERT_TRUE(response);
13676 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213677 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613678
13679 std::string response_data;
robpercival214763f2016-07-01 23:27:0113680 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613681 EXPECT_EQ("hello!", response_data);
13682
13683 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3713684 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613685 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013686 std::unique_ptr<HostResolver::Request> request;
13687 rv = host_resolver.Resolve(resolve_info, DEFAULT_PRIORITY, &ignored,
tfarina42834112016-09-22 13:38:2013688 callback.callback(), &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113689 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713690 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113691 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613692
13693 HttpRequestInfo request2;
13694 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713695 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613696 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013697 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613698
tfarina42834112016-09-22 13:38:2013699 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113700 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13701 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613702
13703 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213704 ASSERT_TRUE(response);
13705 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213706 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613707 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213708 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113709 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613710 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613711}
13712
bncd16676a2016-07-20 16:23:0113713TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313714 const std::string https_url = "https://www.example.org:8080/";
13715 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413716
13717 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4113718 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4913719 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413720
13721 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4113722 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0413723 };
13724
bnc42331402016-07-25 13:36:1513725 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113726 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13727 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5913728 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413729
rch8e6c6c42015-05-01 14:05:1313730 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13731 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413732 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713733 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413734
13735 // HTTP GET for the HTTP URL
13736 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313737 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413738 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313739 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413740 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413741 };
13742
13743 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313744 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13745 MockRead(ASYNC, 2, "hello"),
13746 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413747 };
13748
rch8e6c6c42015-05-01 14:05:1313749 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13750 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0413751
[email protected]8450d722012-07-02 19:14:0413752 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613753 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713754 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13755 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13756 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0413757
danakj1fd259a02016-04-16 03:17:0913758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413759
13760 // Start the first transaction to set up the SpdySession
13761 HttpRequestInfo request1;
13762 request1.method = "GET";
13763 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413764 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013765 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413766 TestCompletionCallback callback1;
13767 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013768 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5513769 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413770
robpercival214763f2016-07-01 23:27:0113771 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0413772 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13773
13774 // Now, start the HTTP request
13775 HttpRequestInfo request2;
13776 request2.method = "GET";
13777 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413778 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013779 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413780 TestCompletionCallback callback2;
13781 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2013782 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5513783 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413784
robpercival214763f2016-07-01 23:27:0113785 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0413786 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13787}
13788
bnc5452e2a2015-05-08 16:27:4213789// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
13790// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0113791TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2513792 url::SchemeHostPort server("https", "www.example.org", 443);
13793 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4213794
bnc8bef8da22016-05-30 01:28:2513795 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4213796 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613797 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4213798 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13799
13800 // No data should be read from the alternative, because HTTP/1.1 is
13801 // negotiated.
13802 StaticSocketDataProvider data;
13803 session_deps_.socket_factory->AddSocketDataProvider(&data);
13804
13805 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4613806 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4213807 // mocked. This way the request relies on the alternate Job.
13808 StaticSocketDataProvider data_refused;
13809 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13810 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13811
zhongyi3d4a55e72016-04-22 20:36:4613812 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913813 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013814 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4213815 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2113816 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1213817 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613818 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013819 expiration);
bnc5452e2a2015-05-08 16:27:4213820
bnc691fda62016-08-12 00:43:1613821 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4213822 HttpRequestInfo request;
13823 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2513824 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4213825 TestCompletionCallback callback;
13826
13827 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5213828 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2013829 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5213830 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4213831}
13832
bnc40448a532015-05-11 19:13:1413833// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4613834// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1413835// succeeds, the request should succeed, even if the latter fails because
13836// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0113837TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2513838 url::SchemeHostPort server("https", "www.example.org", 443);
13839 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1413840
13841 // Negotiate HTTP/1.1 with alternative.
13842 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613843 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1413844 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13845
13846 // No data should be read from the alternative, because HTTP/1.1 is
13847 // negotiated.
13848 StaticSocketDataProvider data;
13849 session_deps_.socket_factory->AddSocketDataProvider(&data);
13850
zhongyi3d4a55e72016-04-22 20:36:4613851 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1413852 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613853 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1413854 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13855
13856 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2513857 MockWrite("GET / HTTP/1.1\r\n"
13858 "Host: www.example.org\r\n"
13859 "Connection: keep-alive\r\n\r\n"),
13860 MockWrite("GET /second HTTP/1.1\r\n"
13861 "Host: www.example.org\r\n"
13862 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1413863 };
13864
13865 MockRead http_reads[] = {
13866 MockRead("HTTP/1.1 200 OK\r\n"),
13867 MockRead("Content-Type: text/html\r\n"),
13868 MockRead("Content-Length: 6\r\n\r\n"),
13869 MockRead("foobar"),
13870 MockRead("HTTP/1.1 200 OK\r\n"),
13871 MockRead("Content-Type: text/html\r\n"),
13872 MockRead("Content-Length: 7\r\n\r\n"),
13873 MockRead("another"),
13874 };
13875 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13876 http_writes, arraysize(http_writes));
13877 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13878
zhongyi3d4a55e72016-04-22 20:36:4613879 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913880 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013881 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1413882 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2113883 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1213884 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613885 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013886 expiration);
bnc40448a532015-05-11 19:13:1413887
13888 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13889 HttpRequestInfo request1;
13890 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2513891 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1413892 request1.load_flags = 0;
13893 TestCompletionCallback callback1;
13894
tfarina42834112016-09-22 13:38:2013895 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1413896 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0113897 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1413898
13899 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213900 ASSERT_TRUE(response1);
13901 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1413902 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13903
13904 std::string response_data1;
robpercival214763f2016-07-01 23:27:0113905 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1413906 EXPECT_EQ("foobar", response_data1);
13907
13908 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13909 // for alternative service.
13910 EXPECT_TRUE(
13911 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13912
zhongyi3d4a55e72016-04-22 20:36:4613913 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1413914 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4613915 // to server.
bnc40448a532015-05-11 19:13:1413916 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13917 HttpRequestInfo request2;
13918 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2513919 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1413920 request2.load_flags = 0;
13921 TestCompletionCallback callback2;
13922
tfarina42834112016-09-22 13:38:2013923 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1413924 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0113925 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1413926
13927 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213928 ASSERT_TRUE(response2);
13929 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1413930 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13931
13932 std::string response_data2;
robpercival214763f2016-07-01 23:27:0113933 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1413934 EXPECT_EQ("another", response_data2);
13935}
13936
bnc5452e2a2015-05-08 16:27:4213937// Alternative service requires HTTP/2 (or SPDY), but there is already a
13938// HTTP/1.1 socket open to the alternative server. That socket should not be
13939// used.
bncd16676a2016-07-20 16:23:0113940TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4613941 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4213942 HostPortPair alternative("alternative.example.org", 443);
13943 std::string origin_url = "https://origin.example.org:443";
13944 std::string alternative_url = "https://alternative.example.org:443";
13945
13946 // Negotiate HTTP/1.1 with alternative.example.org.
13947 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613948 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4213949 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13950
13951 // HTTP/1.1 data for |request1| and |request2|.
13952 MockWrite http_writes[] = {
13953 MockWrite(
13954 "GET / HTTP/1.1\r\n"
13955 "Host: alternative.example.org\r\n"
13956 "Connection: keep-alive\r\n\r\n"),
13957 MockWrite(
13958 "GET / HTTP/1.1\r\n"
13959 "Host: alternative.example.org\r\n"
13960 "Connection: keep-alive\r\n\r\n"),
13961 };
13962
13963 MockRead http_reads[] = {
13964 MockRead(
13965 "HTTP/1.1 200 OK\r\n"
13966 "Content-Type: text/html; charset=iso-8859-1\r\n"
13967 "Content-Length: 40\r\n\r\n"
13968 "first HTTP/1.1 response from alternative"),
13969 MockRead(
13970 "HTTP/1.1 200 OK\r\n"
13971 "Content-Type: text/html; charset=iso-8859-1\r\n"
13972 "Content-Length: 41\r\n\r\n"
13973 "second HTTP/1.1 response from alternative"),
13974 };
13975 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13976 http_writes, arraysize(http_writes));
13977 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13978
13979 // This test documents that an alternate Job should not pool to an already
13980 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4613981 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4213982 StaticSocketDataProvider data_refused;
13983 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13984 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13985
zhongyi3d4a55e72016-04-22 20:36:4613986 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0913987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013988 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4213989 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2113990 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1213991 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613992 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013993 expiration);
bnc5452e2a2015-05-08 16:27:4213994
13995 // First transaction to alternative to open an HTTP/1.1 socket.
bnc691fda62016-08-12 00:43:1613996 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4213997 HttpRequestInfo request1;
13998 request1.method = "GET";
13999 request1.url = GURL(alternative_url);
14000 request1.load_flags = 0;
14001 TestCompletionCallback callback1;
14002
tfarina42834112016-09-22 13:38:2014003 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114004 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614005 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214006 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214007 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214008 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214009 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214010 EXPECT_FALSE(response1->was_fetched_via_spdy);
14011 std::string response_data1;
bnc691fda62016-08-12 00:43:1614012 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214013 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14014
14015 // Request for origin.example.org, which has an alternative service. This
14016 // will start two Jobs: the alternative looks for connections to pool to,
14017 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614018 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214019 // this request fails.
bnc691fda62016-08-12 00:43:1614020 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214021 HttpRequestInfo request2;
14022 request2.method = "GET";
14023 request2.url = GURL(origin_url);
14024 request2.load_flags = 0;
14025 TestCompletionCallback callback2;
14026
tfarina42834112016-09-22 13:38:2014027 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114028 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214029
14030 // Another transaction to alternative. This is to test that the HTTP/1.1
14031 // socket is still open and in the pool.
bnc691fda62016-08-12 00:43:1614032 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214033 HttpRequestInfo request3;
14034 request3.method = "GET";
14035 request3.url = GURL(alternative_url);
14036 request3.load_flags = 0;
14037 TestCompletionCallback callback3;
14038
tfarina42834112016-09-22 13:38:2014039 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114040 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614041 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214042 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214043 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214044 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214045 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214046 EXPECT_FALSE(response3->was_fetched_via_spdy);
14047 std::string response_data3;
bnc691fda62016-08-12 00:43:1614048 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214049 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14050}
14051
bncd16676a2016-07-20 16:23:0114052TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314053 const std::string https_url = "https://www.example.org:8080/";
14054 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414055
rdsmithebb50aa2015-11-12 03:44:3814056 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114057 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814058
[email protected]8450d722012-07-02 19:14:0414059 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314060 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114061 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414062 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114063 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914064 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114065 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214066 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914067
14068 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914069 SpdyHeaderBlock req2_block;
14070 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2314071 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2914072 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4914073 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4114074 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514075 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414076
14077 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114078 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14079 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414080 };
14081
bncdf80d44fd2016-07-15 20:27:4114082 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514083 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114084 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514085 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114086 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14087 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814088 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114089 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814090 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514091 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114092 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314093 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114094 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314095 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114096 CreateMockRead(wrapped_resp1, 4),
14097 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314098 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114099 CreateMockRead(resp2, 8),
14100 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314101 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14102 };
[email protected]8450d722012-07-02 19:14:0414103
mmenke666a6fea2015-12-19 04:16:3314104 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14105 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414106 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714107 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414108
rdsmith82957ad2015-09-16 19:42:0314109 session_deps_.proxy_service =
14110 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114111 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714112 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414113 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614114 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314115 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414116 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614117 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314118 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14119 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414120
danakj1fd259a02016-04-16 03:17:0914121 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414122
14123 // Start the first transaction to set up the SpdySession
14124 HttpRequestInfo request1;
14125 request1.method = "GET";
14126 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414127 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014128 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414129 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014130 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414131
mmenke666a6fea2015-12-19 04:16:3314132 // This pause is a hack to avoid running into https://crbug.com/497228.
14133 data1.RunUntilPaused();
14134 base::RunLoop().RunUntilIdle();
14135 data1.Resume();
robpercival214763f2016-07-01 23:27:0114136 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414137 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14138
[email protected]f6c63db52013-02-02 00:35:2214139 LoadTimingInfo load_timing_info1;
14140 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14141 TestLoadTimingNotReusedWithPac(load_timing_info1,
14142 CONNECT_TIMING_HAS_SSL_TIMES);
14143
mmenke666a6fea2015-12-19 04:16:3314144 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414145 HttpRequestInfo request2;
14146 request2.method = "GET";
14147 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414148 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014149 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414150 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014151 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414152
mmenke666a6fea2015-12-19 04:16:3314153 // This pause is a hack to avoid running into https://crbug.com/497228.
14154 data1.RunUntilPaused();
14155 base::RunLoop().RunUntilIdle();
14156 data1.Resume();
robpercival214763f2016-07-01 23:27:0114157 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314158
[email protected]8450d722012-07-02 19:14:0414159 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214160
14161 LoadTimingInfo load_timing_info2;
14162 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14163 // The established SPDY sessions is considered reused by the HTTP request.
14164 TestLoadTimingReusedWithPac(load_timing_info2);
14165 // HTTP requests over a SPDY session should have a different connection
14166 // socket_log_id than requests over a tunnel.
14167 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414168}
14169
[email protected]2d88e7d2012-07-19 17:55:1714170// Test that in the case where we have a SPDY session to a SPDY proxy
14171// that we do not pool other origins that resolve to the same IP when
14172// the certificate does not match the new origin.
14173// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114174TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314175 const std::string url1 = "http://www.example.org/";
14176 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714177 const std::string ip_addr = "1.2.3.4";
14178
rdsmithebb50aa2015-11-12 03:44:3814179 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114180 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814181
[email protected]2d88e7d2012-07-19 17:55:1714182 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614183 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314184 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114185 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514186 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714187
14188 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114189 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714190 };
14191
bnc42331402016-07-25 13:36:1514192 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114193 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714194 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114195 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14196 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714197 };
14198
mmenke666a6fea2015-12-19 04:16:3314199 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14200 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214201 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914202 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714203 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14204 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314205 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714206
14207 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114208 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914209 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714210
14211 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114212 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714213 };
14214
bnc42331402016-07-25 13:36:1514215 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114216 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14217 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314218 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714219
mmenke666a6fea2015-12-19 04:16:3314220 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14221 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714222 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314223 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714224
14225 // Set up a proxy config that sends HTTP requests to a proxy, and
14226 // all others direct.
14227 ProxyConfig proxy_config;
14228 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0714229 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0914230 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), nullptr,
csharrisonb7e3a082015-09-22 19:13:0414231 NULL));
[email protected]2d88e7d2012-07-19 17:55:1714232
bncce36dca22015-04-21 22:11:2314233 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614234 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714235 // Load a valid cert. Note, that this does not need to
14236 // be valid for proxy because the MockSSLClientSocket does
14237 // not actually verify it. But SpdySession will use this
14238 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314239 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214240 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314241 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14242 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714243
14244 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614245 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314246 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14247 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714248
[email protected]bb88e1d32013-05-03 23:11:0714249 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2314250 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714251 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714252
danakj1fd259a02016-04-16 03:17:0914253 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714254
14255 // Start the first transaction to set up the SpdySession
14256 HttpRequestInfo request1;
14257 request1.method = "GET";
14258 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714259 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014260 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714261 TestCompletionCallback callback1;
14262 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014263 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314264 // This pause is a hack to avoid running into https://crbug.com/497228.
14265 data1.RunUntilPaused();
14266 base::RunLoop().RunUntilIdle();
14267 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714268
robpercival214763f2016-07-01 23:27:0114269 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714270 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14271
14272 // Now, start the HTTP request
14273 HttpRequestInfo request2;
14274 request2.method = "GET";
14275 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714276 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014277 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714278 TestCompletionCallback callback2;
14279 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014280 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514281 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714282
14283 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114284 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714285 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14286}
14287
[email protected]85f97342013-04-17 06:12:2414288// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14289// error) in SPDY session, removes the socket from pool and closes the SPDY
14290// session. Verify that new url's from the same HttpNetworkSession (and a new
14291// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114292TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314293 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414294
14295 MockRead reads1[] = {
14296 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14297 };
14298
mmenke11eb5152015-06-09 14:50:5014299 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414300
bncdf80d44fd2016-07-15 20:27:4114301 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914302 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414303 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114304 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414305 };
14306
bnc42331402016-07-25 13:36:1514307 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114308 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414309 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114310 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14311 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414312 };
14313
mmenke11eb5152015-06-09 14:50:5014314 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14315 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414316
[email protected]85f97342013-04-17 06:12:2414317 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614318 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014319 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14320 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414321
14322 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614323 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14325 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414326
danakj1fd259a02016-04-16 03:17:0914327 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014328 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414329
14330 // Start the first transaction to set up the SpdySession and verify that
14331 // connection was closed.
14332 HttpRequestInfo request1;
14333 request1.method = "GET";
14334 request1.url = GURL(https_url);
14335 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014336 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414337 TestCompletionCallback callback1;
14338 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014339 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114340 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414341
14342 // Now, start the second request and make sure it succeeds.
14343 HttpRequestInfo request2;
14344 request2.method = "GET";
14345 request2.url = GURL(https_url);
14346 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014347 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414348 TestCompletionCallback callback2;
14349 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014350 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414351
robpercival214763f2016-07-01 23:27:0114352 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414353 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14354}
14355
bncd16676a2016-07-20 16:23:0114356TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314357 ClientSocketPoolManager::set_max_sockets_per_group(
14358 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14359 ClientSocketPoolManager::set_max_sockets_per_pool(
14360 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14361
14362 // Use two different hosts with different IPs so they don't get pooled.
14363 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14364 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914365 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314366
14367 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614368 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314369 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614370 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14372 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14373
bncdf80d44fd2016-07-15 20:27:4114374 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914375 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314376 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114377 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314378 };
bnc42331402016-07-25 13:36:1514379 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114380 SpdySerializedFrame host1_resp_body(
14381 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314382 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114383 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914384 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314385 };
14386
rdsmithebb50aa2015-11-12 03:44:3814387 // Use a separate test instance for the separate SpdySession that will be
14388 // created.
bncd16676a2016-07-20 16:23:0114389 SpdyTestUtil spdy_util_2;
danakj1fd259a02016-04-16 03:17:0914390 std::unique_ptr<SequencedSocketData> spdy1_data(
rch8e6c6c42015-05-01 14:05:1314391 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14392 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0314393 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14394
bncdf80d44fd2016-07-15 20:27:4114395 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914396 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314397 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114398 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314399 };
bnc42331402016-07-25 13:36:1514400 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114401 SpdySerializedFrame host2_resp_body(
14402 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314403 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114404 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914405 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314406 };
14407
danakj1fd259a02016-04-16 03:17:0914408 std::unique_ptr<SequencedSocketData> spdy2_data(
rch8e6c6c42015-05-01 14:05:1314409 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14410 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0314411 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14412
14413 MockWrite http_write[] = {
14414 MockWrite("GET / HTTP/1.1\r\n"
14415 "Host: www.a.com\r\n"
14416 "Connection: keep-alive\r\n\r\n"),
14417 };
14418
14419 MockRead http_read[] = {
14420 MockRead("HTTP/1.1 200 OK\r\n"),
14421 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14422 MockRead("Content-Length: 6\r\n\r\n"),
14423 MockRead("hello!"),
14424 };
14425 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14426 http_write, arraysize(http_write));
14427 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14428
14429 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014430 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314431 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314432 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614433 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314434
14435 TestCompletionCallback callback;
14436 HttpRequestInfo request1;
14437 request1.method = "GET";
14438 request1.url = GURL("https://www.a.com/");
14439 request1.load_flags = 0;
danakj1fd259a02016-04-16 03:17:0914440 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5014441 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314442
tfarina42834112016-09-22 13:38:2014443 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114444 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14445 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314446
14447 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214448 ASSERT_TRUE(response);
14449 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214450 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314451 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214452 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0314453
14454 std::string response_data;
robpercival214763f2016-07-01 23:27:0114455 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314456 EXPECT_EQ("hello!", response_data);
14457 trans.reset();
14458 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614459 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314460
14461 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014462 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314463 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314464 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614465 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314466 HttpRequestInfo request2;
14467 request2.method = "GET";
14468 request2.url = GURL("https://www.b.com/");
14469 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014470 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314471
tfarina42834112016-09-22 13:38:2014472 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14474 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314475
14476 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214477 ASSERT_TRUE(response);
14478 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214479 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314480 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214481 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114482 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314483 EXPECT_EQ("hello!", response_data);
14484 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614485 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314486 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614487 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314488
14489 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014490 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314491 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314492 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614493 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314494 HttpRequestInfo request3;
14495 request3.method = "GET";
14496 request3.url = GURL("http://www.a.com/");
14497 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014498 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314499
tfarina42834112016-09-22 13:38:2014500 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114501 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14502 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0314503
14504 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214505 ASSERT_TRUE(response);
14506 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314507 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14508 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214509 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114510 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0314511 EXPECT_EQ("hello!", response_data);
14512 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614513 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314514 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614515 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314516}
14517
bncd16676a2016-07-20 16:23:0114518TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414519 HttpRequestInfo request;
14520 request.method = "GET";
bncce36dca22015-04-21 22:11:2314521 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414522
danakj1fd259a02016-04-16 03:17:0914523 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414525
ttuttled9dbc652015-09-29 20:00:5914526 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414527 StaticSocketDataProvider data;
14528 data.set_connect_data(mock_connect);
14529 session_deps_.socket_factory->AddSocketDataProvider(&data);
14530
14531 TestCompletionCallback callback;
14532
tfarina42834112016-09-22 13:38:2014533 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414535
14536 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114537 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414538
[email protected]79e1fd62013-06-20 06:50:0414539 // We don't care whether this succeeds or fails, but it shouldn't crash.
14540 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614541 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714542
14543 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614544 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714545 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114546 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914547
14548 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614549 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914550 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414551}
14552
bncd16676a2016-07-20 16:23:0114553TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0414554 HttpRequestInfo request;
14555 request.method = "GET";
bncce36dca22015-04-21 22:11:2314556 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414557
danakj1fd259a02016-04-16 03:17:0914558 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614559 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414560
ttuttled9dbc652015-09-29 20:00:5914561 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414562 StaticSocketDataProvider data;
14563 data.set_connect_data(mock_connect);
14564 session_deps_.socket_factory->AddSocketDataProvider(&data);
14565
14566 TestCompletionCallback callback;
14567
tfarina42834112016-09-22 13:38:2014568 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114569 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414570
14571 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114572 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0414573
[email protected]79e1fd62013-06-20 06:50:0414574 // We don't care whether this succeeds or fails, but it shouldn't crash.
14575 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614576 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714577
14578 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1614579 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4714580 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0114581 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5914582
14583 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1614584 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5914585 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414586}
14587
bncd16676a2016-07-20 16:23:0114588TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414589 HttpRequestInfo request;
14590 request.method = "GET";
bncce36dca22015-04-21 22:11:2314591 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414592
danakj1fd259a02016-04-16 03:17:0914593 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614594 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414595
14596 MockWrite data_writes[] = {
14597 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14598 };
14599 MockRead data_reads[] = {
14600 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14601 };
14602
14603 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14604 data_writes, arraysize(data_writes));
14605 session_deps_.socket_factory->AddSocketDataProvider(&data);
14606
14607 TestCompletionCallback callback;
14608
tfarina42834112016-09-22 13:38:2014609 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114610 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414611
14612 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114613 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414614
[email protected]79e1fd62013-06-20 06:50:0414615 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614616 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414617 EXPECT_TRUE(request_headers.HasHeader("Host"));
14618}
14619
bncd16676a2016-07-20 16:23:0114620TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0414621 HttpRequestInfo request;
14622 request.method = "GET";
bncce36dca22015-04-21 22:11:2314623 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414624
danakj1fd259a02016-04-16 03:17:0914625 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414627
14628 MockWrite data_writes[] = {
14629 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14630 };
14631 MockRead data_reads[] = {
14632 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14633 };
14634
14635 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14636 data_writes, arraysize(data_writes));
14637 session_deps_.socket_factory->AddSocketDataProvider(&data);
14638
14639 TestCompletionCallback callback;
14640
tfarina42834112016-09-22 13:38:2014641 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114642 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414643
14644 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114645 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414646
[email protected]79e1fd62013-06-20 06:50:0414647 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614648 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414649 EXPECT_TRUE(request_headers.HasHeader("Host"));
14650}
14651
bncd16676a2016-07-20 16:23:0114652TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414653 HttpRequestInfo request;
14654 request.method = "GET";
bncce36dca22015-04-21 22:11:2314655 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414656
danakj1fd259a02016-04-16 03:17:0914657 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614658 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414659
14660 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314661 MockWrite(
14662 "GET / HTTP/1.1\r\n"
14663 "Host: www.example.org\r\n"
14664 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414665 };
14666 MockRead data_reads[] = {
14667 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14668 };
14669
14670 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14671 data_writes, arraysize(data_writes));
14672 session_deps_.socket_factory->AddSocketDataProvider(&data);
14673
14674 TestCompletionCallback callback;
14675
tfarina42834112016-09-22 13:38:2014676 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114677 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414678
14679 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114680 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414681
[email protected]79e1fd62013-06-20 06:50:0414682 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614683 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414684 EXPECT_TRUE(request_headers.HasHeader("Host"));
14685}
14686
bncd16676a2016-07-20 16:23:0114687TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0414688 HttpRequestInfo request;
14689 request.method = "GET";
bncce36dca22015-04-21 22:11:2314690 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414691
danakj1fd259a02016-04-16 03:17:0914692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414694
14695 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314696 MockWrite(
14697 "GET / HTTP/1.1\r\n"
14698 "Host: www.example.org\r\n"
14699 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414700 };
14701 MockRead data_reads[] = {
14702 MockRead(ASYNC, ERR_CONNECTION_RESET),
14703 };
14704
14705 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14706 data_writes, arraysize(data_writes));
14707 session_deps_.socket_factory->AddSocketDataProvider(&data);
14708
14709 TestCompletionCallback callback;
14710
tfarina42834112016-09-22 13:38:2014711 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114712 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414713
14714 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114715 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0414716
[email protected]79e1fd62013-06-20 06:50:0414717 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614718 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414719 EXPECT_TRUE(request_headers.HasHeader("Host"));
14720}
14721
bncd16676a2016-07-20 16:23:0114722TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0414723 HttpRequestInfo request;
14724 request.method = "GET";
bncce36dca22015-04-21 22:11:2314725 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414726 request.extra_headers.SetHeader("X-Foo", "bar");
14727
danakj1fd259a02016-04-16 03:17:0914728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0414730
14731 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314732 MockWrite(
14733 "GET / HTTP/1.1\r\n"
14734 "Host: www.example.org\r\n"
14735 "Connection: keep-alive\r\n"
14736 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414737 };
14738 MockRead data_reads[] = {
14739 MockRead("HTTP/1.1 200 OK\r\n"
14740 "Content-Length: 5\r\n\r\n"
14741 "hello"),
14742 MockRead(ASYNC, ERR_UNEXPECTED),
14743 };
14744
14745 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14746 data_writes, arraysize(data_writes));
14747 session_deps_.socket_factory->AddSocketDataProvider(&data);
14748
14749 TestCompletionCallback callback;
14750
tfarina42834112016-09-22 13:38:2014751 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114752 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0414753
14754 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114755 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0414756
14757 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1614758 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0414759 std::string foo;
14760 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14761 EXPECT_EQ("bar", foo);
14762}
14763
[email protected]bf828982013-08-14 18:01:4714764namespace {
14765
yhiranoa7e05bb2014-11-06 05:40:3914766// Fake HttpStream that simply records calls to SetPriority().
14767class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0314768 public base::SupportsWeakPtr<FakeStream> {
14769 public:
14770 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2014771 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0314772
14773 RequestPriority priority() const { return priority_; }
14774
dchengb03027d2014-10-21 12:00:2014775 int InitializeStream(const HttpRequestInfo* request_info,
14776 RequestPriority priority,
tfarina42834112016-09-22 13:38:2014777 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2014778 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314779 return ERR_IO_PENDING;
14780 }
14781
dchengb03027d2014-10-21 12:00:2014782 int SendRequest(const HttpRequestHeaders& request_headers,
14783 HttpResponseInfo* response,
14784 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314785 ADD_FAILURE();
14786 return ERR_UNEXPECTED;
14787 }
14788
dchengb03027d2014-10-21 12:00:2014789 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314790 ADD_FAILURE();
14791 return ERR_UNEXPECTED;
14792 }
14793
dchengb03027d2014-10-21 12:00:2014794 int ReadResponseBody(IOBuffer* buf,
14795 int buf_len,
14796 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314797 ADD_FAILURE();
14798 return ERR_UNEXPECTED;
14799 }
14800
dchengb03027d2014-10-21 12:00:2014801 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0314802
dchengb03027d2014-10-21 12:00:2014803 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0314804 ADD_FAILURE();
14805 return false;
14806 }
14807
dchengb03027d2014-10-21 12:00:2014808 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0314809 ADD_FAILURE();
14810 return false;
14811 }
14812
dchengb03027d2014-10-21 12:00:2014813 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314814
mmenkebd84c392015-09-02 14:12:3414815 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314816
sclittle4de1bab92015-09-22 21:28:2414817 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914818 ADD_FAILURE();
14819 return 0;
14820 }
14821
sclittlebe1ccf62015-09-02 19:40:3614822 int64_t GetTotalSentBytes() const override {
14823 ADD_FAILURE();
14824 return 0;
14825 }
14826
dchengb03027d2014-10-21 12:00:2014827 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314828 ADD_FAILURE();
14829 return false;
14830 }
14831
dchengb03027d2014-10-21 12:00:2014832 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14833
14834 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314835 ADD_FAILURE();
14836 }
14837
ttuttled9dbc652015-09-29 20:00:5914838 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14839
nharper78e6d2b2016-09-21 05:42:3514840 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
14841 TokenBindingType tb_type,
14842 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1414843 ADD_FAILURE();
14844 return ERR_NOT_IMPLEMENTED;
14845 }
14846
dchengb03027d2014-10-21 12:00:2014847 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314848
zhongyica364fbb2015-12-12 03:39:1214849 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14850
dchengb03027d2014-10-21 12:00:2014851 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314852
yhiranoa7e05bb2014-11-06 05:40:3914853 HttpStream* RenewStreamForAuth() override { return NULL; }
14854
[email protected]e86839fd2013-08-14 18:29:0314855 private:
14856 RequestPriority priority_;
14857
14858 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14859};
14860
14861// Fake HttpStreamRequest that simply records calls to SetPriority()
14862// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714863class FakeStreamRequest : public HttpStreamRequest,
14864 public base::SupportsWeakPtr<FakeStreamRequest> {
14865 public:
[email protected]e86839fd2013-08-14 18:29:0314866 FakeStreamRequest(RequestPriority priority,
14867 HttpStreamRequest::Delegate* delegate)
14868 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414869 delegate_(delegate),
14870 websocket_stream_create_helper_(NULL) {}
14871
14872 FakeStreamRequest(RequestPriority priority,
14873 HttpStreamRequest::Delegate* delegate,
14874 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14875 : priority_(priority),
14876 delegate_(delegate),
14877 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314878
dchengb03027d2014-10-21 12:00:2014879 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714880
14881 RequestPriority priority() const { return priority_; }
14882
[email protected]831e4a32013-11-14 02:14:4414883 const WebSocketHandshakeStreamBase::CreateHelper*
14884 websocket_stream_create_helper() const {
14885 return websocket_stream_create_helper_;
14886 }
14887
[email protected]e86839fd2013-08-14 18:29:0314888 // Create a new FakeStream and pass it to the request's
14889 // delegate. Returns a weak pointer to the FakeStream.
14890 base::WeakPtr<FakeStream> FinishStreamRequest() {
14891 FakeStream* fake_stream = new FakeStream(priority_);
14892 // Do this before calling OnStreamReady() as OnStreamReady() may
14893 // immediately delete |fake_stream|.
14894 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14895 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14896 return weak_stream;
14897 }
14898
dchengb03027d2014-10-21 12:00:2014899 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714900 ADD_FAILURE();
14901 return ERR_UNEXPECTED;
14902 }
14903
dchengb03027d2014-10-21 12:00:2014904 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714905 ADD_FAILURE();
14906 return LoadState();
14907 }
14908
dchengb03027d2014-10-21 12:00:2014909 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714910
bnc94c92842016-09-21 15:22:5214911 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714912
bnc6227b26e2016-08-12 02:00:4314913 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714914
dchengb03027d2014-10-21 12:00:2014915 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714916
ttuttle1f2d7e92015-04-28 16:17:4714917 const ConnectionAttempts& connection_attempts() const override {
14918 static ConnectionAttempts no_attempts;
14919 return no_attempts;
14920 }
14921
[email protected]bf828982013-08-14 18:01:4714922 private:
14923 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314924 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414925 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714926
14927 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14928};
14929
14930// Fake HttpStreamFactory that vends FakeStreamRequests.
14931class FakeStreamFactory : public HttpStreamFactory {
14932 public:
14933 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014934 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714935
14936 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14937 // RequestStream() (which may be NULL if it was destroyed already).
14938 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14939 return last_stream_request_;
14940 }
14941
dchengb03027d2014-10-21 12:00:2014942 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14943 RequestPriority priority,
14944 const SSLConfig& server_ssl_config,
14945 const SSLConfig& proxy_ssl_config,
14946 HttpStreamRequest::Delegate* delegate,
tfarina42834112016-09-22 13:38:2014947 const NetLogWithSource& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314948 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714949 last_stream_request_ = fake_request->AsWeakPtr();
14950 return fake_request;
14951 }
14952
xunjieli5749218c2016-03-22 16:43:0614953 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0814954 const HttpRequestInfo& info,
14955 RequestPriority priority,
14956 const SSLConfig& server_ssl_config,
14957 const SSLConfig& proxy_ssl_config,
14958 HttpStreamRequest::Delegate* delegate,
tfarina42834112016-09-22 13:38:2014959 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0814960 NOTREACHED();
14961 return nullptr;
14962 }
14963
dchengb03027d2014-10-21 12:00:2014964 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714965 const HttpRequestInfo& info,
14966 RequestPriority priority,
14967 const SSLConfig& server_ssl_config,
14968 const SSLConfig& proxy_ssl_config,
14969 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614970 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
tfarina42834112016-09-22 13:38:2014971 const NetLogWithSource& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414972 FakeStreamRequest* fake_request =
14973 new FakeStreamRequest(priority, delegate, create_helper);
14974 last_stream_request_ = fake_request->AsWeakPtr();
14975 return fake_request;
[email protected]bf828982013-08-14 18:01:4714976 }
14977
dchengb03027d2014-10-21 12:00:2014978 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5914979 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4714980 ADD_FAILURE();
14981 }
14982
dchengb03027d2014-10-21 12:00:2014983 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714984 ADD_FAILURE();
14985 return NULL;
14986 }
14987
14988 private:
14989 base::WeakPtr<FakeStreamRequest> last_stream_request_;
14990
14991 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
14992};
14993
Adam Rice425cf122015-01-19 06:18:2414994// TODO(ricea): Maybe unify this with the one in
14995// url_request_http_job_unittest.cc ?
14996class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
14997 public:
danakj1fd259a02016-04-16 03:17:0914998 FakeWebSocketBasicHandshakeStream(
14999 std::unique_ptr<ClientSocketHandle> connection,
15000 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215001 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415002
15003 // Fake implementation of HttpStreamBase methods.
15004 // This ends up being quite "real" because this object has to really send data
15005 // on the mock socket. It might be easier to use the real implementation, but
15006 // the fact that the WebSocket code is not compiled on iOS makes that
15007 // difficult.
15008 int InitializeStream(const HttpRequestInfo* request_info,
15009 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015010 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415011 const CompletionCallback& callback) override {
15012 state_.Initialize(request_info, priority, net_log, callback);
15013 return OK;
15014 }
15015
15016 int SendRequest(const HttpRequestHeaders& request_headers,
15017 HttpResponseInfo* response,
15018 const CompletionCallback& callback) override {
15019 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15020 response, callback);
15021 }
15022
15023 int ReadResponseHeaders(const CompletionCallback& callback) override {
15024 return parser()->ReadResponseHeaders(callback);
15025 }
15026
15027 int ReadResponseBody(IOBuffer* buf,
15028 int buf_len,
15029 const CompletionCallback& callback) override {
15030 NOTREACHED();
15031 return ERR_IO_PENDING;
15032 }
15033
15034 void Close(bool not_reusable) override {
15035 if (parser())
15036 parser()->Close(true);
15037 }
15038
15039 bool IsResponseBodyComplete() const override {
15040 NOTREACHED();
15041 return false;
15042 }
15043
Adam Rice425cf122015-01-19 06:18:2415044 bool IsConnectionReused() const override {
15045 NOTREACHED();
15046 return false;
15047 }
15048 void SetConnectionReused() override { NOTREACHED(); }
15049
mmenkebd84c392015-09-02 14:12:3415050 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415051
sclittle4de1bab92015-09-22 21:28:2415052 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415053 NOTREACHED();
15054 return 0;
15055 }
15056
sclittlebe1ccf62015-09-02 19:40:3615057 int64_t GetTotalSentBytes() const override {
15058 NOTREACHED();
15059 return 0;
15060 }
15061
Adam Rice425cf122015-01-19 06:18:2415062 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15063 NOTREACHED();
15064 return false;
15065 }
15066
Adam Ricecb76ac62015-02-20 05:33:2515067 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415068
15069 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15070 NOTREACHED();
15071 }
15072
ttuttled9dbc652015-09-29 20:00:5915073 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15074
nharper78e6d2b2016-09-21 05:42:3515075 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15076 TokenBindingType tb_type,
15077 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415078 ADD_FAILURE();
15079 return ERR_NOT_IMPLEMENTED;
15080 }
15081
Adam Rice425cf122015-01-19 06:18:2415082 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15083
zhongyica364fbb2015-12-12 03:39:1215084 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15085
Adam Rice425cf122015-01-19 06:18:2415086 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15087
Adam Rice425cf122015-01-19 06:18:2415088 HttpStream* RenewStreamForAuth() override {
15089 NOTREACHED();
15090 return nullptr;
15091 }
15092
15093 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915094 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415095 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915096 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415097 }
15098
15099 private:
15100 HttpStreamParser* parser() const { return state_.parser(); }
15101 HttpBasicState state_;
15102
15103 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15104};
15105
[email protected]831e4a32013-11-14 02:14:4415106// TODO(yhirano): Split this class out into a net/websockets file, if it is
15107// worth doing.
15108class FakeWebSocketStreamCreateHelper :
15109 public WebSocketHandshakeStreamBase::CreateHelper {
15110 public:
dchengb03027d2014-10-21 12:00:2015111 WebSocketHandshakeStreamBase* CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915112 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315113 bool using_proxy) override {
dchengc7eeda422015-12-26 03:56:4815114 return new FakeWebSocketBasicHandshakeStream(std::move(connection),
Adam Rice425cf122015-01-19 06:18:2415115 using_proxy);
[email protected]831e4a32013-11-14 02:14:4415116 }
15117
dchengb03027d2014-10-21 12:00:2015118 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4415119 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1315120 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4415121 NOTREACHED();
15122 return NULL;
15123 };
15124
dchengb03027d2014-10-21 12:00:2015125 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415126
danakj1fd259a02016-04-16 03:17:0915127 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415128 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915129 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415130 }
15131};
15132
[email protected]bf828982013-08-14 18:01:4715133} // namespace
15134
15135// Make sure that HttpNetworkTransaction passes on its priority to its
15136// stream request on start.
bncd16676a2016-07-20 16:23:0115137TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915138 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215139 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715140 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915141 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715142
dcheng48459ac22014-08-26 00:46:4115143 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715144
wezca1070932016-05-26 20:30:5215145 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715146
15147 HttpRequestInfo request;
15148 TestCompletionCallback callback;
15149 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015150 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715151
15152 base::WeakPtr<FakeStreamRequest> fake_request =
15153 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215154 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715155 EXPECT_EQ(LOW, fake_request->priority());
15156}
15157
15158// Make sure that HttpNetworkTransaction passes on its priority
15159// updates to its stream request.
bncd16676a2016-07-20 16:23:0115160TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915161 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215162 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715163 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915164 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715165
dcheng48459ac22014-08-26 00:46:4115166 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715167
15168 HttpRequestInfo request;
15169 TestCompletionCallback callback;
15170 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015171 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715172
15173 base::WeakPtr<FakeStreamRequest> fake_request =
15174 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215175 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715176 EXPECT_EQ(LOW, fake_request->priority());
15177
15178 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215179 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715180 EXPECT_EQ(LOWEST, fake_request->priority());
15181}
15182
[email protected]e86839fd2013-08-14 18:29:0315183// Make sure that HttpNetworkTransaction passes on its priority
15184// updates to its stream.
bncd16676a2016-07-20 16:23:0115185TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915186 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215187 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315188 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915189 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315190
dcheng48459ac22014-08-26 00:46:4115191 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315192
15193 HttpRequestInfo request;
15194 TestCompletionCallback callback;
15195 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015196 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315197
15198 base::WeakPtr<FakeStreamRequest> fake_request =
15199 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215200 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315201 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215202 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315203 EXPECT_EQ(LOW, fake_stream->priority());
15204
15205 trans.SetPriority(LOWEST);
15206 EXPECT_EQ(LOWEST, fake_stream->priority());
15207}
15208
bncd16676a2016-07-20 16:23:0115209TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415210 // The same logic needs to be tested for both ws: and wss: schemes, but this
15211 // test is already parameterised on NextProto, so it uses a loop to verify
15212 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315213 std::string test_cases[] = {"ws://www.example.org/",
15214 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415215 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915216 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215217 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415218 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15219 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315220 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915221 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415222
dcheng48459ac22014-08-26 00:46:4115223 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415224 trans.SetWebSocketHandshakeStreamCreateHelper(
15225 &websocket_stream_create_helper);
15226
15227 HttpRequestInfo request;
15228 TestCompletionCallback callback;
15229 request.method = "GET";
15230 request.url = GURL(test_cases[i]);
15231
15232 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015233 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415234
15235 base::WeakPtr<FakeStreamRequest> fake_request =
15236 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215237 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415238 EXPECT_EQ(&websocket_stream_create_helper,
15239 fake_request->websocket_stream_create_helper());
15240 }
15241}
15242
[email protected]043b68c82013-08-22 23:41:5215243// Tests that when a used socket is returned to the SSL socket pool, it's closed
15244// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115245TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215246 ClientSocketPoolManager::set_max_sockets_per_group(
15247 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15248 ClientSocketPoolManager::set_max_sockets_per_pool(
15249 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15250
15251 // Set up SSL request.
15252
15253 HttpRequestInfo ssl_request;
15254 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315255 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215256
15257 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315258 MockWrite(
15259 "GET / HTTP/1.1\r\n"
15260 "Host: www.example.org\r\n"
15261 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215262 };
15263 MockRead ssl_reads[] = {
15264 MockRead("HTTP/1.1 200 OK\r\n"),
15265 MockRead("Content-Length: 11\r\n\r\n"),
15266 MockRead("hello world"),
15267 MockRead(SYNCHRONOUS, OK),
15268 };
15269 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15270 ssl_writes, arraysize(ssl_writes));
15271 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15272
15273 SSLSocketDataProvider ssl(ASYNC, OK);
15274 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15275
15276 // Set up HTTP request.
15277
15278 HttpRequestInfo http_request;
15279 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315280 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215281
15282 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315283 MockWrite(
15284 "GET / HTTP/1.1\r\n"
15285 "Host: www.example.org\r\n"
15286 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215287 };
15288 MockRead http_reads[] = {
15289 MockRead("HTTP/1.1 200 OK\r\n"),
15290 MockRead("Content-Length: 7\r\n\r\n"),
15291 MockRead("falafel"),
15292 MockRead(SYNCHRONOUS, OK),
15293 };
15294 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15295 http_writes, arraysize(http_writes));
15296 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15297
danakj1fd259a02016-04-16 03:17:0915298 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215299
15300 // Start the SSL request.
15301 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615302 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015303 ASSERT_EQ(ERR_IO_PENDING,
15304 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15305 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215306
15307 // Start the HTTP request. Pool should stall.
15308 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615309 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015310 ASSERT_EQ(ERR_IO_PENDING,
15311 http_trans.Start(&http_request, http_callback.callback(),
15312 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115313 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215314
15315 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115316 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215317 std::string response_data;
bnc691fda62016-08-12 00:43:1615318 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215319 EXPECT_EQ("hello world", response_data);
15320
15321 // The SSL socket should automatically be closed, so the HTTP request can
15322 // start.
dcheng48459ac22014-08-26 00:46:4115323 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15324 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215325
15326 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115327 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615328 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215329 EXPECT_EQ("falafel", response_data);
15330
dcheng48459ac22014-08-26 00:46:4115331 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215332}
15333
15334// Tests that when a SSL connection is established but there's no corresponding
15335// request that needs it, the new socket is closed if the transport socket pool
15336// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115337TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215338 ClientSocketPoolManager::set_max_sockets_per_group(
15339 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15340 ClientSocketPoolManager::set_max_sockets_per_pool(
15341 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15342
15343 // Set up an ssl request.
15344
15345 HttpRequestInfo ssl_request;
15346 ssl_request.method = "GET";
15347 ssl_request.url = GURL("https://www.foopy.com/");
15348
15349 // No data will be sent on the SSL socket.
15350 StaticSocketDataProvider ssl_data;
15351 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15352
15353 SSLSocketDataProvider ssl(ASYNC, OK);
15354 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15355
15356 // Set up HTTP request.
15357
15358 HttpRequestInfo http_request;
15359 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315360 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215361
15362 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315363 MockWrite(
15364 "GET / HTTP/1.1\r\n"
15365 "Host: www.example.org\r\n"
15366 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215367 };
15368 MockRead http_reads[] = {
15369 MockRead("HTTP/1.1 200 OK\r\n"),
15370 MockRead("Content-Length: 7\r\n\r\n"),
15371 MockRead("falafel"),
15372 MockRead(SYNCHRONOUS, OK),
15373 };
15374 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15375 http_writes, arraysize(http_writes));
15376 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15377
danakj1fd259a02016-04-16 03:17:0915378 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215379
15380 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15381 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915382 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915383 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115384 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215385
15386 // Start the HTTP request. Pool should stall.
15387 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615388 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015389 ASSERT_EQ(ERR_IO_PENDING,
15390 http_trans.Start(&http_request, http_callback.callback(),
15391 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115392 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215393
15394 // The SSL connection will automatically be closed once the connection is
15395 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0115396 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215397 std::string response_data;
bnc691fda62016-08-12 00:43:1615398 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215399 EXPECT_EQ("falafel", response_data);
15400
dcheng48459ac22014-08-26 00:46:4115401 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215402}
15403
bncd16676a2016-07-20 16:23:0115404TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915405 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215406 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715407 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215408 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415409
15410 HttpRequestInfo request;
15411 request.method = "POST";
15412 request.url = GURL("http://www.foo.com/");
15413 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415414
danakj1fd259a02016-04-16 03:17:0915415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615416 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415417 // Send headers successfully, but get an error while sending the body.
15418 MockWrite data_writes[] = {
15419 MockWrite("POST / HTTP/1.1\r\n"
15420 "Host: www.foo.com\r\n"
15421 "Connection: keep-alive\r\n"
15422 "Content-Length: 3\r\n\r\n"),
15423 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15424 };
15425
15426 MockRead data_reads[] = {
15427 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15428 MockRead("hello world"),
15429 MockRead(SYNCHRONOUS, OK),
15430 };
15431 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15432 arraysize(data_writes));
15433 session_deps_.socket_factory->AddSocketDataProvider(&data);
15434
15435 TestCompletionCallback callback;
15436
tfarina42834112016-09-22 13:38:2015437 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115438 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415439
15440 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115441 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415442
bnc691fda62016-08-12 00:43:1615443 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215444 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415445
wezca1070932016-05-26 20:30:5215446 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415447 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15448
15449 std::string response_data;
bnc691fda62016-08-12 00:43:1615450 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115451 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415452 EXPECT_EQ("hello world", response_data);
15453}
15454
15455// This test makes sure the retry logic doesn't trigger when reading an error
15456// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0115457TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415458 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915459 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415460 MockWrite data_writes[] = {
15461 MockWrite("GET / HTTP/1.1\r\n"
15462 "Host: www.foo.com\r\n"
15463 "Connection: keep-alive\r\n\r\n"),
15464 MockWrite("POST / HTTP/1.1\r\n"
15465 "Host: www.foo.com\r\n"
15466 "Connection: keep-alive\r\n"
15467 "Content-Length: 3\r\n\r\n"),
15468 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15469 };
15470
15471 MockRead data_reads[] = {
15472 MockRead("HTTP/1.1 200 Peachy\r\n"
15473 "Content-Length: 14\r\n\r\n"),
15474 MockRead("first response"),
15475 MockRead("HTTP/1.1 400 Not OK\r\n"
15476 "Content-Length: 15\r\n\r\n"),
15477 MockRead("second response"),
15478 MockRead(SYNCHRONOUS, OK),
15479 };
15480 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15481 arraysize(data_writes));
15482 session_deps_.socket_factory->AddSocketDataProvider(&data);
15483
15484 TestCompletionCallback callback;
15485 HttpRequestInfo request1;
15486 request1.method = "GET";
15487 request1.url = GURL("http://www.foo.com/");
15488 request1.load_flags = 0;
15489
bnc691fda62016-08-12 00:43:1615490 std::unique_ptr<HttpNetworkTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4115491 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
tfarina42834112016-09-22 13:38:2015492 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115493 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415494
15495 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115496 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415497
15498 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215499 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415500
wezca1070932016-05-26 20:30:5215501 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415502 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15503
15504 std::string response_data1;
15505 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0115506 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415507 EXPECT_EQ("first response", response_data1);
15508 // Delete the transaction to release the socket back into the socket pool.
15509 trans1.reset();
15510
danakj1fd259a02016-04-16 03:17:0915511 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215512 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915513 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215514 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415515
15516 HttpRequestInfo request2;
15517 request2.method = "POST";
15518 request2.url = GURL("http://www.foo.com/");
15519 request2.upload_data_stream = &upload_data_stream;
15520 request2.load_flags = 0;
15521
bnc691fda62016-08-12 00:43:1615522 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015523 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115524 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415525
15526 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115527 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415528
bnc691fda62016-08-12 00:43:1615529 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215530 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415531
wezca1070932016-05-26 20:30:5215532 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415533 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15534
15535 std::string response_data2;
bnc691fda62016-08-12 00:43:1615536 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0115537 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415538 EXPECT_EQ("second response", response_data2);
15539}
15540
bncd16676a2016-07-20 16:23:0115541TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415542 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915543 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215544 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715545 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215546 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415547
15548 HttpRequestInfo request;
15549 request.method = "POST";
15550 request.url = GURL("http://www.foo.com/");
15551 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415552
danakj1fd259a02016-04-16 03:17:0915553 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615554 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415555 // Send headers successfully, but get an error while sending the body.
15556 MockWrite data_writes[] = {
15557 MockWrite("POST / HTTP/1.1\r\n"
15558 "Host: www.foo.com\r\n"
15559 "Connection: keep-alive\r\n"
15560 "Content-Length: 3\r\n\r\n"
15561 "fo"),
15562 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15563 };
15564
15565 MockRead data_reads[] = {
15566 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15567 MockRead("hello world"),
15568 MockRead(SYNCHRONOUS, OK),
15569 };
15570 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15571 arraysize(data_writes));
15572 session_deps_.socket_factory->AddSocketDataProvider(&data);
15573
15574 TestCompletionCallback callback;
15575
tfarina42834112016-09-22 13:38:2015576 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115577 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415578
15579 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115580 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415581
bnc691fda62016-08-12 00:43:1615582 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215583 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415584
wezca1070932016-05-26 20:30:5215585 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415586 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15587
15588 std::string response_data;
bnc691fda62016-08-12 00:43:1615589 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115590 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415591 EXPECT_EQ("hello world", response_data);
15592}
15593
15594// This tests the more common case than the previous test, where headers and
15595// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0115596TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715597 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415598
15599 HttpRequestInfo request;
15600 request.method = "POST";
15601 request.url = GURL("http://www.foo.com/");
15602 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415603
danakj1fd259a02016-04-16 03:17:0915604 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615605 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415606 // Send headers successfully, but get an error while sending the body.
15607 MockWrite data_writes[] = {
15608 MockWrite("POST / HTTP/1.1\r\n"
15609 "Host: www.foo.com\r\n"
15610 "Connection: keep-alive\r\n"
15611 "Transfer-Encoding: chunked\r\n\r\n"),
15612 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15613 };
15614
15615 MockRead data_reads[] = {
15616 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15617 MockRead("hello world"),
15618 MockRead(SYNCHRONOUS, OK),
15619 };
15620 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15621 arraysize(data_writes));
15622 session_deps_.socket_factory->AddSocketDataProvider(&data);
15623
15624 TestCompletionCallback callback;
15625
tfarina42834112016-09-22 13:38:2015626 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115627 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415628 // Make sure the headers are sent before adding a chunk. This ensures that
15629 // they can't be merged with the body in a single send. Not currently
15630 // necessary since a chunked body is never merged with headers, but this makes
15631 // the test more future proof.
15632 base::RunLoop().RunUntilIdle();
15633
mmenkecbc2b712014-10-09 20:29:0715634 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415635
15636 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115637 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415638
bnc691fda62016-08-12 00:43:1615639 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215640 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415641
wezca1070932016-05-26 20:30:5215642 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415643 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15644
15645 std::string response_data;
bnc691fda62016-08-12 00:43:1615646 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115647 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415648 EXPECT_EQ("hello world", response_data);
15649}
15650
bncd16676a2016-07-20 16:23:0115651TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915652 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215653 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715654 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215655 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415656
15657 HttpRequestInfo request;
15658 request.method = "POST";
15659 request.url = GURL("http://www.foo.com/");
15660 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415661
danakj1fd259a02016-04-16 03:17:0915662 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615663 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415664
15665 MockWrite data_writes[] = {
15666 MockWrite("POST / HTTP/1.1\r\n"
15667 "Host: www.foo.com\r\n"
15668 "Connection: keep-alive\r\n"
15669 "Content-Length: 3\r\n\r\n"),
15670 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15671 };
15672
15673 MockRead data_reads[] = {
15674 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15675 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15676 MockRead("hello world"),
15677 MockRead(SYNCHRONOUS, OK),
15678 };
15679 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15680 arraysize(data_writes));
15681 session_deps_.socket_factory->AddSocketDataProvider(&data);
15682
15683 TestCompletionCallback callback;
15684
tfarina42834112016-09-22 13:38:2015685 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415687
15688 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115689 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415690
bnc691fda62016-08-12 00:43:1615691 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5215692 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415693
wezca1070932016-05-26 20:30:5215694 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415695 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15696
15697 std::string response_data;
bnc691fda62016-08-12 00:43:1615698 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0115699 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5415700 EXPECT_EQ("hello world", response_data);
15701}
15702
bncd16676a2016-07-20 16:23:0115703TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915704 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215705 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715706 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215707 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415708
15709 HttpRequestInfo request;
15710 request.method = "POST";
15711 request.url = GURL("http://www.foo.com/");
15712 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415713
danakj1fd259a02016-04-16 03:17:0915714 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615715 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415716 // Send headers successfully, but get an error while sending the body.
15717 MockWrite data_writes[] = {
15718 MockWrite("POST / HTTP/1.1\r\n"
15719 "Host: www.foo.com\r\n"
15720 "Connection: keep-alive\r\n"
15721 "Content-Length: 3\r\n\r\n"),
15722 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15723 };
15724
15725 MockRead data_reads[] = {
15726 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15727 MockRead("hello world"),
15728 MockRead(SYNCHRONOUS, OK),
15729 };
15730 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15731 arraysize(data_writes));
15732 session_deps_.socket_factory->AddSocketDataProvider(&data);
15733
15734 TestCompletionCallback callback;
15735
tfarina42834112016-09-22 13:38:2015736 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115737 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415738
15739 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115740 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415741}
15742
bncd16676a2016-07-20 16:23:0115743TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5415744 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915745 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215746 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715747 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215748 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415749
15750 HttpRequestInfo request;
15751 request.method = "POST";
15752 request.url = GURL("http://www.foo.com/");
15753 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415754
danakj1fd259a02016-04-16 03:17:0915755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615756 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415757 // Send headers successfully, but get an error while sending the body.
15758 MockWrite data_writes[] = {
15759 MockWrite("POST / HTTP/1.1\r\n"
15760 "Host: www.foo.com\r\n"
15761 "Connection: keep-alive\r\n"
15762 "Content-Length: 3\r\n\r\n"),
15763 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15764 };
15765
15766 MockRead data_reads[] = {
15767 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15768 MockRead("HTTP/1.0 302 Redirect\r\n"),
15769 MockRead("Location: http://somewhere-else.com/\r\n"),
15770 MockRead("Content-Length: 0\r\n\r\n"),
15771 MockRead(SYNCHRONOUS, OK),
15772 };
15773 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15774 arraysize(data_writes));
15775 session_deps_.socket_factory->AddSocketDataProvider(&data);
15776
15777 TestCompletionCallback callback;
15778
tfarina42834112016-09-22 13:38:2015779 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415781
15782 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115783 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415784}
15785
bncd16676a2016-07-20 16:23:0115786TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915787 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215788 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715789 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215790 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415791
15792 HttpRequestInfo request;
15793 request.method = "POST";
15794 request.url = GURL("http://www.foo.com/");
15795 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415796
danakj1fd259a02016-04-16 03:17:0915797 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615798 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415799 // Send headers successfully, but get an error while sending the body.
15800 MockWrite data_writes[] = {
15801 MockWrite("POST / HTTP/1.1\r\n"
15802 "Host: www.foo.com\r\n"
15803 "Connection: keep-alive\r\n"
15804 "Content-Length: 3\r\n\r\n"),
15805 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15806 };
15807
15808 MockRead data_reads[] = {
15809 MockRead("HTTP 0.9 rocks!"),
15810 MockRead(SYNCHRONOUS, OK),
15811 };
15812 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15813 arraysize(data_writes));
15814 session_deps_.socket_factory->AddSocketDataProvider(&data);
15815
15816 TestCompletionCallback callback;
15817
tfarina42834112016-09-22 13:38:2015818 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115819 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415820
15821 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115822 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415823}
15824
bncd16676a2016-07-20 16:23:0115825TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0915826 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215827 element_readers.push_back(
ricea2deef682016-09-09 08:04:0715828 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2215829 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415830
15831 HttpRequestInfo request;
15832 request.method = "POST";
15833 request.url = GURL("http://www.foo.com/");
15834 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5415835
danakj1fd259a02016-04-16 03:17:0915836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5415838 // Send headers successfully, but get an error while sending the body.
15839 MockWrite data_writes[] = {
15840 MockWrite("POST / HTTP/1.1\r\n"
15841 "Host: www.foo.com\r\n"
15842 "Connection: keep-alive\r\n"
15843 "Content-Length: 3\r\n\r\n"),
15844 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15845 };
15846
15847 MockRead data_reads[] = {
15848 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15849 MockRead(SYNCHRONOUS, OK),
15850 };
15851 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15852 arraysize(data_writes));
15853 session_deps_.socket_factory->AddSocketDataProvider(&data);
15854
15855 TestCompletionCallback callback;
15856
tfarina42834112016-09-22 13:38:2015857 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115858 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5415859
15860 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115861 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5415862}
15863
Adam Rice425cf122015-01-19 06:18:2415864// Verify that proxy headers are not sent to the destination server when
15865// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0115866TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2415867 HttpRequestInfo request;
15868 request.method = "GET";
bncce36dca22015-04-21 22:11:2315869 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415870 AddWebSocketHeaders(&request.extra_headers);
15871
15872 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315873 session_deps_.proxy_service =
15874 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415875
danakj1fd259a02016-04-16 03:17:0915876 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415877
15878 // Since a proxy is configured, try to establish a tunnel.
15879 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1715880 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15881 "Host: www.example.org:443\r\n"
15882 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415883
15884 // After calling trans->RestartWithAuth(), this is the request we should
15885 // be issuing -- the final header line contains the credentials.
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"
15889 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415890
rsleevidb16bb02015-11-12 23:47:1715891 MockWrite("GET / HTTP/1.1\r\n"
15892 "Host: www.example.org\r\n"
15893 "Connection: Upgrade\r\n"
15894 "Upgrade: websocket\r\n"
15895 "Origin: http://www.example.org\r\n"
15896 "Sec-WebSocket-Version: 13\r\n"
15897 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415898 };
15899
15900 // The proxy responds to the connect with a 407, using a persistent
15901 // connection.
15902 MockRead data_reads[] = {
15903 // No credentials.
15904 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15905 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415906 MockRead("Content-Length: 0\r\n"),
15907 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415908
15909 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15910
15911 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15912 MockRead("Upgrade: websocket\r\n"),
15913 MockRead("Connection: Upgrade\r\n"),
15914 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15915 };
15916
15917 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15918 arraysize(data_writes));
15919 session_deps_.socket_factory->AddSocketDataProvider(&data);
15920 SSLSocketDataProvider ssl(ASYNC, OK);
15921 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15922
bnc691fda62016-08-12 00:43:1615923 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415924 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15925 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15926 trans->SetWebSocketHandshakeStreamCreateHelper(
15927 &websocket_stream_create_helper);
15928
15929 {
15930 TestCompletionCallback callback;
15931
tfarina42834112016-09-22 13:38:2015932 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115933 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2415934
15935 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115936 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2415937 }
15938
15939 const HttpResponseInfo* response = trans->GetResponseInfo();
15940 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215941 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415942 EXPECT_EQ(407, response->headers->response_code());
15943
15944 {
15945 TestCompletionCallback callback;
15946
15947 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15948 callback.callback());
robpercival214763f2016-07-01 23:27:0115949 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2415950
15951 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115952 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2415953 }
15954
15955 response = trans->GetResponseInfo();
15956 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215957 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415958
15959 EXPECT_EQ(101, response->headers->response_code());
15960
15961 trans.reset();
15962 session->CloseAllConnections();
15963}
15964
15965// Verify that proxy headers are not sent to the destination server when
15966// establishing a tunnel for an insecure WebSocket connection.
15967// This requires the authentication info to be injected into the auth cache
15968// due to crbug.com/395064
15969// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0115970TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2415971 HttpRequestInfo request;
15972 request.method = "GET";
bncce36dca22015-04-21 22:11:2315973 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415974 AddWebSocketHeaders(&request.extra_headers);
15975
15976 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315977 session_deps_.proxy_service =
15978 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415979
danakj1fd259a02016-04-16 03:17:0915980 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415981
15982 MockWrite data_writes[] = {
15983 // Try to establish a tunnel for the WebSocket connection, with
15984 // credentials. Because WebSockets have a separate set of socket pools,
15985 // they cannot and will not use the same TCP/IP connection as the
15986 // preflight HTTP request.
15987 MockWrite(
bncce36dca22015-04-21 22:11:2315988 "CONNECT www.example.org:80 HTTP/1.1\r\n"
15989 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2415990 "Proxy-Connection: keep-alive\r\n"
15991 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15992
15993 MockWrite(
15994 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315995 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415996 "Connection: Upgrade\r\n"
15997 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315998 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415999 "Sec-WebSocket-Version: 13\r\n"
16000 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16001 };
16002
16003 MockRead data_reads[] = {
16004 // HTTP CONNECT with credentials.
16005 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16006
16007 // WebSocket connection established inside tunnel.
16008 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16009 MockRead("Upgrade: websocket\r\n"),
16010 MockRead("Connection: Upgrade\r\n"),
16011 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16012 };
16013
16014 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16015 arraysize(data_writes));
16016 session_deps_.socket_factory->AddSocketDataProvider(&data);
16017
16018 session->http_auth_cache()->Add(
16019 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16020 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16021
bnc691fda62016-08-12 00:43:1616022 std::unique_ptr<HttpNetworkTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2416023 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16024 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16025 trans->SetWebSocketHandshakeStreamCreateHelper(
16026 &websocket_stream_create_helper);
16027
16028 TestCompletionCallback callback;
16029
tfarina42834112016-09-22 13:38:2016030 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116031 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416032
16033 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116034 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416035
16036 const HttpResponseInfo* response = trans->GetResponseInfo();
16037 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216038 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416039
16040 EXPECT_EQ(101, response->headers->response_code());
16041
16042 trans.reset();
16043 session->CloseAllConnections();
16044}
16045
bncd16676a2016-07-20 16:23:0116046TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916047 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216048 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716049 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216050 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216051
16052 HttpRequestInfo request;
16053 request.method = "POST";
16054 request.url = GURL("http://www.foo.com/");
16055 request.upload_data_stream = &upload_data_stream;
16056
danakj1fd259a02016-04-16 03:17:0916057 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616058 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216059 MockWrite data_writes[] = {
16060 MockWrite("POST / HTTP/1.1\r\n"
16061 "Host: www.foo.com\r\n"
16062 "Connection: keep-alive\r\n"
16063 "Content-Length: 3\r\n\r\n"),
16064 MockWrite("foo"),
16065 };
16066
16067 MockRead data_reads[] = {
16068 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16069 MockRead(SYNCHRONOUS, OK),
16070 };
16071 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16072 arraysize(data_writes));
16073 session_deps_.socket_factory->AddSocketDataProvider(&data);
16074
16075 TestCompletionCallback callback;
16076
16077 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016078 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116079 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216080
16081 std::string response_data;
bnc691fda62016-08-12 00:43:1616082 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216083
16084 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616085 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216086 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616087 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216088}
16089
bncd16676a2016-07-20 16:23:0116090TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916091 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216092 element_readers.push_back(
ricea2deef682016-09-09 08:04:0716093 base::MakeUnique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216094 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216095
16096 HttpRequestInfo request;
16097 request.method = "POST";
16098 request.url = GURL("http://www.foo.com/");
16099 request.upload_data_stream = &upload_data_stream;
16100
danakj1fd259a02016-04-16 03:17:0916101 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616102 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216103 MockWrite data_writes[] = {
16104 MockWrite("POST / HTTP/1.1\r\n"
16105 "Host: www.foo.com\r\n"
16106 "Connection: keep-alive\r\n"
16107 "Content-Length: 3\r\n\r\n"),
16108 MockWrite("foo"),
16109 };
16110
16111 MockRead data_reads[] = {
16112 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16113 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16114 MockRead(SYNCHRONOUS, OK),
16115 };
16116 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16117 arraysize(data_writes));
16118 session_deps_.socket_factory->AddSocketDataProvider(&data);
16119
16120 TestCompletionCallback callback;
16121
16122 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016123 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116124 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216125
16126 std::string response_data;
bnc691fda62016-08-12 00:43:1616127 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216128
16129 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616130 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216131 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616132 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216133}
16134
bncd16676a2016-07-20 16:23:0116135TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216136 ChunkedUploadDataStream upload_data_stream(0);
16137
16138 HttpRequestInfo request;
16139 request.method = "POST";
16140 request.url = GURL("http://www.foo.com/");
16141 request.upload_data_stream = &upload_data_stream;
16142
danakj1fd259a02016-04-16 03:17:0916143 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616144 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216145 // Send headers successfully, but get an error while sending the body.
16146 MockWrite data_writes[] = {
16147 MockWrite("POST / HTTP/1.1\r\n"
16148 "Host: www.foo.com\r\n"
16149 "Connection: keep-alive\r\n"
16150 "Transfer-Encoding: chunked\r\n\r\n"),
16151 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16152 };
16153
16154 MockRead data_reads[] = {
16155 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16156 MockRead(SYNCHRONOUS, OK),
16157 };
16158 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16159 arraysize(data_writes));
16160 session_deps_.socket_factory->AddSocketDataProvider(&data);
16161
16162 TestCompletionCallback callback;
16163
16164 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016165 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216166
16167 base::RunLoop().RunUntilIdle();
16168 upload_data_stream.AppendData("f", 1, false);
16169
16170 base::RunLoop().RunUntilIdle();
16171 upload_data_stream.AppendData("oo", 2, true);
16172
robpercival214763f2016-07-01 23:27:0116173 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216174
16175 std::string response_data;
bnc691fda62016-08-12 00:43:1616176 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216177
16178 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616179 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216180 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616181 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216182}
16183
rdsmith1d343be52016-10-21 20:37:5016184// Confirm that transactions whose throttle is created in (and stays in)
16185// the unthrottled state are not blocked.
16186TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16187 TestNetworkStreamThrottler* throttler(nullptr);
16188 std::unique_ptr<HttpNetworkSession> session(
16189 CreateSessionWithThrottler(&session_deps_, &throttler));
16190
16191 // Send a simple request and make sure it goes through.
16192 HttpRequestInfo request;
16193 request.method = "GET";
16194 request.url = GURL("http://www.example.org/");
16195
16196 std::unique_ptr<HttpTransaction> trans(
16197 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16198
16199 MockWrite data_writes[] = {
16200 MockWrite("GET / HTTP/1.1\r\n"
16201 "Host: www.example.org\r\n"
16202 "Connection: keep-alive\r\n\r\n"),
16203 };
16204 MockRead data_reads[] = {
16205 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16206 MockRead(SYNCHRONOUS, OK),
16207 };
16208 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16209 arraysize(data_writes));
16210 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16211
16212 TestCompletionCallback callback;
16213 trans->Start(&request, callback.callback(), NetLogWithSource());
16214 EXPECT_EQ(OK, callback.WaitForResult());
16215}
16216
16217// Confirm requests can be blocked by a throttler, and are resumed
16218// when the throttle is unblocked.
16219TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16220 TestNetworkStreamThrottler* throttler(nullptr);
16221 std::unique_ptr<HttpNetworkSession> session(
16222 CreateSessionWithThrottler(&session_deps_, &throttler));
16223
16224 // Send a simple request and make sure it goes through.
16225 HttpRequestInfo request;
16226 request.method = "GET";
16227 request.url = GURL("http://www.example.org/");
16228
16229 MockWrite data_writes[] = {
16230 MockWrite("GET / HTTP/1.1\r\n"
16231 "Host: www.example.org\r\n"
16232 "Connection: keep-alive\r\n\r\n"),
16233 };
16234 MockRead data_reads[] = {
16235 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16236 MockRead(SYNCHRONOUS, OK),
16237 };
16238 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16239 arraysize(data_writes));
16240 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16241
16242 // Start a request that will be throttled at start; confirm it
16243 // doesn't complete.
16244 throttler->set_throttle_new_requests(true);
16245 std::unique_ptr<HttpTransaction> trans(
16246 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16247
16248 TestCompletionCallback callback;
16249 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16250 EXPECT_EQ(ERR_IO_PENDING, rv);
16251
16252 base::RunLoop().RunUntilIdle();
16253 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16254 EXPECT_FALSE(callback.have_result());
16255
16256 // Confirm the request goes on to complete when unthrottled.
16257 throttler->UnthrottleAllRequests();
16258 base::RunLoop().RunUntilIdle();
16259 ASSERT_TRUE(callback.have_result());
16260 EXPECT_EQ(OK, callback.WaitForResult());
16261}
16262
16263// Destroy a request while it's throttled.
16264TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16265 TestNetworkStreamThrottler* throttler(nullptr);
16266 std::unique_ptr<HttpNetworkSession> session(
16267 CreateSessionWithThrottler(&session_deps_, &throttler));
16268
16269 // Send a simple request and make sure it goes through.
16270 HttpRequestInfo request;
16271 request.method = "GET";
16272 request.url = GURL("http://www.example.org/");
16273
16274 MockWrite data_writes[] = {
16275 MockWrite("GET / HTTP/1.1\r\n"
16276 "Host: www.example.org\r\n"
16277 "Connection: keep-alive\r\n\r\n"),
16278 };
16279 MockRead data_reads[] = {
16280 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16281 MockRead(SYNCHRONOUS, OK),
16282 };
16283 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16284 arraysize(data_writes));
16285 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16286
16287 // Start a request that will be throttled at start; confirm it
16288 // doesn't complete.
16289 throttler->set_throttle_new_requests(true);
16290 std::unique_ptr<HttpTransaction> trans(
16291 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16292
16293 TestCompletionCallback callback;
16294 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16295 EXPECT_EQ(ERR_IO_PENDING, rv);
16296
16297 base::RunLoop().RunUntilIdle();
16298 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16299 EXPECT_FALSE(callback.have_result());
16300
16301 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16302 trans.reset();
16303 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16304}
16305
16306// Confirm the throttler receives SetPriority calls.
16307TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16308 TestNetworkStreamThrottler* throttler(nullptr);
16309 std::unique_ptr<HttpNetworkSession> session(
16310 CreateSessionWithThrottler(&session_deps_, &throttler));
16311
16312 // Send a simple request and make sure it goes through.
16313 HttpRequestInfo request;
16314 request.method = "GET";
16315 request.url = GURL("http://www.example.org/");
16316
16317 MockWrite data_writes[] = {
16318 MockWrite("GET / HTTP/1.1\r\n"
16319 "Host: www.example.org\r\n"
16320 "Connection: keep-alive\r\n\r\n"),
16321 };
16322 MockRead data_reads[] = {
16323 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16324 MockRead(SYNCHRONOUS, OK),
16325 };
16326 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16327 arraysize(data_writes));
16328 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16329
16330 throttler->set_throttle_new_requests(true);
16331 std::unique_ptr<HttpTransaction> trans(
16332 new HttpNetworkTransaction(IDLE, session.get()));
16333 // Start the transaction to associate a throttle with it.
16334 TestCompletionCallback callback;
16335 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16336 EXPECT_EQ(ERR_IO_PENDING, rv);
16337
16338 EXPECT_EQ(0, throttler->num_set_priority_calls());
16339 trans->SetPriority(LOW);
16340 EXPECT_EQ(1, throttler->num_set_priority_calls());
16341 EXPECT_EQ(LOW, throttler->last_priority_set());
16342
16343 throttler->UnthrottleAllRequests();
16344 base::RunLoop().RunUntilIdle();
16345 ASSERT_TRUE(callback.have_result());
16346 EXPECT_EQ(OK, callback.WaitForResult());
16347}
16348
16349// Confirm that unthrottling from a SetPriority call by the
16350// throttler works properly.
16351TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16352 TestNetworkStreamThrottler* throttler(nullptr);
16353 std::unique_ptr<HttpNetworkSession> session(
16354 CreateSessionWithThrottler(&session_deps_, &throttler));
16355
16356 // Send a simple request and make sure it goes through.
16357 HttpRequestInfo request;
16358 request.method = "GET";
16359 request.url = GURL("http://www.example.org/");
16360
16361 MockWrite data_writes[] = {
16362 MockWrite("GET / HTTP/1.1\r\n"
16363 "Host: www.example.org\r\n"
16364 "Connection: keep-alive\r\n\r\n"),
16365 };
16366 MockRead data_reads[] = {
16367 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16368 MockRead(SYNCHRONOUS, OK),
16369 };
16370 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16371 arraysize(data_writes));
16372 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16373
16374 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16375 data_writes, arraysize(data_writes));
16376 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16377
16378 // Start a request that will be throttled at start; confirm it
16379 // doesn't complete.
16380 throttler->set_throttle_new_requests(true);
16381 std::unique_ptr<HttpTransaction> trans(
16382 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16383
16384 TestCompletionCallback callback;
16385 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16386 EXPECT_EQ(ERR_IO_PENDING, rv);
16387
16388 base::RunLoop().RunUntilIdle();
16389 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16390 EXPECT_FALSE(callback.have_result());
16391
16392 // Create a new request, call SetPriority on it to unthrottle,
16393 // and make sure that allows the original request to complete.
16394 std::unique_ptr<HttpTransaction> trans1(
16395 new HttpNetworkTransaction(LOW, session.get()));
16396 throttler->set_priority_change_closure(
16397 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
16398 base::Unretained(throttler)));
16399
16400 // Start the transaction to associate a throttle with it.
16401 TestCompletionCallback callback1;
16402 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
16403 EXPECT_EQ(ERR_IO_PENDING, rv);
16404
16405 trans1->SetPriority(IDLE);
16406
16407 base::RunLoop().RunUntilIdle();
16408 ASSERT_TRUE(callback.have_result());
16409 EXPECT_EQ(OK, callback.WaitForResult());
16410 ASSERT_TRUE(callback1.have_result());
16411 EXPECT_EQ(OK, callback1.WaitForResult());
16412}
16413
16414// Transaction will be destroyed when the unique_ptr goes out of scope.
16415void DestroyTransaction(std::unique_ptr<HttpTransaction> transaction) {}
16416
16417// Confirm that destroying a transaction from a SetPriority call by the
16418// throttler works properly.
16419TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
16420 TestNetworkStreamThrottler* throttler(nullptr);
16421 std::unique_ptr<HttpNetworkSession> session(
16422 CreateSessionWithThrottler(&session_deps_, &throttler));
16423
16424 // Send a simple request and make sure it goes through.
16425 HttpRequestInfo request;
16426 request.method = "GET";
16427 request.url = GURL("http://www.example.org/");
16428
16429 MockWrite data_writes[] = {
16430 MockWrite("GET / HTTP/1.1\r\n"
16431 "Host: www.example.org\r\n"
16432 "Connection: keep-alive\r\n\r\n"),
16433 };
16434 MockRead data_reads[] = {
16435 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16436 MockRead(SYNCHRONOUS, OK),
16437 };
16438 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16439 arraysize(data_writes));
16440 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16441
16442 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16443 data_writes, arraysize(data_writes));
16444 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16445
16446 // Start a request that will be throttled at start; confirm it
16447 // doesn't complete.
16448 throttler->set_throttle_new_requests(true);
16449 std::unique_ptr<HttpTransaction> trans(
16450 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16451
16452 TestCompletionCallback callback;
16453 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16454 EXPECT_EQ(ERR_IO_PENDING, rv);
16455
16456 base::RunLoop().RunUntilIdle();
16457 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16458 EXPECT_FALSE(callback.have_result());
16459
16460 // Arrange for the set priority call on the above transaction to delete
16461 // the transaction.
16462 HttpTransaction* trans_ptr(trans.get());
16463 throttler->set_priority_change_closure(
16464 base::Bind(&DestroyTransaction, base::Passed(&trans)));
16465
16466 // Call it and check results (partially a "doesn't crash" test).
16467 trans_ptr->SetPriority(IDLE);
16468 trans_ptr = nullptr; // No longer a valid pointer.
16469
16470 base::RunLoop().RunUntilIdle();
16471 ASSERT_FALSE(callback.have_result());
16472}
16473
nharperb7441ef2016-01-25 23:54:1416474#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0116475TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1416476 const std::string https_url = "https://www.example.com";
16477 HttpRequestInfo request;
16478 request.url = GURL(https_url);
16479 request.method = "GET";
16480
16481 SSLSocketDataProvider ssl(ASYNC, OK);
16482 ssl.token_binding_negotiated = true;
16483 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3616484 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1416485 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16486
bnc42331402016-07-25 13:36:1516487 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4116488 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
16489 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1416490 MockRead(ASYNC, ERR_IO_PENDING)};
16491 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16492 session_deps_.socket_factory->AddSocketDataProvider(&data);
16493 session_deps_.channel_id_service.reset(new ChannelIDService(
16494 new DefaultChannelIDStore(nullptr), base::ThreadTaskRunnerHandle::Get()));
danakj1fd259a02016-04-16 03:17:0916495 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416496
16497 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16498 TestCompletionCallback callback;
16499 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016500 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516501 base::RunLoop().RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416502
16503 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16504 HttpRequestHeaders headers;
16505 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16506 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16507}
16508#endif // !defined(OS_IOS)
16509
[email protected]89ceba9a2009-03-21 03:46:0616510} // namespace net