blob: aea3ec4b7c9eff1583d1843adc810d3700eeddf8 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "build/build_config.h"
6
7#if defined(OS_WIN)
8#include <windows.h>
9#include <shlobj.h>
10#endif
11
12#include <algorithm>
13#include <string>
14
15#include "base/basictypes.h"
16#include "base/bind.h"
17#include "base/compiler_specific.h"
18#include "base/file_util.h"
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000019#include "base/files/scoped_temp_dir.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000020#include "base/format_macros.h"
21#include "base/memory/weak_ptr.h"
Ben Murdoch9ab55632013-07-18 11:57:30 +010022#include "base/message_loop/message_loop.h"
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +010023#include "base/message_loop/message_loop_proxy.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000024#include "base/path_service.h"
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +010025#include "base/run_loop.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010026#include "base/strings/string_number_conversions.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010027#include "base/strings/string_piece.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000028#include "base/strings/string_split.h"
Ben Murdoch9ab55632013-07-18 11:57:30 +010029#include "base/strings/string_util.h"
30#include "base/strings/stringprintf.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010031#include "base/strings/utf_string_conversions.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000032#include "net/base/capturing_net_log.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000033#include "net/base/load_flags.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000034#include "net/base/load_timing_info.h"
35#include "net/base/load_timing_info_test_util.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000036#include "net/base/net_errors.h"
37#include "net/base/net_log.h"
38#include "net/base/net_log_unittest.h"
39#include "net/base/net_module.h"
40#include "net/base/net_util.h"
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +000041#include "net/base/request_priority.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000042#include "net/base/test_data_directory.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000043#include "net/base/upload_bytes_element_reader.h"
44#include "net/base/upload_data_stream.h"
45#include "net/base/upload_file_element_reader.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010046#include "net/cert/ev_root_ca_metadata.h"
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000047#include "net/cert/mock_cert_verifier.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010048#include "net/cert/test_root_certs.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000049#include "net/cookies/cookie_monster.h"
50#include "net/cookies/cookie_store_test_helpers.h"
51#include "net/disk_cache/disk_cache.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000052#include "net/dns/mock_host_resolver.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000053#include "net/ftp/ftp_network_layer.h"
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000054#include "net/http/http_byte_range.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000055#include "net/http/http_cache.h"
56#include "net/http/http_network_layer.h"
57#include "net/http/http_network_session.h"
58#include "net/http/http_request_headers.h"
59#include "net/http/http_response_headers.h"
Ben Murdocheffb81e2014-03-31 11:51:25 +010060#include "net/http/http_util.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000061#include "net/ocsp/nss_ocsp.h"
62#include "net/proxy/proxy_service.h"
63#include "net/socket/ssl_client_socket.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000064#include "net/ssl/ssl_connection_status_flags.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010065#include "net/test/cert_test_util.h"
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +010066#include "net/test/spawned_test_server/spawned_test_server.h"
67#include "net/url_request/data_protocol_handler.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000068#include "net/url_request/static_http_user_agent_settings.h"
69#include "net/url_request/url_request.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000070#include "net/url_request/url_request_http_job.h"
71#include "net/url_request/url_request_job_factory_impl.h"
72#include "net/url_request/url_request_redirect_job.h"
73#include "net/url_request/url_request_test_job.h"
74#include "net/url_request/url_request_test_util.h"
75#include "testing/gtest/include/gtest/gtest.h"
76#include "testing/platform_test.h"
77
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +010078#if !defined(DISABLE_FILE_SUPPORT)
Torne (Richard Coles)cedac222014-06-03 10:58:34 +010079#include "net/base/filename_util.h"
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +010080#include "net/url_request/file_protocol_handler.h"
81#include "net/url_request/url_request_file_dir_job.h"
82#endif
83
84#if !defined(DISABLE_FTP_SUPPORT)
85#include "net/url_request/ftp_protocol_handler.h"
86#endif
87
Torne (Richard Coles)58218062012-11-14 11:43:16 +000088#if defined(OS_WIN)
89#include "base/win/scoped_com_initializer.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010090#include "base/win/scoped_comptr.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000091#include "base/win/windows_version.h"
92#endif
93
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000094using base::ASCIIToUTF16;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000095using base::Time;
96
97namespace net {
98
99namespace {
100
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100101const base::string16 kChrome(ASCIIToUTF16("chrome"));
102const base::string16 kSecret(ASCIIToUTF16("secret"));
103const base::string16 kUser(ASCIIToUTF16("user"));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000104
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100105// Tests load timing information in the case a fresh connection was used, with
106// no proxy.
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100107void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000108 int connect_timing_flags) {
109 EXPECT_FALSE(load_timing_info.socket_reused);
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100110 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000111
112 EXPECT_FALSE(load_timing_info.request_start_time.is_null());
113 EXPECT_FALSE(load_timing_info.request_start.is_null());
114
115 EXPECT_LE(load_timing_info.request_start,
116 load_timing_info.connect_timing.connect_start);
117 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
118 connect_timing_flags);
119 EXPECT_LE(load_timing_info.connect_timing.connect_end,
120 load_timing_info.send_start);
121 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
122 EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end);
123
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000124 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
125 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
126}
127
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100128// Same as above, but with proxy times.
129void TestLoadTimingNotReusedWithProxy(
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100130 const LoadTimingInfo& load_timing_info,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100131 int connect_timing_flags) {
132 EXPECT_FALSE(load_timing_info.socket_reused);
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100133 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100134
135 EXPECT_FALSE(load_timing_info.request_start_time.is_null());
136 EXPECT_FALSE(load_timing_info.request_start.is_null());
137
138 EXPECT_LE(load_timing_info.request_start,
139 load_timing_info.proxy_resolve_start);
140 EXPECT_LE(load_timing_info.proxy_resolve_start,
141 load_timing_info.proxy_resolve_end);
142 EXPECT_LE(load_timing_info.proxy_resolve_end,
143 load_timing_info.connect_timing.connect_start);
144 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
145 connect_timing_flags);
146 EXPECT_LE(load_timing_info.connect_timing.connect_end,
147 load_timing_info.send_start);
148 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
149 EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end);
150}
151
152// Same as above, but with a reused socket and proxy times.
153void TestLoadTimingReusedWithProxy(
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100154 const LoadTimingInfo& load_timing_info) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100155 EXPECT_TRUE(load_timing_info.socket_reused);
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100156 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100157
158 EXPECT_FALSE(load_timing_info.request_start_time.is_null());
159 EXPECT_FALSE(load_timing_info.request_start.is_null());
160
161 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
162
163 EXPECT_LE(load_timing_info.request_start,
164 load_timing_info.proxy_resolve_start);
165 EXPECT_LE(load_timing_info.proxy_resolve_start,
166 load_timing_info.proxy_resolve_end);
167 EXPECT_LE(load_timing_info.proxy_resolve_end,
168 load_timing_info.send_start);
169 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
170 EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end);
171}
172
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100173// Tests load timing information in the case of a cache hit, when no cache
174// validation request was sent over the wire.
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000175base::StringPiece TestNetResourceProvider(int key) {
176 return "header";
177}
178
179void FillBuffer(char* buffer, size_t len) {
180 static bool called = false;
181 if (!called) {
182 called = true;
183 int seed = static_cast<int>(Time::Now().ToInternalValue());
184 srand(seed);
185 }
186
187 for (size_t i = 0; i < len; i++) {
188 buffer[i] = static_cast<char>(rand());
189 if (!buffer[i])
190 buffer[i] = 'g';
191 }
192}
193
194#if !defined(OS_IOS)
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100195void TestLoadTimingCacheHitNoNetwork(
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100196 const LoadTimingInfo& load_timing_info) {
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100197 EXPECT_FALSE(load_timing_info.socket_reused);
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100198 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100199
200 EXPECT_FALSE(load_timing_info.request_start_time.is_null());
201 EXPECT_FALSE(load_timing_info.request_start.is_null());
202
203 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
204 EXPECT_LE(load_timing_info.request_start, load_timing_info.send_start);
205 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
206 EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end);
207
208 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
209 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
210}
211
212// Tests load timing in the case that there is no HTTP response. This can be
213// used to test in the case of errors or non-HTTP requests.
214void TestLoadTimingNoHttpResponse(
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100215 const LoadTimingInfo& load_timing_info) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000216 EXPECT_FALSE(load_timing_info.socket_reused);
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100217 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000218
219 // Only the request times should be non-null.
220 EXPECT_FALSE(load_timing_info.request_start_time.is_null());
221 EXPECT_FALSE(load_timing_info.request_start.is_null());
222
223 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
224
225 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
226 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
227 EXPECT_TRUE(load_timing_info.send_start.is_null());
228 EXPECT_TRUE(load_timing_info.send_end.is_null());
229 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
230}
231
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000232// Do a case-insensitive search through |haystack| for |needle|.
233bool ContainsString(const std::string& haystack, const char* needle) {
234 std::string::const_iterator it =
235 std::search(haystack.begin(),
236 haystack.end(),
237 needle,
238 needle + strlen(needle),
239 base::CaseInsensitiveCompare<char>());
240 return it != haystack.end();
241}
242
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000243UploadDataStream* CreateSimpleUploadData(const char* data) {
244 scoped_ptr<UploadElementReader> reader(
245 new UploadBytesElementReader(data, strlen(data)));
246 return UploadDataStream::CreateWithReader(reader.Pass(), 0);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000247}
248
249// Verify that the SSLInfo of a successful SSL connection has valid values.
250void CheckSSLInfo(const SSLInfo& ssl_info) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000251 // -1 means unknown. 0 means no encryption.
252 EXPECT_GT(ssl_info.security_bits, 0);
253
254 // The cipher suite TLS_NULL_WITH_NULL_NULL (0) must not be negotiated.
255 int cipher_suite = SSLConnectionStatusToCipherSuite(
256 ssl_info.connection_status);
257 EXPECT_NE(0, cipher_suite);
258}
259
Ben Murdocheb525c52013-07-10 11:40:50 +0100260void CheckFullRequestHeaders(const HttpRequestHeaders& headers,
261 const GURL& host_url) {
262 std::string sent_value;
263
264 EXPECT_TRUE(headers.GetHeader("Host", &sent_value));
265 EXPECT_EQ(GetHostAndOptionalPort(host_url), sent_value);
266
267 EXPECT_TRUE(headers.GetHeader("Connection", &sent_value));
268 EXPECT_EQ("keep-alive", sent_value);
269}
270
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000271bool FingerprintsEqual(const HashValueVector& a, const HashValueVector& b) {
272 size_t size = a.size();
273
274 if (size != b.size())
275 return false;
276
277 for (size_t i = 0; i < size; ++i) {
278 if (!a[i].Equals(b[i]))
279 return false;
280 }
281
282 return true;
283}
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000284#endif // !defined(OS_IOS)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000285
286// A network delegate that allows the user to choose a subset of request stages
287// to block in. When blocking, the delegate can do one of the following:
288// * synchronously return a pre-specified error code, or
289// * asynchronously return that value via an automatically called callback,
290// or
291// * block and wait for the user to do a callback.
292// Additionally, the user may also specify a redirect URL -- then each request
293// with the current URL different from the redirect target will be redirected
294// to that target, in the on-before-URL-request stage, independent of whether
295// the delegate blocks in ON_BEFORE_URL_REQUEST or not.
296class BlockingNetworkDelegate : public TestNetworkDelegate {
297 public:
298 // Stages in which the delegate can block.
299 enum Stage {
300 NOT_BLOCKED = 0,
301 ON_BEFORE_URL_REQUEST = 1 << 0,
302 ON_BEFORE_SEND_HEADERS = 1 << 1,
303 ON_HEADERS_RECEIVED = 1 << 2,
304 ON_AUTH_REQUIRED = 1 << 3
305 };
306
307 // Behavior during blocked stages. During other stages, just
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100308 // returns OK or NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000309 enum BlockMode {
310 SYNCHRONOUS, // No callback, returns specified return values.
311 AUTO_CALLBACK, // |this| posts a task to run the callback using the
312 // specified return codes.
313 USER_CALLBACK, // User takes care of doing a callback. |retval_| and
314 // |auth_retval_| are ignored. In every blocking stage the
315 // message loop is quit.
316 };
317
318 // Creates a delegate which does not block at all.
319 explicit BlockingNetworkDelegate(BlockMode block_mode);
320
321 // For users to trigger a callback returning |response|.
322 // Side-effects: resets |stage_blocked_for_callback_| and stored callbacks.
323 // Only call if |block_mode_| == USER_CALLBACK.
324 void DoCallback(int response);
325 void DoAuthCallback(NetworkDelegate::AuthRequiredResponse response);
326
327 // Setters.
328 void set_retval(int retval) {
329 ASSERT_NE(USER_CALLBACK, block_mode_);
330 ASSERT_NE(ERR_IO_PENDING, retval);
331 ASSERT_NE(OK, retval);
332 retval_ = retval;
333 }
334
335 // If |auth_retval| == AUTH_REQUIRED_RESPONSE_SET_AUTH, then
336 // |auth_credentials_| will be passed with the response.
337 void set_auth_retval(AuthRequiredResponse auth_retval) {
338 ASSERT_NE(USER_CALLBACK, block_mode_);
339 ASSERT_NE(AUTH_REQUIRED_RESPONSE_IO_PENDING, auth_retval);
340 auth_retval_ = auth_retval;
341 }
342 void set_auth_credentials(const AuthCredentials& auth_credentials) {
343 auth_credentials_ = auth_credentials;
344 }
345
346 void set_redirect_url(const GURL& url) {
347 redirect_url_ = url;
348 }
349
350 void set_block_on(int block_on) {
351 block_on_ = block_on;
352 }
353
354 // Allows the user to check in which state did we block.
355 Stage stage_blocked_for_callback() const {
356 EXPECT_EQ(USER_CALLBACK, block_mode_);
357 return stage_blocked_for_callback_;
358 }
359
360 private:
361 void RunCallback(int response, const CompletionCallback& callback);
362 void RunAuthCallback(AuthRequiredResponse response,
363 const AuthCallback& callback);
364
365 // TestNetworkDelegate implementation.
366 virtual int OnBeforeURLRequest(URLRequest* request,
367 const CompletionCallback& callback,
368 GURL* new_url) OVERRIDE;
369
370 virtual int OnBeforeSendHeaders(URLRequest* request,
371 const CompletionCallback& callback,
372 HttpRequestHeaders* headers) OVERRIDE;
373
374 virtual int OnHeadersReceived(
375 URLRequest* request,
376 const CompletionCallback& callback,
377 const HttpResponseHeaders* original_response_headers,
Ben Murdocheffb81e2014-03-31 11:51:25 +0100378 scoped_refptr<HttpResponseHeaders>* override_response_headers,
379 GURL* allowed_unsafe_redirect_url) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000380
381 virtual NetworkDelegate::AuthRequiredResponse OnAuthRequired(
382 URLRequest* request,
383 const AuthChallengeInfo& auth_info,
384 const AuthCallback& callback,
385 AuthCredentials* credentials) OVERRIDE;
386
387 // Resets the callbacks and |stage_blocked_for_callback_|.
388 void Reset();
389
390 // Checks whether we should block in |stage|. If yes, returns an error code
391 // and optionally sets up callback based on |block_mode_|. If no, returns OK.
392 int MaybeBlockStage(Stage stage, const CompletionCallback& callback);
393
394 // Configuration parameters, can be adjusted by public methods:
395 const BlockMode block_mode_;
396
397 // Values returned on blocking stages when mode is SYNCHRONOUS or
398 // AUTO_CALLBACK. For USER_CALLBACK these are set automatically to IO_PENDING.
399 int retval_; // To be returned in non-auth stages.
400 AuthRequiredResponse auth_retval_;
401
Ben Murdocheffb81e2014-03-31 11:51:25 +0100402 GURL redirect_url_; // Used if non-empty during OnBeforeURLRequest.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000403 int block_on_; // Bit mask: in which stages to block.
404
405 // |auth_credentials_| will be copied to |*target_auth_credential_| on
406 // callback.
407 AuthCredentials auth_credentials_;
408 AuthCredentials* target_auth_credentials_;
409
410 // Internal variables, not set by not the user:
411 // Last blocked stage waiting for user callback (unused if |block_mode_| !=
412 // USER_CALLBACK).
413 Stage stage_blocked_for_callback_;
414
415 // Callback objects stored during blocking stages.
416 CompletionCallback callback_;
417 AuthCallback auth_callback_;
418
419 base::WeakPtrFactory<BlockingNetworkDelegate> weak_factory_;
420
421 DISALLOW_COPY_AND_ASSIGN(BlockingNetworkDelegate);
422};
423
424BlockingNetworkDelegate::BlockingNetworkDelegate(BlockMode block_mode)
425 : block_mode_(block_mode),
426 retval_(OK),
427 auth_retval_(AUTH_REQUIRED_RESPONSE_NO_ACTION),
428 block_on_(0),
429 target_auth_credentials_(NULL),
430 stage_blocked_for_callback_(NOT_BLOCKED),
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100431 weak_factory_(this) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000432}
433
434void BlockingNetworkDelegate::DoCallback(int response) {
435 ASSERT_EQ(USER_CALLBACK, block_mode_);
436 ASSERT_NE(NOT_BLOCKED, stage_blocked_for_callback_);
437 ASSERT_NE(ON_AUTH_REQUIRED, stage_blocked_for_callback_);
438 CompletionCallback callback = callback_;
439 Reset();
440 RunCallback(response, callback);
441}
442
443void BlockingNetworkDelegate::DoAuthCallback(
444 NetworkDelegate::AuthRequiredResponse response) {
445 ASSERT_EQ(USER_CALLBACK, block_mode_);
446 ASSERT_EQ(ON_AUTH_REQUIRED, stage_blocked_for_callback_);
447 AuthCallback auth_callback = auth_callback_;
448 Reset();
449 RunAuthCallback(response, auth_callback);
450}
451
452void BlockingNetworkDelegate::RunCallback(int response,
453 const CompletionCallback& callback) {
454 callback.Run(response);
455}
456
457void BlockingNetworkDelegate::RunAuthCallback(AuthRequiredResponse response,
458 const AuthCallback& callback) {
459 if (auth_retval_ == AUTH_REQUIRED_RESPONSE_SET_AUTH) {
460 ASSERT_TRUE(target_auth_credentials_ != NULL);
461 *target_auth_credentials_ = auth_credentials_;
462 }
463 callback.Run(response);
464}
465
466int BlockingNetworkDelegate::OnBeforeURLRequest(
467 URLRequest* request,
468 const CompletionCallback& callback,
469 GURL* new_url) {
470 if (redirect_url_ == request->url())
471 return OK; // We've already seen this request and redirected elsewhere.
472
473 TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url);
474
475 if (!redirect_url_.is_empty())
476 *new_url = redirect_url_;
477
478 return MaybeBlockStage(ON_BEFORE_URL_REQUEST, callback);
479}
480
481int BlockingNetworkDelegate::OnBeforeSendHeaders(
482 URLRequest* request,
483 const CompletionCallback& callback,
484 HttpRequestHeaders* headers) {
485 TestNetworkDelegate::OnBeforeSendHeaders(request, callback, headers);
486
487 return MaybeBlockStage(ON_BEFORE_SEND_HEADERS, callback);
488}
489
490int BlockingNetworkDelegate::OnHeadersReceived(
491 URLRequest* request,
492 const CompletionCallback& callback,
493 const HttpResponseHeaders* original_response_headers,
Ben Murdocheffb81e2014-03-31 11:51:25 +0100494 scoped_refptr<HttpResponseHeaders>* override_response_headers,
495 GURL* allowed_unsafe_redirect_url) {
496 TestNetworkDelegate::OnHeadersReceived(request,
497 callback,
498 original_response_headers,
499 override_response_headers,
500 allowed_unsafe_redirect_url);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000501
502 return MaybeBlockStage(ON_HEADERS_RECEIVED, callback);
503}
504
505NetworkDelegate::AuthRequiredResponse BlockingNetworkDelegate::OnAuthRequired(
506 URLRequest* request,
507 const AuthChallengeInfo& auth_info,
508 const AuthCallback& callback,
509 AuthCredentials* credentials) {
510 TestNetworkDelegate::OnAuthRequired(request, auth_info, callback,
511 credentials);
512 // Check that the user has provided callback for the previous blocked stage.
513 EXPECT_EQ(NOT_BLOCKED, stage_blocked_for_callback_);
514
515 if ((block_on_ & ON_AUTH_REQUIRED) == 0) {
516 return AUTH_REQUIRED_RESPONSE_NO_ACTION;
517 }
518
519 target_auth_credentials_ = credentials;
520
521 switch (block_mode_) {
522 case SYNCHRONOUS:
523 if (auth_retval_ == AUTH_REQUIRED_RESPONSE_SET_AUTH)
524 *target_auth_credentials_ = auth_credentials_;
525 return auth_retval_;
526
527 case AUTO_CALLBACK:
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100528 base::MessageLoop::current()->PostTask(
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000529 FROM_HERE,
530 base::Bind(&BlockingNetworkDelegate::RunAuthCallback,
531 weak_factory_.GetWeakPtr(), auth_retval_, callback));
532 return AUTH_REQUIRED_RESPONSE_IO_PENDING;
533
534 case USER_CALLBACK:
535 auth_callback_ = callback;
536 stage_blocked_for_callback_ = ON_AUTH_REQUIRED;
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100537 base::MessageLoop::current()->PostTask(FROM_HERE,
538 base::MessageLoop::QuitClosure());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000539 return AUTH_REQUIRED_RESPONSE_IO_PENDING;
540 }
541 NOTREACHED();
542 return AUTH_REQUIRED_RESPONSE_NO_ACTION; // Dummy value.
543}
544
545void BlockingNetworkDelegate::Reset() {
546 EXPECT_NE(NOT_BLOCKED, stage_blocked_for_callback_);
547 stage_blocked_for_callback_ = NOT_BLOCKED;
548 callback_.Reset();
549 auth_callback_.Reset();
550}
551
552int BlockingNetworkDelegate::MaybeBlockStage(
553 BlockingNetworkDelegate::Stage stage,
554 const CompletionCallback& callback) {
555 // Check that the user has provided callback for the previous blocked stage.
556 EXPECT_EQ(NOT_BLOCKED, stage_blocked_for_callback_);
557
558 if ((block_on_ & stage) == 0) {
559 return OK;
560 }
561
562 switch (block_mode_) {
563 case SYNCHRONOUS:
564 EXPECT_NE(OK, retval_);
565 return retval_;
566
567 case AUTO_CALLBACK:
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100568 base::MessageLoop::current()->PostTask(
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000569 FROM_HERE,
570 base::Bind(&BlockingNetworkDelegate::RunCallback,
571 weak_factory_.GetWeakPtr(), retval_, callback));
572 return ERR_IO_PENDING;
573
574 case USER_CALLBACK:
575 callback_ = callback;
576 stage_blocked_for_callback_ = stage;
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100577 base::MessageLoop::current()->PostTask(FROM_HERE,
578 base::MessageLoop::QuitClosure());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000579 return ERR_IO_PENDING;
580 }
581 NOTREACHED();
582 return 0;
583}
584
585class TestURLRequestContextWithProxy : public TestURLRequestContext {
586 public:
587 // Does not own |delegate|.
588 TestURLRequestContextWithProxy(const std::string& proxy,
589 NetworkDelegate* delegate)
590 : TestURLRequestContext(true) {
591 context_storage_.set_proxy_service(ProxyService::CreateFixed(proxy));
592 set_network_delegate(delegate);
593 Init();
594 }
595 virtual ~TestURLRequestContextWithProxy() {}
596};
597
598} // namespace
599
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000600// Inherit PlatformTest since we require the autorelease pool on Mac OS X.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000601class URLRequestTest : public PlatformTest {
602 public:
603 URLRequestTest() : default_context_(true) {
604 default_context_.set_network_delegate(&default_network_delegate_);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000605 default_context_.set_net_log(&net_log_);
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100606 job_factory_.SetProtocolHandler("data", new DataProtocolHandler);
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +0100607#if !defined(DISABLE_FILE_SUPPORT)
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +0100608 job_factory_.SetProtocolHandler(
609 "file", new FileProtocolHandler(base::MessageLoopProxy::current()));
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +0100610#endif
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100611 default_context_.set_job_factory(&job_factory_);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000612 default_context_.Init();
613 }
Torne (Richard Coles)68043e12013-09-26 13:24:57 +0100614 virtual ~URLRequestTest() {
615 // URLRequestJobs may post clean-up tasks on destruction.
616 base::RunLoop().RunUntilIdle();
617 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000618
619 // Adds the TestJobInterceptor to the default context.
620 TestJobInterceptor* AddTestInterceptor() {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000621 TestJobInterceptor* protocol_handler_ = new TestJobInterceptor();
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100622 job_factory_.SetProtocolHandler("http", NULL);
623 job_factory_.SetProtocolHandler("http", protocol_handler_);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000624 return protocol_handler_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000625 }
626
627 protected:
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000628 CapturingNetLog net_log_;
629 TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest.
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100630 URLRequestJobFactoryImpl job_factory_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000631 TestURLRequestContext default_context_;
632};
633
634TEST_F(URLRequestTest, AboutBlankTest) {
635 TestDelegate d;
636 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100637 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
638 GURL("about:blank"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000639
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100640 r->Start();
641 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000642
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +0100643 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000644
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100645 EXPECT_TRUE(!r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000646 EXPECT_FALSE(d.received_data_before_response());
647 EXPECT_EQ(d.bytes_received(), 0);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100648 EXPECT_EQ("", r->GetSocketAddress().host());
649 EXPECT_EQ(0, r->GetSocketAddress().port());
Ben Murdocheb525c52013-07-10 11:40:50 +0100650
651 HttpRequestHeaders headers;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100652 EXPECT_FALSE(r->GetFullRequestHeaders(&headers));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000653 }
654}
655
656TEST_F(URLRequestTest, DataURLImageTest) {
657 TestDelegate d;
658 {
659 // Use our nice little Chrome logo.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100660 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +0000661 GURL(
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000662 "data:image/png;base64,"
663 "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADVklEQVQ4jX2TfUwUBBjG3"
664 "w1y+HGcd9dxhXR8T4awOccJGgOSWclHImznLkTlSw0DDQXkrmgYgbUYnlQTqQxIEVxitD"
665 "5UMCATRA1CEEg+Qjw3bWDxIauJv/5oumqs39/P827vnucRmYN0gyF01GI5MpCVdW0gO7t"
666 "vNC+vqSEtbZefk5NuLv1jdJ46p/zw0HeH4+PHr3h7c1mjoV2t5rKzMx1+fg9bAgK6zHq9"
667 "cU5z+LpA3xOtx34+vTeT21onRuzssC3zxbbSwC13d/pFuC7CkIMDxQpF7r/MWq12UctI1"
668 "dWWm99ypqSYmRUBdKem8MkrO/kgaTt1O7YzlpzE5GIVd0WYUqt57yWf2McHTObYPbVD+Z"
669 "wbtlLTVMZ3BW+TnLyXLaWtmEq6WJVbT3HBh3Svj2HQQcm43XwmtoYM6vVKleh0uoWvnzW"
670 "3v3MpidruPTQPf0bia7sJOtBM0ufTWNvus/nkDFHF9ZS+uYVjRUasMeHUmyLYtcklTvzW"
671 "GFZnNOXczThvpKIzjcahSqIzkvDLayDq6D3eOjtBbNUEIZYyqsvj4V4wY92eNJ4IoyhTb"
672 "xXX1T5xsV9tm9r4TQwHLiZw/pdDZJea8TKmsmR/K0uLh/GwnCHghTja6lPhphezPfO5/5"
673 "MrVvMzNaI3+ERHfrFzPKQukrQGI4d/3EFD/3E2mVNYvi4at7CXWREaxZGD+3hg28zD3gV"
674 "Md6q5c8GdosynKmSeRuGzpjyl1/9UDGtPR5HeaKT8Wjo17WXk579BXVUhN64ehF9fhRtq"
675 "/uxxZKzNiZFGD0wRC3NFROZ5mwIPL/96K/rKMMLrIzF9uhHr+/sYH7DAbwlgC4J+R2Z7F"
676 "Ux1qLnV7MGF40smVSoJ/jvHRfYhQeUJd/SnYtGWhPHR0Sz+GE2F2yth0B36Vcz2KpnufB"
677 "JbsysjjW4kblBUiIjiURUWqJY65zxbnTy57GQyH58zgy0QBtTQv5gH15XMdKkYu+TGaJM"
678 "nlm2O34uI4b9tflqp1+QEFGzoW/ulmcofcpkZCYJhDfSpme7QcrHa+Xfji8paEQkTkSfm"
679 "moRWRNZr/F1KfVMjW+IKEnv2FwZfKdzt0BQR6lClcZR0EfEXEfv/G6W9iLiIyCoReV5En"
680 "hORIBHx+ufPj/gLB/zGI/G4Bk0AAAAASUVORK5CYII="),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100681 DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000682
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100683 r->Start();
684 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000685
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +0100686 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000687
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100688 EXPECT_TRUE(!r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000689 EXPECT_FALSE(d.received_data_before_response());
690 EXPECT_EQ(d.bytes_received(), 911);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100691 EXPECT_EQ("", r->GetSocketAddress().host());
692 EXPECT_EQ(0, r->GetSocketAddress().port());
Ben Murdocheb525c52013-07-10 11:40:50 +0100693
694 HttpRequestHeaders headers;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100695 EXPECT_FALSE(r->GetFullRequestHeaders(&headers));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000696 }
697}
698
Torne (Richard Coles)cedac222014-06-03 10:58:34 +0100699#if !defined(DISABLE_FILE_SUPPORT)
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000700TEST_F(URLRequestTest, FileTest) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000701 base::FilePath app_path;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000702 PathService::Get(base::FILE_EXE, &app_path);
703 GURL app_url = FilePathToFileURL(app_path);
704
705 TestDelegate d;
706 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100707 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
708 app_url, DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000709
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100710 r->Start();
711 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000712
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +0100713 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000714
715 int64 file_size = -1;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +0000716 EXPECT_TRUE(base::GetFileSize(app_path, &file_size));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000717
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100718 EXPECT_TRUE(!r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000719 EXPECT_EQ(1, d.response_started_count());
720 EXPECT_FALSE(d.received_data_before_response());
721 EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100722 EXPECT_EQ("", r->GetSocketAddress().host());
723 EXPECT_EQ(0, r->GetSocketAddress().port());
Ben Murdocheb525c52013-07-10 11:40:50 +0100724
725 HttpRequestHeaders headers;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100726 EXPECT_FALSE(r->GetFullRequestHeaders(&headers));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000727 }
728}
729
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000730TEST_F(URLRequestTest, FileTestCancel) {
731 base::FilePath app_path;
732 PathService::Get(base::FILE_EXE, &app_path);
733 GURL app_url = FilePathToFileURL(app_path);
734
735 TestDelegate d;
736 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100737 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
738 app_url, DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000739
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100740 r->Start();
741 EXPECT_TRUE(r->is_pending());
742 r->Cancel();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000743 }
Ben Murdocheb525c52013-07-10 11:40:50 +0100744 // Async cancellation should be safe even when URLRequest has been already
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000745 // destroyed.
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +0100746 base::RunLoop().RunUntilIdle();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000747}
748
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000749TEST_F(URLRequestTest, FileTestFullSpecifiedRange) {
750 const size_t buffer_size = 4000;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100751 scoped_ptr<char[]> buffer(new char[buffer_size]);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000752 FillBuffer(buffer.get(), buffer_size);
753
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000754 base::FilePath temp_path;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +0000755 EXPECT_TRUE(base::CreateTemporaryFile(&temp_path));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000756 GURL temp_url = FilePathToFileURL(temp_path);
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000757 EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000758
759 int64 file_size;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +0000760 EXPECT_TRUE(base::GetFileSize(temp_path, &file_size));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000761
762 const size_t first_byte_position = 500;
763 const size_t last_byte_position = buffer_size - first_byte_position;
764 const size_t content_length = last_byte_position - first_byte_position + 1;
765 std::string partial_buffer_string(buffer.get() + first_byte_position,
766 buffer.get() + last_byte_position + 1);
767
768 TestDelegate d;
769 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100770 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
771 temp_url, DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000772
773 HttpRequestHeaders headers;
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000774 headers.SetHeader(
775 HttpRequestHeaders::kRange,
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100776 HttpByteRange::Bounded(
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000777 first_byte_position, last_byte_position).GetHeaderValue());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100778 r->SetExtraRequestHeaders(headers);
779 r->Start();
780 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000781
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +0100782 base::RunLoop().Run();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100783 EXPECT_TRUE(!r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000784 EXPECT_EQ(1, d.response_started_count());
785 EXPECT_FALSE(d.received_data_before_response());
786 EXPECT_EQ(static_cast<int>(content_length), d.bytes_received());
787 // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed.
788 EXPECT_TRUE(partial_buffer_string == d.data_received());
789 }
790
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100791 EXPECT_TRUE(base::DeleteFile(temp_path, false));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000792}
793
794TEST_F(URLRequestTest, FileTestHalfSpecifiedRange) {
795 const size_t buffer_size = 4000;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100796 scoped_ptr<char[]> buffer(new char[buffer_size]);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000797 FillBuffer(buffer.get(), buffer_size);
798
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000799 base::FilePath temp_path;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +0000800 EXPECT_TRUE(base::CreateTemporaryFile(&temp_path));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000801 GURL temp_url = FilePathToFileURL(temp_path);
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000802 EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000803
804 int64 file_size;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +0000805 EXPECT_TRUE(base::GetFileSize(temp_path, &file_size));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000806
807 const size_t first_byte_position = 500;
808 const size_t last_byte_position = buffer_size - 1;
809 const size_t content_length = last_byte_position - first_byte_position + 1;
810 std::string partial_buffer_string(buffer.get() + first_byte_position,
811 buffer.get() + last_byte_position + 1);
812
813 TestDelegate d;
814 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100815 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
816 temp_url, DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000817
818 HttpRequestHeaders headers;
819 headers.SetHeader(HttpRequestHeaders::kRange,
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100820 HttpByteRange::RightUnbounded(
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000821 first_byte_position).GetHeaderValue());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100822 r->SetExtraRequestHeaders(headers);
823 r->Start();
824 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000825
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +0100826 base::RunLoop().Run();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100827 EXPECT_TRUE(!r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000828 EXPECT_EQ(1, d.response_started_count());
829 EXPECT_FALSE(d.received_data_before_response());
830 EXPECT_EQ(static_cast<int>(content_length), d.bytes_received());
831 // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed.
832 EXPECT_TRUE(partial_buffer_string == d.data_received());
833 }
834
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100835 EXPECT_TRUE(base::DeleteFile(temp_path, false));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000836}
837
838TEST_F(URLRequestTest, FileTestMultipleRanges) {
839 const size_t buffer_size = 400000;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100840 scoped_ptr<char[]> buffer(new char[buffer_size]);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000841 FillBuffer(buffer.get(), buffer_size);
842
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000843 base::FilePath temp_path;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +0000844 EXPECT_TRUE(base::CreateTemporaryFile(&temp_path));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000845 GURL temp_url = FilePathToFileURL(temp_path);
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000846 EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000847
848 int64 file_size;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +0000849 EXPECT_TRUE(base::GetFileSize(temp_path, &file_size));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000850
851 TestDelegate d;
852 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100853 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
854 temp_url, DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000855
856 HttpRequestHeaders headers;
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000857 headers.SetHeader(HttpRequestHeaders::kRange, "bytes=0-0,10-200,200-300");
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100858 r->SetExtraRequestHeaders(headers);
859 r->Start();
860 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000861
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +0100862 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000863 EXPECT_TRUE(d.request_failed());
864 }
865
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100866 EXPECT_TRUE(base::DeleteFile(temp_path, false));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000867}
868
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000869TEST_F(URLRequestTest, AllowFileURLs) {
870 base::ScopedTempDir temp_dir;
871 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
872 base::FilePath test_file;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +0000873 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), &test_file));
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000874 std::string test_data("monkey");
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000875 base::WriteFile(test_file, test_data.data(), test_data.size());
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100876 GURL test_file_url = FilePathToFileURL(test_file);
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000877
878 {
879 TestDelegate d;
880 TestNetworkDelegate network_delegate;
881 network_delegate.set_can_access_files(true);
882 default_context_.set_network_delegate(&network_delegate);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100883 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
884 test_file_url, DEFAULT_PRIORITY, &d, NULL));
885 r->Start();
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000886 base::RunLoop().Run();
887 EXPECT_FALSE(d.request_failed());
888 EXPECT_EQ(test_data, d.data_received());
889 }
890
891 {
892 TestDelegate d;
893 TestNetworkDelegate network_delegate;
894 network_delegate.set_can_access_files(false);
895 default_context_.set_network_delegate(&network_delegate);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100896 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
897 test_file_url, DEFAULT_PRIORITY, &d, NULL));
898 r->Start();
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000899 base::RunLoop().Run();
900 EXPECT_TRUE(d.request_failed());
901 EXPECT_EQ("", d.data_received());
902 }
903}
904
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000905
906TEST_F(URLRequestTest, FileDirCancelTest) {
907 // Put in mock resource provider.
908 NetModule::SetResourceProvider(TestNetResourceProvider);
909
910 TestDelegate d;
911 {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000912 base::FilePath file_path;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000913 PathService::Get(base::DIR_SOURCE_ROOT, &file_path);
914 file_path = file_path.Append(FILE_PATH_LITERAL("net"));
915 file_path = file_path.Append(FILE_PATH_LITERAL("data"));
916
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100917 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
918 FilePathToFileURL(file_path), DEFAULT_PRIORITY, &d, NULL));
919 req->Start();
920 EXPECT_TRUE(req->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000921
922 d.set_cancel_in_received_data_pending(true);
923
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +0100924 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000925 }
926
927 // Take out mock resource provider.
928 NetModule::SetResourceProvider(NULL);
929}
930
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +0000931TEST_F(URLRequestTest, FileDirOutputSanity) {
932 // Verify the general sanity of the the output of the file:
933 // directory lister by checking for the output of a known existing
934 // file.
935 const char sentinel_name[] = "filedir-sentinel";
936
937 base::FilePath path;
938 PathService::Get(base::DIR_SOURCE_ROOT, &path);
939 path = path.Append(FILE_PATH_LITERAL("net"));
940 path = path.Append(FILE_PATH_LITERAL("data"));
941 path = path.Append(FILE_PATH_LITERAL("url_request_unittest"));
942
943 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100944 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
945 FilePathToFileURL(path), DEFAULT_PRIORITY, &d, NULL));
946 req->Start();
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +0000947 base::RunLoop().Run();
948
949 // Generate entry for the sentinel file.
950 base::FilePath sentinel_path = path.AppendASCII(sentinel_name);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000951 base::File::Info info;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +0000952 EXPECT_TRUE(base::GetFileInfo(sentinel_path, &info));
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +0000953 EXPECT_GT(info.size, 0);
954 std::string sentinel_output = GetDirectoryListingEntry(
955 base::string16(sentinel_name, sentinel_name + strlen(sentinel_name)),
956 std::string(sentinel_name),
957 false /* is_dir */,
958 info.size,
959 info.last_modified);
960
961 ASSERT_LT(0, d.bytes_received());
962 ASSERT_FALSE(d.request_failed());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100963 ASSERT_TRUE(req->status().is_success());
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +0000964 // Check for the entry generated for the "sentinel" file.
965 const std::string& data = d.data_received();
966 ASSERT_NE(data.find(sentinel_output), std::string::npos);
967}
968
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000969TEST_F(URLRequestTest, FileDirRedirectNoCrash) {
970 // There is an implicit redirect when loading a file path that matches a
971 // directory and does not end with a slash. Ensure that following such
972 // redirects does not crash. See http://crbug.com/18686.
973
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000974 base::FilePath path;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000975 PathService::Get(base::DIR_SOURCE_ROOT, &path);
976 path = path.Append(FILE_PATH_LITERAL("net"));
977 path = path.Append(FILE_PATH_LITERAL("data"));
978 path = path.Append(FILE_PATH_LITERAL("url_request_unittest"));
979
980 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100981 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
982 FilePathToFileURL(path), DEFAULT_PRIORITY, &d, NULL));
983 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +0100984 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000985
986 ASSERT_EQ(1, d.received_redirect_count());
987 ASSERT_LT(0, d.bytes_received());
988 ASSERT_FALSE(d.request_failed());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100989 ASSERT_TRUE(req->status().is_success());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000990}
991
992#if defined(OS_WIN)
993// Don't accept the url "file:///" on windows. See http://crbug.com/1474.
994TEST_F(URLRequestTest, FileDirRedirectSingleSlash) {
995 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +0100996 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
997 GURL("file:///"), DEFAULT_PRIORITY, &d, NULL));
998 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +0100999 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001000
1001 ASSERT_EQ(1, d.received_redirect_count());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001002 ASSERT_FALSE(req->status().is_success());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001003}
Torne (Richard Coles)cedac222014-06-03 10:58:34 +01001004#endif // defined(OS_WIN)
1005
1006#endif // !defined(DISABLE_FILE_SUPPORT)
1007
1008TEST_F(URLRequestTest, InvalidUrlTest) {
1009 TestDelegate d;
1010 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001011 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
1012 GURL("invalid url"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)cedac222014-06-03 10:58:34 +01001013
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001014 r->Start();
1015 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)cedac222014-06-03 10:58:34 +01001016
1017 base::RunLoop().Run();
1018 EXPECT_TRUE(d.request_failed());
1019 }
1020}
1021
1022#if defined(OS_WIN)
1023TEST_F(URLRequestTest, ResolveShortcutTest) {
1024 base::FilePath app_path;
1025 PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
1026 app_path = app_path.AppendASCII("net");
1027 app_path = app_path.AppendASCII("data");
1028 app_path = app_path.AppendASCII("url_request_unittest");
1029 app_path = app_path.AppendASCII("with-headers.html");
1030
1031 std::wstring lnk_path = app_path.value() + L".lnk";
1032
1033 base::win::ScopedCOMInitializer com_initializer;
1034
1035 // Temporarily create a shortcut for test
1036 {
1037 base::win::ScopedComPtr<IShellLink> shell;
1038 ASSERT_TRUE(SUCCEEDED(shell.CreateInstance(CLSID_ShellLink, NULL,
1039 CLSCTX_INPROC_SERVER)));
1040 base::win::ScopedComPtr<IPersistFile> persist;
1041 ASSERT_TRUE(SUCCEEDED(shell.QueryInterface(persist.Receive())));
1042 EXPECT_TRUE(SUCCEEDED(shell->SetPath(app_path.value().c_str())));
1043 EXPECT_TRUE(SUCCEEDED(shell->SetDescription(L"ResolveShortcutTest")));
1044 EXPECT_TRUE(SUCCEEDED(persist->Save(lnk_path.c_str(), TRUE)));
1045 }
1046
1047 TestDelegate d;
1048 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001049 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
1050 FilePathToFileURL(base::FilePath(lnk_path)), DEFAULT_PRIORITY, &d,
1051 NULL));
Torne (Richard Coles)cedac222014-06-03 10:58:34 +01001052
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001053 r->Start();
1054 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)cedac222014-06-03 10:58:34 +01001055
1056 base::RunLoop().Run();
1057
1058 WIN32_FILE_ATTRIBUTE_DATA data;
1059 GetFileAttributesEx(app_path.value().c_str(),
1060 GetFileExInfoStandard, &data);
1061 HANDLE file = CreateFile(app_path.value().c_str(), GENERIC_READ,
1062 FILE_SHARE_READ, NULL, OPEN_EXISTING,
1063 FILE_ATTRIBUTE_NORMAL, NULL);
1064 EXPECT_NE(INVALID_HANDLE_VALUE, file);
1065 scoped_ptr<char[]> buffer(new char[data.nFileSizeLow]);
1066 DWORD read_size;
1067 BOOL result;
1068 result = ReadFile(file, buffer.get(), data.nFileSizeLow,
1069 &read_size, NULL);
1070 std::string content(buffer.get(), read_size);
1071 CloseHandle(file);
1072
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001073 EXPECT_TRUE(!r->is_pending());
Torne (Richard Coles)cedac222014-06-03 10:58:34 +01001074 EXPECT_EQ(1, d.received_redirect_count());
1075 EXPECT_EQ(content, d.data_received());
1076 }
1077
1078 // Clean the shortcut
1079 DeleteFile(lnk_path.c_str());
1080}
1081#endif // defined(OS_WIN)
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001082
1083// Custom URLRequestJobs for use with interceptor tests
1084class RestartTestJob : public URLRequestTestJob {
1085 public:
1086 RestartTestJob(URLRequest* request, NetworkDelegate* network_delegate)
1087 : URLRequestTestJob(request, network_delegate, true) {}
1088 protected:
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001089 virtual void StartAsync() OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001090 this->NotifyRestartRequired();
1091 }
1092 private:
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001093 virtual ~RestartTestJob() {}
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001094};
1095
1096class CancelTestJob : public URLRequestTestJob {
1097 public:
1098 explicit CancelTestJob(URLRequest* request, NetworkDelegate* network_delegate)
1099 : URLRequestTestJob(request, network_delegate, true) {}
1100 protected:
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001101 virtual void StartAsync() OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001102 request_->Cancel();
1103 }
1104 private:
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001105 virtual ~CancelTestJob() {}
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001106};
1107
1108class CancelThenRestartTestJob : public URLRequestTestJob {
1109 public:
1110 explicit CancelThenRestartTestJob(URLRequest* request,
1111 NetworkDelegate* network_delegate)
1112 : URLRequestTestJob(request, network_delegate, true) {
1113 }
1114 protected:
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001115 virtual void StartAsync() OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001116 request_->Cancel();
1117 this->NotifyRestartRequired();
1118 }
1119 private:
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001120 virtual ~CancelThenRestartTestJob() {}
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001121};
1122
1123// An Interceptor for use with interceptor tests
1124class TestInterceptor : URLRequest::Interceptor {
1125 public:
1126 TestInterceptor()
1127 : intercept_main_request_(false), restart_main_request_(false),
1128 cancel_main_request_(false), cancel_then_restart_main_request_(false),
1129 simulate_main_network_error_(false),
1130 intercept_redirect_(false), cancel_redirect_request_(false),
1131 intercept_final_response_(false), cancel_final_request_(false),
1132 did_intercept_main_(false), did_restart_main_(false),
1133 did_cancel_main_(false), did_cancel_then_restart_main_(false),
1134 did_simulate_error_main_(false),
1135 did_intercept_redirect_(false), did_cancel_redirect_(false),
1136 did_intercept_final_(false), did_cancel_final_(false) {
1137 URLRequest::Deprecated::RegisterRequestInterceptor(this);
1138 }
1139
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001140 virtual ~TestInterceptor() {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001141 URLRequest::Deprecated::UnregisterRequestInterceptor(this);
1142 }
1143
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001144 virtual URLRequestJob* MaybeIntercept(
1145 URLRequest* request,
1146 NetworkDelegate* network_delegate) OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001147 if (restart_main_request_) {
1148 restart_main_request_ = false;
1149 did_restart_main_ = true;
1150 return new RestartTestJob(request, network_delegate);
1151 }
1152 if (cancel_main_request_) {
1153 cancel_main_request_ = false;
1154 did_cancel_main_ = true;
1155 return new CancelTestJob(request, network_delegate);
1156 }
1157 if (cancel_then_restart_main_request_) {
1158 cancel_then_restart_main_request_ = false;
1159 did_cancel_then_restart_main_ = true;
1160 return new CancelThenRestartTestJob(request, network_delegate);
1161 }
1162 if (simulate_main_network_error_) {
1163 simulate_main_network_error_ = false;
1164 did_simulate_error_main_ = true;
1165 // will error since the requeted url is not one of its canned urls
1166 return new URLRequestTestJob(request, network_delegate, true);
1167 }
1168 if (!intercept_main_request_)
1169 return NULL;
1170 intercept_main_request_ = false;
1171 did_intercept_main_ = true;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001172 URLRequestTestJob* job = new URLRequestTestJob(request,
1173 network_delegate,
1174 main_headers_,
1175 main_data_,
1176 true);
1177 job->set_load_timing_info(main_request_load_timing_info_);
1178 return job;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001179 }
1180
1181 virtual URLRequestJob* MaybeInterceptRedirect(
1182 URLRequest* request,
1183 NetworkDelegate* network_delegate,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001184 const GURL& location) OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001185 if (cancel_redirect_request_) {
1186 cancel_redirect_request_ = false;
1187 did_cancel_redirect_ = true;
1188 return new CancelTestJob(request, network_delegate);
1189 }
1190 if (!intercept_redirect_)
1191 return NULL;
1192 intercept_redirect_ = false;
1193 did_intercept_redirect_ = true;
1194 return new URLRequestTestJob(request,
1195 network_delegate,
1196 redirect_headers_,
1197 redirect_data_,
1198 true);
1199 }
1200
1201 virtual URLRequestJob* MaybeInterceptResponse(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001202 URLRequest* request, NetworkDelegate* network_delegate) OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001203 if (cancel_final_request_) {
1204 cancel_final_request_ = false;
1205 did_cancel_final_ = true;
1206 return new CancelTestJob(request, network_delegate);
1207 }
1208 if (!intercept_final_response_)
1209 return NULL;
1210 intercept_final_response_ = false;
1211 did_intercept_final_ = true;
1212 return new URLRequestTestJob(request,
1213 network_delegate,
1214 final_headers_,
1215 final_data_,
1216 true);
1217 }
1218
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001219 // Whether to intercept the main request, and if so the response to return and
1220 // the LoadTimingInfo to use.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001221 bool intercept_main_request_;
1222 std::string main_headers_;
1223 std::string main_data_;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001224 LoadTimingInfo main_request_load_timing_info_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001225
1226 // Other actions we take at MaybeIntercept time
1227 bool restart_main_request_;
1228 bool cancel_main_request_;
1229 bool cancel_then_restart_main_request_;
1230 bool simulate_main_network_error_;
1231
1232 // Whether to intercept redirects, and if so the response to return.
1233 bool intercept_redirect_;
1234 std::string redirect_headers_;
1235 std::string redirect_data_;
1236
1237 // Other actions we can take at MaybeInterceptRedirect time
1238 bool cancel_redirect_request_;
1239
1240 // Whether to intercept final response, and if so the response to return.
1241 bool intercept_final_response_;
1242 std::string final_headers_;
1243 std::string final_data_;
1244
1245 // Other actions we can take at MaybeInterceptResponse time
1246 bool cancel_final_request_;
1247
1248 // If we did something or not
1249 bool did_intercept_main_;
1250 bool did_restart_main_;
1251 bool did_cancel_main_;
1252 bool did_cancel_then_restart_main_;
1253 bool did_simulate_error_main_;
1254 bool did_intercept_redirect_;
1255 bool did_cancel_redirect_;
1256 bool did_intercept_final_;
1257 bool did_cancel_final_;
1258
1259 // Static getters for canned response header and data strings
1260
1261 static std::string ok_data() {
1262 return URLRequestTestJob::test_data_1();
1263 }
1264
1265 static std::string ok_headers() {
1266 return URLRequestTestJob::test_headers();
1267 }
1268
1269 static std::string redirect_data() {
1270 return std::string();
1271 }
1272
1273 static std::string redirect_headers() {
1274 return URLRequestTestJob::test_redirect_headers();
1275 }
1276
1277 static std::string error_data() {
1278 return std::string("ohhh nooooo mr. bill!");
1279 }
1280
1281 static std::string error_headers() {
1282 return URLRequestTestJob::test_error_headers();
1283 }
1284};
1285
1286TEST_F(URLRequestTest, Intercept) {
1287 TestInterceptor interceptor;
1288
1289 // intercept the main request and respond with a simple response
1290 interceptor.intercept_main_request_ = true;
1291 interceptor.main_headers_ = TestInterceptor::ok_headers();
1292 interceptor.main_data_ = TestInterceptor::ok_data();
1293
1294 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001295 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1296 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001297 base::SupportsUserData::Data* user_data0 = new base::SupportsUserData::Data();
1298 base::SupportsUserData::Data* user_data1 = new base::SupportsUserData::Data();
1299 base::SupportsUserData::Data* user_data2 = new base::SupportsUserData::Data();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001300 req->SetUserData(NULL, user_data0);
1301 req->SetUserData(&user_data1, user_data1);
1302 req->SetUserData(&user_data2, user_data2);
1303 req->set_method("GET");
1304 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001305 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001306
1307 // Make sure we can retrieve our specific user data
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001308 EXPECT_EQ(user_data0, req->GetUserData(NULL));
1309 EXPECT_EQ(user_data1, req->GetUserData(&user_data1));
1310 EXPECT_EQ(user_data2, req->GetUserData(&user_data2));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001311
1312 // Check the interceptor got called as expected
1313 EXPECT_TRUE(interceptor.did_intercept_main_);
1314
1315 // Check we got one good response
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001316 EXPECT_TRUE(req->status().is_success());
1317 EXPECT_EQ(200, req->response_headers()->response_code());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001318 EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
1319 EXPECT_EQ(1, d.response_started_count());
1320 EXPECT_EQ(0, d.received_redirect_count());
1321}
1322
1323TEST_F(URLRequestTest, InterceptRedirect) {
1324 TestInterceptor interceptor;
1325
1326 // intercept the main request and respond with a redirect
1327 interceptor.intercept_main_request_ = true;
1328 interceptor.main_headers_ = TestInterceptor::redirect_headers();
1329 interceptor.main_data_ = TestInterceptor::redirect_data();
1330
1331 // intercept that redirect and respond a final OK response
1332 interceptor.intercept_redirect_ = true;
1333 interceptor.redirect_headers_ = TestInterceptor::ok_headers();
1334 interceptor.redirect_data_ = TestInterceptor::ok_data();
1335
1336 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001337 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1338 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
1339 req->set_method("GET");
1340 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001341 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001342
1343 // Check the interceptor got called as expected
1344 EXPECT_TRUE(interceptor.did_intercept_main_);
1345 EXPECT_TRUE(interceptor.did_intercept_redirect_);
1346
1347 // Check we got one good response
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001348 EXPECT_TRUE(req->status().is_success());
1349 if (req->status().is_success()) {
1350 EXPECT_EQ(200, req->response_headers()->response_code());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001351 }
1352 EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
1353 EXPECT_EQ(1, d.response_started_count());
1354 EXPECT_EQ(0, d.received_redirect_count());
1355}
1356
1357TEST_F(URLRequestTest, InterceptServerError) {
1358 TestInterceptor interceptor;
1359
1360 // intercept the main request to generate a server error response
1361 interceptor.intercept_main_request_ = true;
1362 interceptor.main_headers_ = TestInterceptor::error_headers();
1363 interceptor.main_data_ = TestInterceptor::error_data();
1364
1365 // intercept that error and respond with an OK response
1366 interceptor.intercept_final_response_ = true;
1367 interceptor.final_headers_ = TestInterceptor::ok_headers();
1368 interceptor.final_data_ = TestInterceptor::ok_data();
1369
1370 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001371 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1372 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
1373 req->set_method("GET");
1374 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001375 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001376
1377 // Check the interceptor got called as expected
1378 EXPECT_TRUE(interceptor.did_intercept_main_);
1379 EXPECT_TRUE(interceptor.did_intercept_final_);
1380
1381 // Check we got one good response
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001382 EXPECT_TRUE(req->status().is_success());
1383 EXPECT_EQ(200, req->response_headers()->response_code());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001384 EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
1385 EXPECT_EQ(1, d.response_started_count());
1386 EXPECT_EQ(0, d.received_redirect_count());
1387}
1388
1389TEST_F(URLRequestTest, InterceptNetworkError) {
1390 TestInterceptor interceptor;
1391
1392 // intercept the main request to simulate a network error
1393 interceptor.simulate_main_network_error_ = true;
1394
1395 // intercept that error and respond with an OK response
1396 interceptor.intercept_final_response_ = true;
1397 interceptor.final_headers_ = TestInterceptor::ok_headers();
1398 interceptor.final_data_ = TestInterceptor::ok_data();
1399
1400 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001401 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1402 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
1403 req->set_method("GET");
1404 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001405 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001406
1407 // Check the interceptor got called as expected
1408 EXPECT_TRUE(interceptor.did_simulate_error_main_);
1409 EXPECT_TRUE(interceptor.did_intercept_final_);
1410
1411 // Check we received one good response
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001412 EXPECT_TRUE(req->status().is_success());
1413 EXPECT_EQ(200, req->response_headers()->response_code());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001414 EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
1415 EXPECT_EQ(1, d.response_started_count());
1416 EXPECT_EQ(0, d.received_redirect_count());
1417}
1418
1419TEST_F(URLRequestTest, InterceptRestartRequired) {
1420 TestInterceptor interceptor;
1421
1422 // restart the main request
1423 interceptor.restart_main_request_ = true;
1424
1425 // then intercept the new main request and respond with an OK response
1426 interceptor.intercept_main_request_ = true;
1427 interceptor.main_headers_ = TestInterceptor::ok_headers();
1428 interceptor.main_data_ = TestInterceptor::ok_data();
1429
1430 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001431 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1432 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
1433 req->set_method("GET");
1434 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001435 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001436
1437 // Check the interceptor got called as expected
1438 EXPECT_TRUE(interceptor.did_restart_main_);
1439 EXPECT_TRUE(interceptor.did_intercept_main_);
1440
1441 // Check we received one good response
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001442 EXPECT_TRUE(req->status().is_success());
1443 if (req->status().is_success()) {
1444 EXPECT_EQ(200, req->response_headers()->response_code());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001445 }
1446 EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
1447 EXPECT_EQ(1, d.response_started_count());
1448 EXPECT_EQ(0, d.received_redirect_count());
1449}
1450
1451TEST_F(URLRequestTest, InterceptRespectsCancelMain) {
1452 TestInterceptor interceptor;
1453
1454 // intercept the main request and cancel from within the restarted job
1455 interceptor.cancel_main_request_ = true;
1456
1457 // setup to intercept final response and override it with an OK response
1458 interceptor.intercept_final_response_ = true;
1459 interceptor.final_headers_ = TestInterceptor::ok_headers();
1460 interceptor.final_data_ = TestInterceptor::ok_data();
1461
1462 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001463 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1464 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
1465 req->set_method("GET");
1466 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001467 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001468
1469 // Check the interceptor got called as expected
1470 EXPECT_TRUE(interceptor.did_cancel_main_);
1471 EXPECT_FALSE(interceptor.did_intercept_final_);
1472
1473 // Check we see a canceled request
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001474 EXPECT_FALSE(req->status().is_success());
1475 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001476}
1477
1478TEST_F(URLRequestTest, InterceptRespectsCancelRedirect) {
1479 TestInterceptor interceptor;
1480
1481 // intercept the main request and respond with a redirect
1482 interceptor.intercept_main_request_ = true;
1483 interceptor.main_headers_ = TestInterceptor::redirect_headers();
1484 interceptor.main_data_ = TestInterceptor::redirect_data();
1485
1486 // intercept the redirect and cancel from within that job
1487 interceptor.cancel_redirect_request_ = true;
1488
1489 // setup to intercept final response and override it with an OK response
1490 interceptor.intercept_final_response_ = true;
1491 interceptor.final_headers_ = TestInterceptor::ok_headers();
1492 interceptor.final_data_ = TestInterceptor::ok_data();
1493
1494 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001495 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1496 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
1497 req->set_method("GET");
1498 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001499 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001500
1501 // Check the interceptor got called as expected
1502 EXPECT_TRUE(interceptor.did_intercept_main_);
1503 EXPECT_TRUE(interceptor.did_cancel_redirect_);
1504 EXPECT_FALSE(interceptor.did_intercept_final_);
1505
1506 // Check we see a canceled request
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001507 EXPECT_FALSE(req->status().is_success());
1508 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001509}
1510
1511TEST_F(URLRequestTest, InterceptRespectsCancelFinal) {
1512 TestInterceptor interceptor;
1513
1514 // intercept the main request to simulate a network error
1515 interceptor.simulate_main_network_error_ = true;
1516
1517 // setup to intercept final response and cancel from within that job
1518 interceptor.cancel_final_request_ = true;
1519
1520 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001521 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1522 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
1523 req->set_method("GET");
1524 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001525 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001526
1527 // Check the interceptor got called as expected
1528 EXPECT_TRUE(interceptor.did_simulate_error_main_);
1529 EXPECT_TRUE(interceptor.did_cancel_final_);
1530
1531 // Check we see a canceled request
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001532 EXPECT_FALSE(req->status().is_success());
1533 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001534}
1535
1536TEST_F(URLRequestTest, InterceptRespectsCancelInRestart) {
1537 TestInterceptor interceptor;
1538
1539 // intercept the main request and cancel then restart from within that job
1540 interceptor.cancel_then_restart_main_request_ = true;
1541
1542 // setup to intercept final response and override it with an OK response
1543 interceptor.intercept_final_response_ = true;
1544 interceptor.final_headers_ = TestInterceptor::ok_headers();
1545 interceptor.final_data_ = TestInterceptor::ok_data();
1546
1547 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001548 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1549 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
1550 req->set_method("GET");
1551 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001552 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001553
1554 // Check the interceptor got called as expected
1555 EXPECT_TRUE(interceptor.did_cancel_then_restart_main_);
1556 EXPECT_FALSE(interceptor.did_intercept_final_);
1557
1558 // Check we see a canceled request
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001559 EXPECT_FALSE(req->status().is_success());
1560 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001561}
1562
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001563LoadTimingInfo RunLoadTimingTest(const LoadTimingInfo& job_load_timing,
1564 URLRequestContext* context) {
1565 TestInterceptor interceptor;
1566 interceptor.intercept_main_request_ = true;
1567 interceptor.main_request_load_timing_info_ = job_load_timing;
1568 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001569 scoped_ptr<URLRequest> req(context->CreateRequest(
1570 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
1571 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001572 base::RunLoop().Run();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001573
1574 LoadTimingInfo resulting_load_timing;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001575 req->GetLoadTimingInfo(&resulting_load_timing);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001576
1577 // None of these should be modified by the URLRequest.
1578 EXPECT_EQ(job_load_timing.socket_reused, resulting_load_timing.socket_reused);
1579 EXPECT_EQ(job_load_timing.socket_log_id, resulting_load_timing.socket_log_id);
1580 EXPECT_EQ(job_load_timing.send_start, resulting_load_timing.send_start);
1581 EXPECT_EQ(job_load_timing.send_end, resulting_load_timing.send_end);
1582 EXPECT_EQ(job_load_timing.receive_headers_end,
1583 resulting_load_timing.receive_headers_end);
1584
1585 return resulting_load_timing;
1586}
1587
1588// "Normal" LoadTimingInfo as returned by a job. Everything is in order, not
1589// reused. |connect_time_flags| is used to indicate if there should be dns
1590// or SSL times, and |used_proxy| is used for proxy times.
1591LoadTimingInfo NormalLoadTimingInfo(base::TimeTicks now,
1592 int connect_time_flags,
1593 bool used_proxy) {
1594 LoadTimingInfo load_timing;
1595 load_timing.socket_log_id = 1;
1596
1597 if (used_proxy) {
1598 load_timing.proxy_resolve_start = now + base::TimeDelta::FromDays(1);
1599 load_timing.proxy_resolve_end = now + base::TimeDelta::FromDays(2);
1600 }
1601
1602 LoadTimingInfo::ConnectTiming& connect_timing = load_timing.connect_timing;
1603 if (connect_time_flags & CONNECT_TIMING_HAS_DNS_TIMES) {
1604 connect_timing.dns_start = now + base::TimeDelta::FromDays(3);
1605 connect_timing.dns_end = now + base::TimeDelta::FromDays(4);
1606 }
1607 connect_timing.connect_start = now + base::TimeDelta::FromDays(5);
1608 if (connect_time_flags & CONNECT_TIMING_HAS_SSL_TIMES) {
1609 connect_timing.ssl_start = now + base::TimeDelta::FromDays(6);
1610 connect_timing.ssl_end = now + base::TimeDelta::FromDays(7);
1611 }
1612 connect_timing.connect_end = now + base::TimeDelta::FromDays(8);
1613
1614 load_timing.send_start = now + base::TimeDelta::FromDays(9);
1615 load_timing.send_end = now + base::TimeDelta::FromDays(10);
1616 load_timing.receive_headers_end = now + base::TimeDelta::FromDays(11);
1617 return load_timing;
1618}
1619
1620// Same as above, but in the case of a reused socket.
1621LoadTimingInfo NormalLoadTimingInfoReused(base::TimeTicks now,
1622 bool used_proxy) {
1623 LoadTimingInfo load_timing;
1624 load_timing.socket_log_id = 1;
1625 load_timing.socket_reused = true;
1626
1627 if (used_proxy) {
1628 load_timing.proxy_resolve_start = now + base::TimeDelta::FromDays(1);
1629 load_timing.proxy_resolve_end = now + base::TimeDelta::FromDays(2);
1630 }
1631
1632 load_timing.send_start = now + base::TimeDelta::FromDays(9);
1633 load_timing.send_end = now + base::TimeDelta::FromDays(10);
1634 load_timing.receive_headers_end = now + base::TimeDelta::FromDays(11);
1635 return load_timing;
1636}
1637
1638// Basic test that the intercept + load timing tests work.
1639TEST_F(URLRequestTest, InterceptLoadTiming) {
1640 base::TimeTicks now = base::TimeTicks::Now();
1641 LoadTimingInfo job_load_timing =
1642 NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, false);
1643
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00001644 LoadTimingInfo load_timing_result =
1645 RunLoadTimingTest(job_load_timing, &default_context_);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001646
1647 // Nothing should have been changed by the URLRequest.
1648 EXPECT_EQ(job_load_timing.proxy_resolve_start,
1649 load_timing_result.proxy_resolve_start);
1650 EXPECT_EQ(job_load_timing.proxy_resolve_end,
1651 load_timing_result.proxy_resolve_end);
1652 EXPECT_EQ(job_load_timing.connect_timing.dns_start,
1653 load_timing_result.connect_timing.dns_start);
1654 EXPECT_EQ(job_load_timing.connect_timing.dns_end,
1655 load_timing_result.connect_timing.dns_end);
1656 EXPECT_EQ(job_load_timing.connect_timing.connect_start,
1657 load_timing_result.connect_timing.connect_start);
1658 EXPECT_EQ(job_load_timing.connect_timing.connect_end,
1659 load_timing_result.connect_timing.connect_end);
1660 EXPECT_EQ(job_load_timing.connect_timing.ssl_start,
1661 load_timing_result.connect_timing.ssl_start);
1662 EXPECT_EQ(job_load_timing.connect_timing.ssl_end,
1663 load_timing_result.connect_timing.ssl_end);
1664
1665 // Redundant sanity check.
1666 TestLoadTimingNotReused(load_timing_result, CONNECT_TIMING_HAS_DNS_TIMES);
1667}
1668
1669// Another basic test, with proxy and SSL times, but no DNS times.
1670TEST_F(URLRequestTest, InterceptLoadTimingProxy) {
1671 base::TimeTicks now = base::TimeTicks::Now();
1672 LoadTimingInfo job_load_timing =
1673 NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, true);
1674
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00001675 LoadTimingInfo load_timing_result =
1676 RunLoadTimingTest(job_load_timing, &default_context_);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001677
1678 // Nothing should have been changed by the URLRequest.
1679 EXPECT_EQ(job_load_timing.proxy_resolve_start,
1680 load_timing_result.proxy_resolve_start);
1681 EXPECT_EQ(job_load_timing.proxy_resolve_end,
1682 load_timing_result.proxy_resolve_end);
1683 EXPECT_EQ(job_load_timing.connect_timing.dns_start,
1684 load_timing_result.connect_timing.dns_start);
1685 EXPECT_EQ(job_load_timing.connect_timing.dns_end,
1686 load_timing_result.connect_timing.dns_end);
1687 EXPECT_EQ(job_load_timing.connect_timing.connect_start,
1688 load_timing_result.connect_timing.connect_start);
1689 EXPECT_EQ(job_load_timing.connect_timing.connect_end,
1690 load_timing_result.connect_timing.connect_end);
1691 EXPECT_EQ(job_load_timing.connect_timing.ssl_start,
1692 load_timing_result.connect_timing.ssl_start);
1693 EXPECT_EQ(job_load_timing.connect_timing.ssl_end,
1694 load_timing_result.connect_timing.ssl_end);
1695
1696 // Redundant sanity check.
1697 TestLoadTimingNotReusedWithProxy(load_timing_result,
1698 CONNECT_TIMING_HAS_SSL_TIMES);
1699}
1700
1701// Make sure that URLRequest correctly adjusts proxy times when they're before
1702// |request_start|, due to already having a connected socket. This happens in
Torne (Richard Coles)cedac222014-06-03 10:58:34 +01001703// the case of reusing a SPDY session. The connected socket is not considered
1704// reused in this test (May be a preconnect).
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001705//
1706// To mix things up from the test above, assumes DNS times but no SSL times.
1707TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolution) {
1708 base::TimeTicks now = base::TimeTicks::Now();
1709 LoadTimingInfo job_load_timing =
1710 NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, true);
1711 job_load_timing.proxy_resolve_start = now - base::TimeDelta::FromDays(6);
1712 job_load_timing.proxy_resolve_end = now - base::TimeDelta::FromDays(5);
1713 job_load_timing.connect_timing.dns_start = now - base::TimeDelta::FromDays(4);
1714 job_load_timing.connect_timing.dns_end = now - base::TimeDelta::FromDays(3);
1715 job_load_timing.connect_timing.connect_start =
1716 now - base::TimeDelta::FromDays(2);
1717 job_load_timing.connect_timing.connect_end =
1718 now - base::TimeDelta::FromDays(1);
1719
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00001720 LoadTimingInfo load_timing_result =
1721 RunLoadTimingTest(job_load_timing, &default_context_);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001722
1723 // Proxy times, connect times, and DNS times should all be replaced with
1724 // request_start.
1725 EXPECT_EQ(load_timing_result.request_start,
1726 load_timing_result.proxy_resolve_start);
1727 EXPECT_EQ(load_timing_result.request_start,
1728 load_timing_result.proxy_resolve_end);
1729 EXPECT_EQ(load_timing_result.request_start,
1730 load_timing_result.connect_timing.dns_start);
1731 EXPECT_EQ(load_timing_result.request_start,
1732 load_timing_result.connect_timing.dns_end);
1733 EXPECT_EQ(load_timing_result.request_start,
1734 load_timing_result.connect_timing.connect_start);
1735 EXPECT_EQ(load_timing_result.request_start,
1736 load_timing_result.connect_timing.connect_end);
1737
1738 // Other times should have been left null.
1739 TestLoadTimingNotReusedWithProxy(load_timing_result,
1740 CONNECT_TIMING_HAS_DNS_TIMES);
1741}
1742
1743// Same as above, but in the reused case.
1744TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolutionReused) {
1745 base::TimeTicks now = base::TimeTicks::Now();
1746 LoadTimingInfo job_load_timing = NormalLoadTimingInfoReused(now, true);
1747 job_load_timing.proxy_resolve_start = now - base::TimeDelta::FromDays(4);
1748 job_load_timing.proxy_resolve_end = now - base::TimeDelta::FromDays(3);
1749
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00001750 LoadTimingInfo load_timing_result =
1751 RunLoadTimingTest(job_load_timing, &default_context_);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001752
1753 // Proxy times and connect times should all be replaced with request_start.
1754 EXPECT_EQ(load_timing_result.request_start,
1755 load_timing_result.proxy_resolve_start);
1756 EXPECT_EQ(load_timing_result.request_start,
1757 load_timing_result.proxy_resolve_end);
1758
1759 // Other times should have been left null.
1760 TestLoadTimingReusedWithProxy(load_timing_result);
1761}
1762
1763// Make sure that URLRequest correctly adjusts connect times when they're before
1764// |request_start|, due to reusing a connected socket. The connected socket is
1765// not considered reused in this test (May be a preconnect).
1766//
1767// To mix things up, the request has SSL times, but no DNS times.
1768TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnect) {
1769 base::TimeTicks now = base::TimeTicks::Now();
1770 LoadTimingInfo job_load_timing =
1771 NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, false);
1772 job_load_timing.connect_timing.connect_start =
1773 now - base::TimeDelta::FromDays(1);
1774 job_load_timing.connect_timing.ssl_start = now - base::TimeDelta::FromDays(2);
1775 job_load_timing.connect_timing.ssl_end = now - base::TimeDelta::FromDays(3);
1776 job_load_timing.connect_timing.connect_end =
1777 now - base::TimeDelta::FromDays(4);
1778
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00001779 LoadTimingInfo load_timing_result =
1780 RunLoadTimingTest(job_load_timing, &default_context_);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001781
1782 // Connect times, and SSL times should be replaced with request_start.
1783 EXPECT_EQ(load_timing_result.request_start,
1784 load_timing_result.connect_timing.connect_start);
1785 EXPECT_EQ(load_timing_result.request_start,
1786 load_timing_result.connect_timing.ssl_start);
1787 EXPECT_EQ(load_timing_result.request_start,
1788 load_timing_result.connect_timing.ssl_end);
1789 EXPECT_EQ(load_timing_result.request_start,
1790 load_timing_result.connect_timing.connect_end);
1791
1792 // Other times should have been left null.
1793 TestLoadTimingNotReused(load_timing_result, CONNECT_TIMING_HAS_SSL_TIMES);
1794}
1795
1796// Make sure that URLRequest correctly adjusts connect times when they're before
1797// |request_start|, due to reusing a connected socket in the case that there
1798// are also proxy times. The connected socket is not considered reused in this
1799// test (May be a preconnect).
1800//
1801// In this test, there are no SSL or DNS times.
1802TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnectWithProxy) {
1803 base::TimeTicks now = base::TimeTicks::Now();
1804 LoadTimingInfo job_load_timing =
1805 NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY, true);
1806 job_load_timing.connect_timing.connect_start =
1807 now - base::TimeDelta::FromDays(1);
1808 job_load_timing.connect_timing.connect_end =
1809 now - base::TimeDelta::FromDays(2);
1810
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00001811 LoadTimingInfo load_timing_result =
1812 RunLoadTimingTest(job_load_timing, &default_context_);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001813
1814 // Connect times should be replaced with proxy_resolve_end.
1815 EXPECT_EQ(load_timing_result.proxy_resolve_end,
1816 load_timing_result.connect_timing.connect_start);
1817 EXPECT_EQ(load_timing_result.proxy_resolve_end,
1818 load_timing_result.connect_timing.connect_end);
1819
1820 // Other times should have been left null.
1821 TestLoadTimingNotReusedWithProxy(load_timing_result,
1822 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
1823}
1824
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001825// Check that two different URL requests have different identifiers.
1826TEST_F(URLRequestTest, Identifiers) {
1827 TestDelegate d;
1828 TestURLRequestContext context;
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00001829 TestURLRequest req(
1830 GURL("http://example.com"), DEFAULT_PRIORITY, &d, &context);
1831 TestURLRequest other_req(
1832 GURL("http://example.com"), DEFAULT_PRIORITY, &d, &context);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001833
1834 ASSERT_NE(req.identifier(), other_req.identifier());
1835}
1836
1837// Check that a failure to connect to the proxy is reported to the network
1838// delegate.
1839TEST_F(URLRequestTest, NetworkDelegateProxyError) {
1840 MockHostResolver host_resolver;
1841 host_resolver.rules()->AddSimulatedFailure("*");
1842
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001843 TestNetworkDelegate network_delegate; // Must outlive URLRequests.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001844 TestURLRequestContextWithProxy context("myproxy:70", &network_delegate);
1845
1846 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001847 scoped_ptr<URLRequest> req(context.CreateRequest(
1848 GURL("http://example.com"), DEFAULT_PRIORITY, &d, NULL));
1849 req->set_method("GET");
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001850
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001851 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001852 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001853
1854 // Check we see a failed request.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001855 EXPECT_FALSE(req->status().is_success());
Torne (Richard Coles)f8ee7882014-06-20 14:52:04 +01001856 // The proxy server is not set before failure.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001857 EXPECT_TRUE(req->proxy_server().IsEmpty());
1858 EXPECT_EQ(URLRequestStatus::FAILED, req->status().status());
1859 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, req->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001860
1861 EXPECT_EQ(1, network_delegate.error_count());
1862 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, network_delegate.last_error());
1863 EXPECT_EQ(1, network_delegate.completed_requests());
1864}
1865
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01001866// Make sure that NetworkDelegate::NotifyCompleted is called if
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001867// content is empty.
1868TEST_F(URLRequestTest, RequestCompletionForEmptyResponse) {
1869 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001870 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1871 GURL("data:,"), DEFAULT_PRIORITY, &d, NULL));
1872 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001873 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001874 EXPECT_EQ("", d.data_received());
1875 EXPECT_EQ(1, default_network_delegate_.completed_requests());
1876}
1877
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001878// Make sure that SetPriority actually sets the URLRequest's priority
1879// correctly, both before and after start.
1880TEST_F(URLRequestTest, SetPriorityBasic) {
1881 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001882 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1883 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
1884 EXPECT_EQ(DEFAULT_PRIORITY, req->priority());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001885
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001886 req->SetPriority(LOW);
1887 EXPECT_EQ(LOW, req->priority());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001888
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001889 req->Start();
1890 EXPECT_EQ(LOW, req->priority());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001891
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001892 req->SetPriority(MEDIUM);
1893 EXPECT_EQ(MEDIUM, req->priority());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001894}
1895
1896// Make sure that URLRequest calls SetPriority on a job before calling
1897// Start on it.
1898TEST_F(URLRequestTest, SetJobPriorityBeforeJobStart) {
1899 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001900 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1901 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
1902 EXPECT_EQ(DEFAULT_PRIORITY, req->priority());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001903
1904 scoped_refptr<URLRequestTestJob> job =
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001905 new URLRequestTestJob(req.get(), &default_network_delegate_);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01001906 AddTestInterceptor()->set_main_intercept_job(job.get());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001907 EXPECT_EQ(DEFAULT_PRIORITY, job->priority());
1908
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001909 req->SetPriority(LOW);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001910
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001911 req->Start();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001912 EXPECT_EQ(LOW, job->priority());
1913}
1914
1915// Make sure that URLRequest passes on its priority updates to its
1916// job.
1917TEST_F(URLRequestTest, SetJobPriority) {
1918 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001919 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1920 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001921
1922 scoped_refptr<URLRequestTestJob> job =
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001923 new URLRequestTestJob(req.get(), &default_network_delegate_);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01001924 AddTestInterceptor()->set_main_intercept_job(job.get());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001925
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001926 req->SetPriority(LOW);
1927 req->Start();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001928 EXPECT_EQ(LOW, job->priority());
1929
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001930 req->SetPriority(MEDIUM);
1931 EXPECT_EQ(MEDIUM, req->priority());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001932 EXPECT_EQ(MEDIUM, job->priority());
1933}
1934
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +00001935// Setting the IGNORE_LIMITS load flag should be okay if the priority
1936// is MAXIMUM_PRIORITY.
1937TEST_F(URLRequestTest, PriorityIgnoreLimits) {
1938 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001939 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
1940 GURL("http://test_intercept/foo"), MAXIMUM_PRIORITY, &d, NULL));
1941 EXPECT_EQ(MAXIMUM_PRIORITY, req->priority());
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +00001942
1943 scoped_refptr<URLRequestTestJob> job =
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001944 new URLRequestTestJob(req.get(), &default_network_delegate_);
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +00001945 AddTestInterceptor()->set_main_intercept_job(job.get());
1946
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001947 req->SetLoadFlags(LOAD_IGNORE_LIMITS);
1948 EXPECT_EQ(MAXIMUM_PRIORITY, req->priority());
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +00001949
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001950 req->SetPriority(MAXIMUM_PRIORITY);
1951 EXPECT_EQ(MAXIMUM_PRIORITY, req->priority());
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +00001952
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001953 req->Start();
1954 EXPECT_EQ(MAXIMUM_PRIORITY, req->priority());
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +00001955 EXPECT_EQ(MAXIMUM_PRIORITY, job->priority());
1956}
1957
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001958// TODO(droger): Support SpawnedTestServer on iOS (see http://crbug.com/148666).
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001959#if !defined(OS_IOS)
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001960// A subclass of SpawnedTestServer that uses a statically-configured hostname.
1961// This is to work around mysterious failures in chrome_frame_net_tests. See:
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001962// http://crbug.com/114369
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00001963// TODO(erikwright): remove or update as needed; see http://crbug.com/334634.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001964class LocalHttpTestServer : public SpawnedTestServer {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001965 public:
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001966 explicit LocalHttpTestServer(const base::FilePath& document_root)
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001967 : SpawnedTestServer(SpawnedTestServer::TYPE_HTTP,
1968 ScopedCustomUrlRequestTestHttpHost::value(),
1969 document_root) {}
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001970 LocalHttpTestServer()
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01001971 : SpawnedTestServer(SpawnedTestServer::TYPE_HTTP,
1972 ScopedCustomUrlRequestTestHttpHost::value(),
1973 base::FilePath()) {}
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001974};
1975
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001976TEST_F(URLRequestTest, DelayedCookieCallback) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001977 LocalHttpTestServer test_server;
1978 ASSERT_TRUE(test_server.Start());
1979
1980 TestURLRequestContext context;
1981 scoped_refptr<DelayedCookieMonster> delayed_cm =
1982 new DelayedCookieMonster();
1983 scoped_refptr<CookieStore> cookie_store = delayed_cm;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01001984 context.set_cookie_store(delayed_cm.get());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001985
1986 // Set up a cookie.
1987 {
1988 TestNetworkDelegate network_delegate;
1989 context.set_network_delegate(&network_delegate);
1990 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01001991 scoped_ptr<URLRequest> req(context.CreateRequest(
1992 test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
1993 &d, NULL));
1994 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01001995 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001996 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
1997 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
1998 EXPECT_EQ(1, network_delegate.set_cookie_count());
1999 }
2000
2001 // Verify that the cookie is set.
2002 {
2003 TestNetworkDelegate network_delegate;
2004 context.set_network_delegate(&network_delegate);
2005 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002006 scoped_ptr<URLRequest> req(context.CreateRequest(
2007 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL));
2008 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002009 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002010
2011 EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
2012 != std::string::npos);
2013 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2014 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2015 }
2016}
2017
2018TEST_F(URLRequestTest, DoNotSendCookies) {
2019 LocalHttpTestServer test_server;
2020 ASSERT_TRUE(test_server.Start());
2021
2022 // Set up a cookie.
2023 {
2024 TestNetworkDelegate network_delegate;
2025 default_context_.set_network_delegate(&network_delegate);
2026 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002027 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2028 test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
2029 &d, NULL));
2030 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002031 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002032 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2033 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2034 }
2035
2036 // Verify that the cookie is set.
2037 {
2038 TestNetworkDelegate network_delegate;
2039 default_context_.set_network_delegate(&network_delegate);
2040 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002041 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2042 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL));
2043 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002044 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002045
2046 EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
2047 != std::string::npos);
2048 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2049 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2050 }
2051
2052 // Verify that the cookie isn't sent when LOAD_DO_NOT_SEND_COOKIES is set.
2053 {
2054 TestNetworkDelegate network_delegate;
2055 default_context_.set_network_delegate(&network_delegate);
2056 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002057 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2058 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL));
2059 req->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES);
2060 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002061 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002062
2063 EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1")
2064 == std::string::npos);
2065
2066 // LOAD_DO_NOT_SEND_COOKIES does not trigger OnGetCookies.
2067 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2068 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2069 }
2070}
2071
2072TEST_F(URLRequestTest, DoNotSaveCookies) {
2073 LocalHttpTestServer test_server;
2074 ASSERT_TRUE(test_server.Start());
2075
2076 // Set up a cookie.
2077 {
2078 TestNetworkDelegate network_delegate;
2079 default_context_.set_network_delegate(&network_delegate);
2080 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002081 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2082 test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY,
2083 &d, NULL));
2084 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002085 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002086
2087 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2088 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2089 EXPECT_EQ(1, network_delegate.set_cookie_count());
2090 }
2091
2092 // Try to set-up another cookie and update the previous cookie.
2093 {
2094 TestNetworkDelegate network_delegate;
2095 default_context_.set_network_delegate(&network_delegate);
2096 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002097 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002098 test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002099 DEFAULT_PRIORITY, &d, NULL));
2100 req->SetLoadFlags(LOAD_DO_NOT_SAVE_COOKIES);
2101 req->Start();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002102
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002103 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002104
2105 // LOAD_DO_NOT_SAVE_COOKIES does not trigger OnSetCookie.
2106 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2107 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2108 EXPECT_EQ(0, network_delegate.set_cookie_count());
2109 }
2110
2111 // Verify the cookies weren't saved or updated.
2112 {
2113 TestNetworkDelegate network_delegate;
2114 default_context_.set_network_delegate(&network_delegate);
2115 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002116 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2117 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL));
2118 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002119 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002120
2121 EXPECT_TRUE(d.data_received().find("CookieToNotSave=1")
2122 == std::string::npos);
2123 EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2")
2124 != std::string::npos);
2125
2126 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2127 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2128 EXPECT_EQ(0, network_delegate.set_cookie_count());
2129 }
2130}
2131
2132TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy) {
2133 LocalHttpTestServer test_server;
2134 ASSERT_TRUE(test_server.Start());
2135
2136 // Set up a cookie.
2137 {
2138 TestNetworkDelegate network_delegate;
2139 default_context_.set_network_delegate(&network_delegate);
2140 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002141 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2142 test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
2143 &d, NULL));
2144 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002145 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002146
2147 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2148 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2149 }
2150
2151 // Verify that the cookie is set.
2152 {
2153 TestNetworkDelegate network_delegate;
2154 default_context_.set_network_delegate(&network_delegate);
2155 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002156 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2157 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL));
2158 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002159 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002160
2161 EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
2162 != std::string::npos);
2163
2164 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2165 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2166 }
2167
2168 // Verify that the cookie isn't sent.
2169 {
2170 TestNetworkDelegate network_delegate;
2171 default_context_.set_network_delegate(&network_delegate);
2172 TestDelegate d;
2173 network_delegate.set_cookie_options(TestNetworkDelegate::NO_GET_COOKIES);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002174 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2175 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL));
2176 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002177 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002178
2179 EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1")
2180 == std::string::npos);
2181
2182 EXPECT_EQ(1, network_delegate.blocked_get_cookies_count());
2183 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2184 }
2185}
2186
2187TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy) {
2188 LocalHttpTestServer test_server;
2189 ASSERT_TRUE(test_server.Start());
2190
2191 // Set up a cookie.
2192 {
2193 TestNetworkDelegate network_delegate;
2194 default_context_.set_network_delegate(&network_delegate);
2195 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002196 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2197 test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY,
2198 &d, NULL));
2199 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002200 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002201
2202 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2203 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2204 }
2205
2206 // Try to set-up another cookie and update the previous cookie.
2207 {
2208 TestNetworkDelegate network_delegate;
2209 default_context_.set_network_delegate(&network_delegate);
2210 TestDelegate d;
2211 network_delegate.set_cookie_options(TestNetworkDelegate::NO_SET_COOKIE);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002212 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002213 test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002214 DEFAULT_PRIORITY, &d, NULL));
2215 req->Start();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002216
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002217 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002218
2219 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2220 EXPECT_EQ(2, network_delegate.blocked_set_cookie_count());
2221 }
2222
2223 // Verify the cookies weren't saved or updated.
2224 {
2225 TestNetworkDelegate network_delegate;
2226 default_context_.set_network_delegate(&network_delegate);
2227 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002228 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2229 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL));
2230 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002231 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002232
2233 EXPECT_TRUE(d.data_received().find("CookieToNotSave=1")
2234 == std::string::npos);
2235 EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2")
2236 != std::string::npos);
2237
2238 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2239 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2240 }
2241}
2242
2243TEST_F(URLRequestTest, DoNotSaveEmptyCookies) {
2244 LocalHttpTestServer test_server;
2245 ASSERT_TRUE(test_server.Start());
2246
2247 // Set up an empty cookie.
2248 {
2249 TestNetworkDelegate network_delegate;
2250 default_context_.set_network_delegate(&network_delegate);
2251 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002252 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2253 test_server.GetURL("set-cookie"), DEFAULT_PRIORITY, &d, NULL));
2254 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002255 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002256
2257 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2258 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2259 EXPECT_EQ(0, network_delegate.set_cookie_count());
2260 }
2261}
2262
2263TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy_Async) {
2264 LocalHttpTestServer test_server;
2265 ASSERT_TRUE(test_server.Start());
2266
2267 // Set up a cookie.
2268 {
2269 TestNetworkDelegate network_delegate;
2270 default_context_.set_network_delegate(&network_delegate);
2271 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002272 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2273 test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
2274 &d, NULL));
2275 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002276 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002277
2278 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2279 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2280 }
2281
2282 // Verify that the cookie is set.
2283 {
2284 TestNetworkDelegate network_delegate;
2285 default_context_.set_network_delegate(&network_delegate);
2286 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002287 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2288 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL));
2289 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002290 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002291
2292 EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
2293 != std::string::npos);
2294
2295 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2296 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2297 }
2298
2299 // Verify that the cookie isn't sent.
2300 {
2301 TestNetworkDelegate network_delegate;
2302 default_context_.set_network_delegate(&network_delegate);
2303 TestDelegate d;
2304 network_delegate.set_cookie_options(TestNetworkDelegate::NO_GET_COOKIES);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002305 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2306 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL));
2307 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002308 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002309
2310 EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1")
2311 == std::string::npos);
2312
2313 EXPECT_EQ(1, network_delegate.blocked_get_cookies_count());
2314 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2315 }
2316}
2317
2318TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy_Async) {
2319 LocalHttpTestServer test_server;
2320 ASSERT_TRUE(test_server.Start());
2321
2322 // Set up a cookie.
2323 {
2324 TestNetworkDelegate network_delegate;
2325 default_context_.set_network_delegate(&network_delegate);
2326 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002327 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2328 test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY,
2329 &d, NULL));
2330 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002331 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002332
2333 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2334 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2335 }
2336
2337 // Try to set-up another cookie and update the previous cookie.
2338 {
2339 TestNetworkDelegate network_delegate;
2340 default_context_.set_network_delegate(&network_delegate);
2341 TestDelegate d;
2342 network_delegate.set_cookie_options(TestNetworkDelegate::NO_SET_COOKIE);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002343 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002344 test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002345 DEFAULT_PRIORITY, &d, NULL));
2346 req->Start();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002347
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002348 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002349
2350 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2351 EXPECT_EQ(2, network_delegate.blocked_set_cookie_count());
2352 }
2353
2354 // Verify the cookies weren't saved or updated.
2355 {
2356 TestNetworkDelegate network_delegate;
2357 default_context_.set_network_delegate(&network_delegate);
2358 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002359 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2360 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL));
2361 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002362 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002363
2364 EXPECT_TRUE(d.data_received().find("CookieToNotSave=1")
2365 == std::string::npos);
2366 EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2")
2367 != std::string::npos);
2368
2369 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
2370 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
2371 }
2372}
2373
2374// FixedDateNetworkDelegate swaps out the server's HTTP Date response header
2375// value for the |fixed_date| argument given to the constructor.
2376class FixedDateNetworkDelegate : public TestNetworkDelegate {
2377 public:
2378 explicit FixedDateNetworkDelegate(const std::string& fixed_date)
2379 : fixed_date_(fixed_date) {}
2380 virtual ~FixedDateNetworkDelegate() {}
2381
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01002382 // NetworkDelegate implementation
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002383 virtual int OnHeadersReceived(
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01002384 URLRequest* request,
2385 const CompletionCallback& callback,
2386 const HttpResponseHeaders* original_response_headers,
2387 scoped_refptr<HttpResponseHeaders>* override_response_headers,
Ben Murdocheffb81e2014-03-31 11:51:25 +01002388 GURL* allowed_unsafe_redirect_url) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002389
2390 private:
2391 std::string fixed_date_;
2392
2393 DISALLOW_COPY_AND_ASSIGN(FixedDateNetworkDelegate);
2394};
2395
2396int FixedDateNetworkDelegate::OnHeadersReceived(
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01002397 URLRequest* request,
2398 const CompletionCallback& callback,
2399 const HttpResponseHeaders* original_response_headers,
2400 scoped_refptr<HttpResponseHeaders>* override_response_headers,
Ben Murdocheffb81e2014-03-31 11:51:25 +01002401 GURL* allowed_unsafe_redirect_url) {
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01002402 HttpResponseHeaders* new_response_headers =
2403 new HttpResponseHeaders(original_response_headers->raw_headers());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002404
2405 new_response_headers->RemoveHeader("Date");
2406 new_response_headers->AddHeader("Date: " + fixed_date_);
2407
2408 *override_response_headers = new_response_headers;
2409 return TestNetworkDelegate::OnHeadersReceived(request,
2410 callback,
2411 original_response_headers,
Ben Murdocheffb81e2014-03-31 11:51:25 +01002412 override_response_headers,
2413 allowed_unsafe_redirect_url);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002414}
2415
2416// Test that cookie expiration times are adjusted for server/client clock
2417// skew and that we handle incorrect timezone specifier "UTC" in HTTP Date
2418// headers by defaulting to GMT. (crbug.com/135131)
2419TEST_F(URLRequestTest, AcceptClockSkewCookieWithWrongDateTimezone) {
2420 LocalHttpTestServer test_server;
2421 ASSERT_TRUE(test_server.Start());
2422
2423 // Set up an expired cookie.
2424 {
2425 TestNetworkDelegate network_delegate;
2426 default_context_.set_network_delegate(&network_delegate);
2427 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002428 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00002429 test_server.GetURL(
2430 "set-cookie?StillGood=1;expires=Mon,18-Apr-1977,22:50:13,GMT"),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002431 DEFAULT_PRIORITY, &d, NULL));
2432 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002433 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002434 }
2435 // Verify that the cookie is not set.
2436 {
2437 TestNetworkDelegate network_delegate;
2438 default_context_.set_network_delegate(&network_delegate);
2439 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002440 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2441 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL));
2442 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002443 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002444
2445 EXPECT_TRUE(d.data_received().find("StillGood=1") == std::string::npos);
2446 }
2447 // Set up a cookie with clock skew and "UTC" HTTP Date timezone specifier.
2448 {
2449 FixedDateNetworkDelegate network_delegate("18-Apr-1977 22:49:13 UTC");
2450 default_context_.set_network_delegate(&network_delegate);
2451 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002452 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00002453 test_server.GetURL(
2454 "set-cookie?StillGood=1;expires=Mon,18-Apr-1977,22:50:13,GMT"),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002455 DEFAULT_PRIORITY, &d, NULL));
2456 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002457 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002458 }
2459 // Verify that the cookie is set.
2460 {
2461 TestNetworkDelegate network_delegate;
2462 default_context_.set_network_delegate(&network_delegate);
2463 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002464 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2465 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL));
2466 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002467 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002468
2469 EXPECT_TRUE(d.data_received().find("StillGood=1") != std::string::npos);
2470 }
2471}
2472
2473
2474// Check that it is impossible to change the referrer in the extra headers of
2475// an URLRequest.
2476TEST_F(URLRequestTest, DoNotOverrideReferrer) {
2477 LocalHttpTestServer test_server;
2478 ASSERT_TRUE(test_server.Start());
2479
2480 // If extra headers contain referer and the request contains a referer,
2481 // only the latter shall be respected.
2482 {
2483 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002484 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2485 test_server.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL));
2486 req->SetReferrer("http://foo.com/");
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002487
2488 HttpRequestHeaders headers;
2489 headers.SetHeader(HttpRequestHeaders::kReferer, "http://bar.com/");
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002490 req->SetExtraRequestHeaders(headers);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002491
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002492 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002493 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002494
2495 EXPECT_EQ("http://foo.com/", d.data_received());
2496 }
2497
2498 // If extra headers contain a referer but the request does not, no referer
2499 // shall be sent in the header.
2500 {
2501 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002502 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2503 test_server.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002504
2505 HttpRequestHeaders headers;
2506 headers.SetHeader(HttpRequestHeaders::kReferer, "http://bar.com/");
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002507 req->SetExtraRequestHeaders(headers);
2508 req->SetLoadFlags(LOAD_VALIDATE_CACHE);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002509
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002510 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002511 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002512
2513 EXPECT_EQ("None", d.data_received());
2514 }
2515}
2516
2517class URLRequestTestHTTP : public URLRequestTest {
2518 public:
2519 URLRequestTestHTTP()
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002520 : test_server_(base::FilePath(FILE_PATH_LITERAL(
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002521 "net/data/url_request_unittest"))) {
2522 }
2523
2524 protected:
2525 // Requests |redirect_url|, which must return a HTTP 3xx redirect.
2526 // |request_method| is the method to use for the initial request.
2527 // |redirect_method| is the method that is expected to be used for the second
2528 // request, after redirection.
2529 // If |include_data| is true, data is uploaded with the request. The
2530 // response body is expected to match it exactly, if and only if
2531 // |request_method| == |redirect_method|.
2532 void HTTPRedirectMethodTest(const GURL& redirect_url,
2533 const std::string& request_method,
2534 const std::string& redirect_method,
2535 bool include_data) {
2536 static const char kData[] = "hello world";
2537 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002538 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
2539 redirect_url, DEFAULT_PRIORITY, &d, NULL));
2540 req->set_method(request_method);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002541 if (include_data) {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002542 req->set_upload(make_scoped_ptr(CreateSimpleUploadData(kData)));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002543 HttpRequestHeaders headers;
2544 headers.SetHeader(HttpRequestHeaders::kContentLength,
2545 base::UintToString(arraysize(kData) - 1));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002546 req->SetExtraRequestHeaders(headers);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002547 }
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002548 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002549 base::RunLoop().Run();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002550 EXPECT_EQ(redirect_method, req->method());
2551 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
2552 EXPECT_EQ(OK, req->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002553 if (include_data) {
2554 if (request_method == redirect_method) {
2555 EXPECT_EQ(kData, d.data_received());
2556 } else {
2557 EXPECT_NE(kData, d.data_received());
2558 }
2559 }
2560 if (HasFailure())
2561 LOG(WARNING) << "Request method was: " << request_method;
2562 }
2563
2564 void HTTPUploadDataOperationTest(const std::string& method) {
2565 const int kMsgSize = 20000; // multiple of 10
2566 const int kIterations = 50;
2567 char* uploadBytes = new char[kMsgSize+1];
2568 char* ptr = uploadBytes;
2569 char marker = 'a';
2570 for (int idx = 0; idx < kMsgSize/10; idx++) {
2571 memcpy(ptr, "----------", 10);
2572 ptr += 10;
2573 if (idx % 100 == 0) {
2574 ptr--;
2575 *ptr++ = marker;
2576 if (++marker > 'z')
2577 marker = 'a';
2578 }
2579 }
2580 uploadBytes[kMsgSize] = '\0';
2581
2582 for (int i = 0; i < kIterations; ++i) {
2583 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002584 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
2585 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL));
2586 r->set_method(method.c_str());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002587
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002588 r->set_upload(make_scoped_ptr(CreateSimpleUploadData(uploadBytes)));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002589
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002590 r->Start();
2591 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002592
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002593 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002594
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002595 ASSERT_EQ(1, d.response_started_count())
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002596 << "request failed: " << r->status().status()
2597 << ", os error: " << r->status().error();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002598
2599 EXPECT_FALSE(d.received_data_before_response());
2600 EXPECT_EQ(uploadBytes, d.data_received());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002601 }
2602 delete[] uploadBytes;
2603 }
2604
2605 void AddChunksToUpload(URLRequest* r) {
2606 r->AppendChunkToUpload("a", 1, false);
2607 r->AppendChunkToUpload("bcd", 3, false);
2608 r->AppendChunkToUpload("this is a longer chunk than before.", 35, false);
2609 r->AppendChunkToUpload("\r\n\r\n", 4, false);
2610 r->AppendChunkToUpload("0", 1, false);
2611 r->AppendChunkToUpload("2323", 4, true);
2612 }
2613
2614 void VerifyReceivedDataMatchesChunks(URLRequest* r, TestDelegate* d) {
2615 // This should match the chunks sent by AddChunksToUpload().
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002616 const std::string expected_data =
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002617 "abcdthis is a longer chunk than before.\r\n\r\n02323";
2618
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002619 ASSERT_EQ(1, d->response_started_count())
2620 << "request failed: " << r->status().status()
2621 << ", os error: " << r->status().error();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002622
2623 EXPECT_FALSE(d->received_data_before_response());
2624
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002625 EXPECT_EQ(expected_data.size(), static_cast<size_t>(d->bytes_received()));
2626 EXPECT_EQ(expected_data, d->data_received());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002627 }
2628
2629 bool DoManyCookiesRequest(int num_cookies) {
2630 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002631 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
2632 test_server_.GetURL("set-many-cookies?" +
2633 base::IntToString(num_cookies)),
2634 DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002635
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002636 r->Start();
2637 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002638
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002639 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002640
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002641 bool is_success = r->status().is_success();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002642
2643 if (!is_success) {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002644 EXPECT_TRUE(r->status().error() == ERR_RESPONSE_HEADERS_TOO_BIG);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002645 // The test server appears to be unable to handle subsequent requests
2646 // after this error is triggered. Force it to restart.
2647 EXPECT_TRUE(test_server_.Stop());
2648 EXPECT_TRUE(test_server_.Start());
2649 }
2650
2651 return is_success;
2652 }
2653
2654 LocalHttpTestServer test_server_;
2655};
2656
2657// In this unit test, we're using the HTTPTestServer as a proxy server and
2658// issuing a CONNECT request with the magic host name "www.redirect.com".
2659// The HTTPTestServer will return a 302 response, which we should not
2660// follow.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002661TEST_F(URLRequestTestHTTP, ProxyTunnelRedirectTest) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002662 ASSERT_TRUE(test_server_.Start());
2663
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002664 TestNetworkDelegate network_delegate; // Must outlive URLRequest.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002665 TestURLRequestContextWithProxy context(
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00002666 test_server_.host_port_pair().ToString(), &network_delegate);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002667
2668 TestDelegate d;
2669 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002670 scoped_ptr<URLRequest> r(context.CreateRequest(
2671 GURL("https://www.redirect.com/"), DEFAULT_PRIORITY, &d, NULL));
2672 r->Start();
2673 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002674
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002675 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002676
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002677 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
Torne (Richard Coles)f8ee7882014-06-20 14:52:04 +01002678 // The proxy server is not set before failure.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002679 EXPECT_TRUE(r->proxy_server().IsEmpty());
2680 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002681 EXPECT_EQ(1, d.response_started_count());
2682 // We should not have followed the redirect.
2683 EXPECT_EQ(0, d.received_redirect_count());
2684 }
2685}
2686
2687// This is the same as the previous test, but checks that the network delegate
2688// registers the error.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002689TEST_F(URLRequestTestHTTP, NetworkDelegateTunnelConnectionFailed) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002690 ASSERT_TRUE(test_server_.Start());
2691
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00002692 TestNetworkDelegate network_delegate; // Must outlive URLRequest.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002693 TestURLRequestContextWithProxy context(
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00002694 test_server_.host_port_pair().ToString(), &network_delegate);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002695
2696 TestDelegate d;
2697 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002698 scoped_ptr<URLRequest> r(context.CreateRequest(
2699 GURL("https://www.redirect.com/"), DEFAULT_PRIORITY, &d, NULL));
2700 r->Start();
2701 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002702
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002703 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002704
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002705 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
Torne (Richard Coles)f8ee7882014-06-20 14:52:04 +01002706 // The proxy server is not set before failure.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002707 EXPECT_TRUE(r->proxy_server().IsEmpty());
2708 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002709 EXPECT_EQ(1, d.response_started_count());
2710 // We should not have followed the redirect.
2711 EXPECT_EQ(0, d.received_redirect_count());
2712
2713 EXPECT_EQ(1, network_delegate.error_count());
2714 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, network_delegate.last_error());
2715 }
2716}
2717
2718// Tests that we can block and asynchronously return OK in various stages.
2719TEST_F(URLRequestTestHTTP, NetworkDelegateBlockAsynchronously) {
2720 static const BlockingNetworkDelegate::Stage blocking_stages[] = {
2721 BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST,
2722 BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS,
2723 BlockingNetworkDelegate::ON_HEADERS_RECEIVED
2724 };
2725 static const size_t blocking_stages_length = arraysize(blocking_stages);
2726
2727 ASSERT_TRUE(test_server_.Start());
2728
2729 TestDelegate d;
2730 BlockingNetworkDelegate network_delegate(
2731 BlockingNetworkDelegate::USER_CALLBACK);
2732 network_delegate.set_block_on(
2733 BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST |
2734 BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS |
2735 BlockingNetworkDelegate::ON_HEADERS_RECEIVED);
2736
2737 TestURLRequestContext context(true);
2738 context.set_network_delegate(&network_delegate);
2739 context.Init();
2740
2741 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002742 scoped_ptr<URLRequest> r(context.CreateRequest(
2743 test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002744
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002745 r->Start();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002746 for (size_t i = 0; i < blocking_stages_length; ++i) {
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002747 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002748 EXPECT_EQ(blocking_stages[i],
2749 network_delegate.stage_blocked_for_callback());
2750 network_delegate.DoCallback(OK);
2751 }
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002752 base::RunLoop().Run();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002753 EXPECT_EQ(200, r->GetResponseCode());
2754 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002755 EXPECT_EQ(1, network_delegate.created_requests());
2756 EXPECT_EQ(0, network_delegate.destroyed_requests());
2757 }
2758 EXPECT_EQ(1, network_delegate.destroyed_requests());
2759}
2760
2761// Tests that the network delegate can block and cancel a request.
2762TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequest) {
2763 ASSERT_TRUE(test_server_.Start());
2764
2765 TestDelegate d;
2766 BlockingNetworkDelegate network_delegate(
2767 BlockingNetworkDelegate::AUTO_CALLBACK);
2768 network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST);
2769 network_delegate.set_retval(ERR_EMPTY_RESPONSE);
2770
2771 TestURLRequestContextWithProxy context(
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00002772 test_server_.host_port_pair().ToString(), &network_delegate);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002773
2774 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002775 scoped_ptr<URLRequest> r(context.CreateRequest(
2776 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002777
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002778 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002779 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002780
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002781 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
Torne (Richard Coles)f8ee7882014-06-20 14:52:04 +01002782 // The proxy server is not set before cancellation.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002783 EXPECT_TRUE(r->proxy_server().IsEmpty());
2784 EXPECT_EQ(ERR_EMPTY_RESPONSE, r->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002785 EXPECT_EQ(1, network_delegate.created_requests());
2786 EXPECT_EQ(0, network_delegate.destroyed_requests());
2787 }
2788 EXPECT_EQ(1, network_delegate.destroyed_requests());
2789}
2790
2791// Helper function for NetworkDelegateCancelRequestAsynchronously and
2792// NetworkDelegateCancelRequestSynchronously. Sets up a blocking network
2793// delegate operating in |block_mode| and a request for |url|. It blocks the
2794// request in |stage| and cancels it with ERR_BLOCKED_BY_CLIENT.
2795void NetworkDelegateCancelRequest(BlockingNetworkDelegate::BlockMode block_mode,
2796 BlockingNetworkDelegate::Stage stage,
2797 const GURL& url) {
2798 TestDelegate d;
2799 BlockingNetworkDelegate network_delegate(block_mode);
2800 network_delegate.set_retval(ERR_BLOCKED_BY_CLIENT);
2801 network_delegate.set_block_on(stage);
2802
2803 TestURLRequestContext context(true);
2804 context.set_network_delegate(&network_delegate);
2805 context.Init();
2806
2807 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002808 scoped_ptr<URLRequest> r(context.CreateRequest(
2809 url, DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002810
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002811 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002812 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002813
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002814 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
Torne (Richard Coles)f8ee7882014-06-20 14:52:04 +01002815 // The proxy server is not set before cancellation.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002816 EXPECT_TRUE(r->proxy_server().IsEmpty());
2817 EXPECT_EQ(ERR_BLOCKED_BY_CLIENT, r->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002818 EXPECT_EQ(1, network_delegate.created_requests());
2819 EXPECT_EQ(0, network_delegate.destroyed_requests());
2820 }
2821 EXPECT_EQ(1, network_delegate.destroyed_requests());
2822}
2823
2824// The following 3 tests check that the network delegate can cancel a request
2825// synchronously in various stages of the request.
2826TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously1) {
2827 ASSERT_TRUE(test_server_.Start());
2828 NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS,
2829 BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002830 test_server_.GetURL(std::string()));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002831}
2832
2833TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously2) {
2834 ASSERT_TRUE(test_server_.Start());
2835 NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS,
2836 BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002837 test_server_.GetURL(std::string()));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002838}
2839
2840TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously3) {
2841 ASSERT_TRUE(test_server_.Start());
2842 NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS,
2843 BlockingNetworkDelegate::ON_HEADERS_RECEIVED,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002844 test_server_.GetURL(std::string()));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002845}
2846
2847// The following 3 tests check that the network delegate can cancel a request
2848// asynchronously in various stages of the request.
2849TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously1) {
2850 ASSERT_TRUE(test_server_.Start());
2851 NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK,
2852 BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002853 test_server_.GetURL(std::string()));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002854}
2855
2856TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously2) {
2857 ASSERT_TRUE(test_server_.Start());
2858 NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK,
2859 BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002860 test_server_.GetURL(std::string()));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002861}
2862
2863TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously3) {
2864 ASSERT_TRUE(test_server_.Start());
2865 NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK,
2866 BlockingNetworkDelegate::ON_HEADERS_RECEIVED,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01002867 test_server_.GetURL(std::string()));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002868}
2869
2870// Tests that the network delegate can block and redirect a request to a new
2871// URL.
2872TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequest) {
2873 ASSERT_TRUE(test_server_.Start());
2874
2875 TestDelegate d;
2876 BlockingNetworkDelegate network_delegate(
2877 BlockingNetworkDelegate::AUTO_CALLBACK);
2878 network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST);
2879 GURL redirect_url(test_server_.GetURL("simple.html"));
2880 network_delegate.set_redirect_url(redirect_url);
2881
2882 TestURLRequestContextWithProxy context(
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00002883 test_server_.host_port_pair().ToString(), &network_delegate);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002884
2885 {
2886 GURL original_url(test_server_.GetURL("empty.html"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002887 scoped_ptr<URLRequest> r(context.CreateRequest(
2888 original_url, DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002889
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01002890 // Quit after hitting the redirect, so can check the headers.
2891 d.set_quit_on_redirect(true);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002892 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002893 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002894
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01002895 // Check headers from URLRequestJob.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002896 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
2897 EXPECT_EQ(307, r->GetResponseCode());
2898 EXPECT_EQ(307, r->response_headers()->response_code());
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01002899 std::string location;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002900 ASSERT_TRUE(r->response_headers()->EnumerateHeader(NULL, "Location",
2901 &location));
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01002902 EXPECT_EQ(redirect_url, GURL(location));
2903
2904 // Let the request finish.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002905 r->FollowDeferredRedirect();
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01002906 base::RunLoop().Run();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002907 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
2908 EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair()));
Ben Murdoch116680a2014-07-20 18:25:52 -07002909 EXPECT_EQ(
2910 1, network_delegate.observed_before_proxy_headers_sent_callbacks());
2911 EXPECT_TRUE(
2912 network_delegate.last_observed_proxy().Equals(
2913 test_server_.host_port_pair()));
2914
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002915 EXPECT_EQ(0, r->status().error());
2916 EXPECT_EQ(redirect_url, r->url());
2917 EXPECT_EQ(original_url, r->original_url());
2918 EXPECT_EQ(2U, r->url_chain().size());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002919 EXPECT_EQ(1, network_delegate.created_requests());
2920 EXPECT_EQ(0, network_delegate.destroyed_requests());
2921 }
2922 EXPECT_EQ(1, network_delegate.destroyed_requests());
2923}
2924
2925// Tests that the network delegate can block and redirect a request to a new
2926// URL by setting a redirect_url and returning in OnBeforeURLRequest directly.
2927TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestSynchronously) {
2928 ASSERT_TRUE(test_server_.Start());
2929
2930 TestDelegate d;
2931 BlockingNetworkDelegate network_delegate(
2932 BlockingNetworkDelegate::SYNCHRONOUS);
2933 GURL redirect_url(test_server_.GetURL("simple.html"));
2934 network_delegate.set_redirect_url(redirect_url);
2935
2936 TestURLRequestContextWithProxy context(
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00002937 test_server_.host_port_pair().ToString(), &network_delegate);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002938
2939 {
2940 GURL original_url(test_server_.GetURL("empty.html"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002941 scoped_ptr<URLRequest> r(context.CreateRequest(
2942 original_url, DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002943
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01002944 // Quit after hitting the redirect, so can check the headers.
2945 d.set_quit_on_redirect(true);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002946 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01002947 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002948
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01002949 // Check headers from URLRequestJob.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002950 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
2951 EXPECT_EQ(307, r->GetResponseCode());
2952 EXPECT_EQ(307, r->response_headers()->response_code());
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01002953 std::string location;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002954 ASSERT_TRUE(r->response_headers()->EnumerateHeader(NULL, "Location",
2955 &location));
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01002956 EXPECT_EQ(redirect_url, GURL(location));
2957
2958 // Let the request finish.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002959 r->FollowDeferredRedirect();
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01002960 base::RunLoop().Run();
2961
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002962 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
2963 EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair()));
Ben Murdoch116680a2014-07-20 18:25:52 -07002964 EXPECT_EQ(
2965 1, network_delegate.observed_before_proxy_headers_sent_callbacks());
2966 EXPECT_TRUE(
2967 network_delegate.last_observed_proxy().Equals(
2968 test_server_.host_port_pair()));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002969 EXPECT_EQ(0, r->status().error());
2970 EXPECT_EQ(redirect_url, r->url());
2971 EXPECT_EQ(original_url, r->original_url());
2972 EXPECT_EQ(2U, r->url_chain().size());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00002973 EXPECT_EQ(1, network_delegate.created_requests());
2974 EXPECT_EQ(0, network_delegate.destroyed_requests());
2975 }
2976 EXPECT_EQ(1, network_delegate.destroyed_requests());
2977}
2978
2979// Tests that redirects caused by the network delegate preserve POST data.
2980TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestPost) {
2981 ASSERT_TRUE(test_server_.Start());
2982
2983 const char kData[] = "hello world";
2984
2985 TestDelegate d;
2986 BlockingNetworkDelegate network_delegate(
2987 BlockingNetworkDelegate::AUTO_CALLBACK);
2988 network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST);
2989 GURL redirect_url(test_server_.GetURL("echo"));
2990 network_delegate.set_redirect_url(redirect_url);
2991
2992 TestURLRequestContext context(true);
2993 context.set_network_delegate(&network_delegate);
2994 context.Init();
2995
2996 {
2997 GURL original_url(test_server_.GetURL("empty.html"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01002998 scoped_ptr<URLRequest> r(context.CreateRequest(
2999 original_url, DEFAULT_PRIORITY, &d, NULL));
3000 r->set_method("POST");
3001 r->set_upload(make_scoped_ptr(CreateSimpleUploadData(kData)));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003002 HttpRequestHeaders headers;
3003 headers.SetHeader(HttpRequestHeaders::kContentLength,
3004 base::UintToString(arraysize(kData) - 1));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003005 r->SetExtraRequestHeaders(headers);
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01003006
3007 // Quit after hitting the redirect, so can check the headers.
3008 d.set_quit_on_redirect(true);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003009 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003010 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003011
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01003012 // Check headers from URLRequestJob.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003013 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
3014 EXPECT_EQ(307, r->GetResponseCode());
3015 EXPECT_EQ(307, r->response_headers()->response_code());
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01003016 std::string location;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003017 ASSERT_TRUE(r->response_headers()->EnumerateHeader(NULL, "Location",
3018 &location));
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01003019 EXPECT_EQ(redirect_url, GURL(location));
3020
3021 // Let the request finish.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003022 r->FollowDeferredRedirect();
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +01003023 base::RunLoop().Run();
3024
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003025 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
3026 EXPECT_EQ(0, r->status().error());
3027 EXPECT_EQ(redirect_url, r->url());
3028 EXPECT_EQ(original_url, r->original_url());
3029 EXPECT_EQ(2U, r->url_chain().size());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003030 EXPECT_EQ(1, network_delegate.created_requests());
3031 EXPECT_EQ(0, network_delegate.destroyed_requests());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003032 EXPECT_EQ("POST", r->method());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003033 EXPECT_EQ(kData, d.data_received());
3034 }
3035 EXPECT_EQ(1, network_delegate.destroyed_requests());
3036}
3037
Ben Murdocheffb81e2014-03-31 11:51:25 +01003038// Tests that the network delegate can block and redirect a request to a new
3039// URL during OnHeadersReceived.
3040TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestOnHeadersReceived) {
3041 ASSERT_TRUE(test_server_.Start());
3042
3043 TestDelegate d;
3044 BlockingNetworkDelegate network_delegate(
3045 BlockingNetworkDelegate::AUTO_CALLBACK);
3046 network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED);
3047 GURL redirect_url(test_server_.GetURL("simple.html"));
3048 network_delegate.set_redirect_on_headers_received_url(redirect_url);
3049
3050 TestURLRequestContextWithProxy context(
3051 test_server_.host_port_pair().ToString(), &network_delegate);
3052
3053 {
3054 GURL original_url(test_server_.GetURL("empty.html"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003055 scoped_ptr<URLRequest> r(context.CreateRequest(
3056 original_url, DEFAULT_PRIORITY, &d, NULL));
Ben Murdocheffb81e2014-03-31 11:51:25 +01003057
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003058 r->Start();
Ben Murdocheffb81e2014-03-31 11:51:25 +01003059 base::RunLoop().Run();
3060
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003061 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
3062 EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair()));
Ben Murdoch116680a2014-07-20 18:25:52 -07003063 EXPECT_EQ(
3064 2, network_delegate.observed_before_proxy_headers_sent_callbacks());
3065 EXPECT_TRUE(
3066 network_delegate.last_observed_proxy().Equals(
3067 test_server_.host_port_pair()));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003068
3069 EXPECT_EQ(OK, r->status().error());
3070 EXPECT_EQ(redirect_url, r->url());
3071 EXPECT_EQ(original_url, r->original_url());
3072 EXPECT_EQ(2U, r->url_chain().size());
Ben Murdocheffb81e2014-03-31 11:51:25 +01003073 EXPECT_EQ(2, network_delegate.created_requests());
3074 EXPECT_EQ(0, network_delegate.destroyed_requests());
3075 }
3076 EXPECT_EQ(1, network_delegate.destroyed_requests());
3077}
3078
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003079// Tests that the network delegate can synchronously complete OnAuthRequired
3080// by taking no action. This indicates that the NetworkDelegate does not want to
3081// handle the challenge, and is passing the buck along to the
3082// URLRequest::Delegate.
3083TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncNoAction) {
3084 ASSERT_TRUE(test_server_.Start());
3085
3086 TestDelegate d;
3087 BlockingNetworkDelegate network_delegate(
3088 BlockingNetworkDelegate::SYNCHRONOUS);
3089
3090 TestURLRequestContext context(true);
3091 context.set_network_delegate(&network_delegate);
3092 context.Init();
3093
3094 d.set_credentials(AuthCredentials(kUser, kSecret));
3095
3096 {
3097 GURL url(test_server_.GetURL("auth-basic"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003098 scoped_ptr<URLRequest> r(context.CreateRequest(
3099 url, DEFAULT_PRIORITY, &d, NULL));
3100 r->Start();
Ben Murdocheb525c52013-07-10 11:40:50 +01003101
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003102 base::RunLoop().Run();
Ben Murdocheb525c52013-07-10 11:40:50 +01003103
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003104 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
3105 EXPECT_EQ(0, r->status().error());
3106 EXPECT_EQ(200, r->GetResponseCode());
Ben Murdocheb525c52013-07-10 11:40:50 +01003107 EXPECT_TRUE(d.auth_required_called());
3108 EXPECT_EQ(1, network_delegate.created_requests());
3109 EXPECT_EQ(0, network_delegate.destroyed_requests());
3110 }
3111 EXPECT_EQ(1, network_delegate.destroyed_requests());
3112}
3113
3114TEST_F(URLRequestTestHTTP,
3115 NetworkDelegateOnAuthRequiredSyncNoAction_GetFullRequestHeaders) {
3116 ASSERT_TRUE(test_server_.Start());
3117
3118 TestDelegate d;
3119 BlockingNetworkDelegate network_delegate(
3120 BlockingNetworkDelegate::SYNCHRONOUS);
3121
3122 TestURLRequestContext context(true);
3123 context.set_network_delegate(&network_delegate);
3124 context.Init();
3125
3126 d.set_credentials(AuthCredentials(kUser, kSecret));
3127
3128 {
3129 GURL url(test_server_.GetURL("auth-basic"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003130 scoped_ptr<URLRequest> r(context.CreateRequest(
3131 url, DEFAULT_PRIORITY, &d, NULL));
3132 r->Start();
Ben Murdocheb525c52013-07-10 11:40:50 +01003133
3134 {
3135 HttpRequestHeaders headers;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003136 EXPECT_TRUE(r->GetFullRequestHeaders(&headers));
Ben Murdocheb525c52013-07-10 11:40:50 +01003137 EXPECT_FALSE(headers.HasHeader("Authorization"));
3138 }
3139
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003140 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003141
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003142 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
3143 EXPECT_EQ(0, r->status().error());
3144 EXPECT_EQ(200, r->GetResponseCode());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003145 EXPECT_TRUE(d.auth_required_called());
3146 EXPECT_EQ(1, network_delegate.created_requests());
3147 EXPECT_EQ(0, network_delegate.destroyed_requests());
3148 }
3149 EXPECT_EQ(1, network_delegate.destroyed_requests());
3150}
3151
3152// Tests that the network delegate can synchronously complete OnAuthRequired
3153// by setting credentials.
3154TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncSetAuth) {
3155 ASSERT_TRUE(test_server_.Start());
3156
3157 TestDelegate d;
3158 BlockingNetworkDelegate network_delegate(
3159 BlockingNetworkDelegate::SYNCHRONOUS);
3160 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);
3161 network_delegate.set_auth_retval(
3162 NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH);
3163
3164 network_delegate.set_auth_credentials(AuthCredentials(kUser, kSecret));
3165
3166 TestURLRequestContext context(true);
3167 context.set_network_delegate(&network_delegate);
3168 context.Init();
3169
3170 {
3171 GURL url(test_server_.GetURL("auth-basic"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003172 scoped_ptr<URLRequest> r(context.CreateRequest(
3173 url, DEFAULT_PRIORITY, &d, NULL));
3174 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003175 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003176
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003177 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
3178 EXPECT_EQ(0, r->status().error());
3179 EXPECT_EQ(200, r->GetResponseCode());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003180 EXPECT_FALSE(d.auth_required_called());
3181 EXPECT_EQ(1, network_delegate.created_requests());
3182 EXPECT_EQ(0, network_delegate.destroyed_requests());
3183 }
3184 EXPECT_EQ(1, network_delegate.destroyed_requests());
3185}
3186
Ben Murdocheb525c52013-07-10 11:40:50 +01003187// Same as above, but also tests that GetFullRequestHeaders returns the proper
3188// headers (for the first or second request) when called at the proper times.
3189TEST_F(URLRequestTestHTTP,
3190 NetworkDelegateOnAuthRequiredSyncSetAuth_GetFullRequestHeaders) {
3191 ASSERT_TRUE(test_server_.Start());
3192
3193 TestDelegate d;
3194 BlockingNetworkDelegate network_delegate(
3195 BlockingNetworkDelegate::SYNCHRONOUS);
3196 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);
3197 network_delegate.set_auth_retval(
3198 NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH);
3199
3200 network_delegate.set_auth_credentials(AuthCredentials(kUser, kSecret));
3201
3202 TestURLRequestContext context(true);
3203 context.set_network_delegate(&network_delegate);
3204 context.Init();
3205
3206 {
3207 GURL url(test_server_.GetURL("auth-basic"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003208 scoped_ptr<URLRequest> r(context.CreateRequest(
3209 url, DEFAULT_PRIORITY, &d, NULL));
3210 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003211 base::RunLoop().Run();
Ben Murdocheb525c52013-07-10 11:40:50 +01003212
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003213 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
3214 EXPECT_EQ(0, r->status().error());
3215 EXPECT_EQ(200, r->GetResponseCode());
Ben Murdocheb525c52013-07-10 11:40:50 +01003216 EXPECT_FALSE(d.auth_required_called());
3217 EXPECT_EQ(1, network_delegate.created_requests());
3218 EXPECT_EQ(0, network_delegate.destroyed_requests());
3219
3220 {
3221 HttpRequestHeaders headers;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003222 EXPECT_TRUE(r->GetFullRequestHeaders(&headers));
Ben Murdocheb525c52013-07-10 11:40:50 +01003223 EXPECT_TRUE(headers.HasHeader("Authorization"));
3224 }
3225 }
3226 EXPECT_EQ(1, network_delegate.destroyed_requests());
3227}
3228
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003229// Tests that the network delegate can synchronously complete OnAuthRequired
3230// by cancelling authentication.
3231TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncCancel) {
3232 ASSERT_TRUE(test_server_.Start());
3233
3234 TestDelegate d;
3235 BlockingNetworkDelegate network_delegate(
3236 BlockingNetworkDelegate::SYNCHRONOUS);
3237 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);
3238 network_delegate.set_auth_retval(
3239 NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH);
3240
3241 TestURLRequestContext context(true);
3242 context.set_network_delegate(&network_delegate);
3243 context.Init();
3244
3245 {
3246 GURL url(test_server_.GetURL("auth-basic"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003247 scoped_ptr<URLRequest> r(context.CreateRequest(
3248 url, DEFAULT_PRIORITY, &d, NULL));
3249 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003250 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003251
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003252 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
3253 EXPECT_EQ(OK, r->status().error());
3254 EXPECT_EQ(401, r->GetResponseCode());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003255 EXPECT_FALSE(d.auth_required_called());
3256 EXPECT_EQ(1, network_delegate.created_requests());
3257 EXPECT_EQ(0, network_delegate.destroyed_requests());
3258 }
3259 EXPECT_EQ(1, network_delegate.destroyed_requests());
3260}
3261
3262// Tests that the network delegate can asynchronously complete OnAuthRequired
3263// by taking no action. This indicates that the NetworkDelegate does not want
3264// to handle the challenge, and is passing the buck along to the
3265// URLRequest::Delegate.
3266TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncNoAction) {
3267 ASSERT_TRUE(test_server_.Start());
3268
3269 TestDelegate d;
3270 BlockingNetworkDelegate network_delegate(
3271 BlockingNetworkDelegate::AUTO_CALLBACK);
3272 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);
3273
3274 TestURLRequestContext context(true);
3275 context.set_network_delegate(&network_delegate);
3276 context.Init();
3277
3278 d.set_credentials(AuthCredentials(kUser, kSecret));
3279
3280 {
3281 GURL url(test_server_.GetURL("auth-basic"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003282 scoped_ptr<URLRequest> r(context.CreateRequest(
3283 url, DEFAULT_PRIORITY, &d, NULL));
3284 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003285 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003286
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003287 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
3288 EXPECT_EQ(0, r->status().error());
3289 EXPECT_EQ(200, r->GetResponseCode());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003290 EXPECT_TRUE(d.auth_required_called());
3291 EXPECT_EQ(1, network_delegate.created_requests());
3292 EXPECT_EQ(0, network_delegate.destroyed_requests());
3293 }
3294 EXPECT_EQ(1, network_delegate.destroyed_requests());
3295}
3296
3297// Tests that the network delegate can asynchronously complete OnAuthRequired
3298// by setting credentials.
3299TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncSetAuth) {
3300 ASSERT_TRUE(test_server_.Start());
3301
3302 TestDelegate d;
3303 BlockingNetworkDelegate network_delegate(
3304 BlockingNetworkDelegate::AUTO_CALLBACK);
3305 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);
3306 network_delegate.set_auth_retval(
3307 NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH);
3308
3309 AuthCredentials auth_credentials(kUser, kSecret);
3310 network_delegate.set_auth_credentials(auth_credentials);
3311
3312 TestURLRequestContext context(true);
3313 context.set_network_delegate(&network_delegate);
3314 context.Init();
3315
3316 {
3317 GURL url(test_server_.GetURL("auth-basic"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003318 scoped_ptr<URLRequest> r(context.CreateRequest(
3319 url, DEFAULT_PRIORITY, &d, NULL));
3320 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003321 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003322
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003323 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
3324 EXPECT_EQ(0, r->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003325
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003326 EXPECT_EQ(200, r->GetResponseCode());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003327 EXPECT_FALSE(d.auth_required_called());
3328 EXPECT_EQ(1, network_delegate.created_requests());
3329 EXPECT_EQ(0, network_delegate.destroyed_requests());
3330 }
3331 EXPECT_EQ(1, network_delegate.destroyed_requests());
3332}
3333
3334// Tests that the network delegate can asynchronously complete OnAuthRequired
3335// by cancelling authentication.
3336TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncCancel) {
3337 ASSERT_TRUE(test_server_.Start());
3338
3339 TestDelegate d;
3340 BlockingNetworkDelegate network_delegate(
3341 BlockingNetworkDelegate::AUTO_CALLBACK);
3342 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);
3343 network_delegate.set_auth_retval(
3344 NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH);
3345
3346 TestURLRequestContext context(true);
3347 context.set_network_delegate(&network_delegate);
3348 context.Init();
3349
3350 {
3351 GURL url(test_server_.GetURL("auth-basic"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003352 scoped_ptr<URLRequest> r(context.CreateRequest(
3353 url, DEFAULT_PRIORITY, &d, NULL));
3354 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003355 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003356
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003357 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
3358 EXPECT_EQ(OK, r->status().error());
3359 EXPECT_EQ(401, r->GetResponseCode());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003360 EXPECT_FALSE(d.auth_required_called());
3361 EXPECT_EQ(1, network_delegate.created_requests());
3362 EXPECT_EQ(0, network_delegate.destroyed_requests());
3363 }
3364 EXPECT_EQ(1, network_delegate.destroyed_requests());
3365}
3366
3367// Tests that we can handle when a network request was canceled while we were
3368// waiting for the network delegate.
3369// Part 1: Request is cancelled while waiting for OnBeforeURLRequest callback.
3370TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting1) {
3371 ASSERT_TRUE(test_server_.Start());
3372
3373 TestDelegate d;
3374 BlockingNetworkDelegate network_delegate(
3375 BlockingNetworkDelegate::USER_CALLBACK);
3376 network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST);
3377
3378 TestURLRequestContext context(true);
3379 context.set_network_delegate(&network_delegate);
3380 context.Init();
3381
3382 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003383 scoped_ptr<URLRequest> r(context.CreateRequest(
3384 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003385
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003386 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003387 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003388 EXPECT_EQ(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST,
3389 network_delegate.stage_blocked_for_callback());
3390 EXPECT_EQ(0, network_delegate.completed_requests());
3391 // Cancel before callback.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003392 r->Cancel();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003393 // Ensure that network delegate is notified.
3394 EXPECT_EQ(1, network_delegate.completed_requests());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003395 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
3396 EXPECT_EQ(ERR_ABORTED, r->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003397 EXPECT_EQ(1, network_delegate.created_requests());
3398 EXPECT_EQ(0, network_delegate.destroyed_requests());
3399 }
3400 EXPECT_EQ(1, network_delegate.destroyed_requests());
3401}
3402
3403// Tests that we can handle when a network request was canceled while we were
3404// waiting for the network delegate.
3405// Part 2: Request is cancelled while waiting for OnBeforeSendHeaders callback.
3406TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting2) {
3407 ASSERT_TRUE(test_server_.Start());
3408
3409 TestDelegate d;
3410 BlockingNetworkDelegate network_delegate(
3411 BlockingNetworkDelegate::USER_CALLBACK);
3412 network_delegate.set_block_on(
3413 BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS);
3414
3415 TestURLRequestContext context(true);
3416 context.set_network_delegate(&network_delegate);
3417 context.Init();
3418
3419 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003420 scoped_ptr<URLRequest> r(context.CreateRequest(
3421 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003422
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003423 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003424 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003425 EXPECT_EQ(BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS,
3426 network_delegate.stage_blocked_for_callback());
3427 EXPECT_EQ(0, network_delegate.completed_requests());
3428 // Cancel before callback.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003429 r->Cancel();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003430 // Ensure that network delegate is notified.
3431 EXPECT_EQ(1, network_delegate.completed_requests());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003432 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
3433 EXPECT_EQ(ERR_ABORTED, r->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003434 EXPECT_EQ(1, network_delegate.created_requests());
3435 EXPECT_EQ(0, network_delegate.destroyed_requests());
3436 }
3437 EXPECT_EQ(1, network_delegate.destroyed_requests());
3438}
3439
3440// Tests that we can handle when a network request was canceled while we were
3441// waiting for the network delegate.
3442// Part 3: Request is cancelled while waiting for OnHeadersReceived callback.
3443TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting3) {
3444 ASSERT_TRUE(test_server_.Start());
3445
3446 TestDelegate d;
3447 BlockingNetworkDelegate network_delegate(
3448 BlockingNetworkDelegate::USER_CALLBACK);
3449 network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED);
3450
3451 TestURLRequestContext context(true);
3452 context.set_network_delegate(&network_delegate);
3453 context.Init();
3454
3455 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003456 scoped_ptr<URLRequest> r(context.CreateRequest(
3457 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003458
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003459 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003460 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003461 EXPECT_EQ(BlockingNetworkDelegate::ON_HEADERS_RECEIVED,
3462 network_delegate.stage_blocked_for_callback());
3463 EXPECT_EQ(0, network_delegate.completed_requests());
3464 // Cancel before callback.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003465 r->Cancel();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003466 // Ensure that network delegate is notified.
3467 EXPECT_EQ(1, network_delegate.completed_requests());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003468 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
3469 EXPECT_EQ(ERR_ABORTED, r->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003470 EXPECT_EQ(1, network_delegate.created_requests());
3471 EXPECT_EQ(0, network_delegate.destroyed_requests());
3472 }
3473 EXPECT_EQ(1, network_delegate.destroyed_requests());
3474}
3475
3476// Tests that we can handle when a network request was canceled while we were
3477// waiting for the network delegate.
3478// Part 4: Request is cancelled while waiting for OnAuthRequired callback.
3479TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting4) {
3480 ASSERT_TRUE(test_server_.Start());
3481
3482 TestDelegate d;
3483 BlockingNetworkDelegate network_delegate(
3484 BlockingNetworkDelegate::USER_CALLBACK);
3485 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);
3486
3487 TestURLRequestContext context(true);
3488 context.set_network_delegate(&network_delegate);
3489 context.Init();
3490
3491 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003492 scoped_ptr<URLRequest> r(context.CreateRequest(
3493 test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003494
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003495 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003496 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003497 EXPECT_EQ(BlockingNetworkDelegate::ON_AUTH_REQUIRED,
3498 network_delegate.stage_blocked_for_callback());
3499 EXPECT_EQ(0, network_delegate.completed_requests());
3500 // Cancel before callback.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003501 r->Cancel();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003502 // Ensure that network delegate is notified.
3503 EXPECT_EQ(1, network_delegate.completed_requests());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003504 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
3505 EXPECT_EQ(ERR_ABORTED, r->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003506 EXPECT_EQ(1, network_delegate.created_requests());
3507 EXPECT_EQ(0, network_delegate.destroyed_requests());
3508 }
3509 EXPECT_EQ(1, network_delegate.destroyed_requests());
3510}
3511
3512// In this unit test, we're using the HTTPTestServer as a proxy server and
3513// issuing a CONNECT request with the magic host name "www.server-auth.com".
3514// The HTTPTestServer will return a 401 response, which we should balk at.
3515TEST_F(URLRequestTestHTTP, UnexpectedServerAuthTest) {
3516 ASSERT_TRUE(test_server_.Start());
3517
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003518 TestNetworkDelegate network_delegate; // Must outlive URLRequest.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003519 TestURLRequestContextWithProxy context(
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00003520 test_server_.host_port_pair().ToString(), &network_delegate);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003521
3522 TestDelegate d;
3523 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003524 scoped_ptr<URLRequest> r(context.CreateRequest(
3525 GURL("https://www.server-auth.com/"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003526
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003527 r->Start();
3528 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003529
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003530 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003531
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003532 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
Torne (Richard Coles)f8ee7882014-06-20 14:52:04 +01003533 // The proxy server is not set before failure.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003534 EXPECT_TRUE(r->proxy_server().IsEmpty());
3535 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003536 }
3537}
3538
3539TEST_F(URLRequestTestHTTP, GetTest_NoCache) {
3540 ASSERT_TRUE(test_server_.Start());
3541
3542 TestDelegate d;
3543 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003544 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
3545 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003546
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003547 r->Start();
3548 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003549
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003550 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003551
3552 EXPECT_EQ(1, d.response_started_count());
3553 EXPECT_FALSE(d.received_data_before_response());
3554 EXPECT_NE(0, d.bytes_received());
3555 EXPECT_EQ(test_server_.host_port_pair().host(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003556 r->GetSocketAddress().host());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003557 EXPECT_EQ(test_server_.host_port_pair().port(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003558 r->GetSocketAddress().port());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003559
3560 // TODO(eroman): Add back the NetLog tests...
3561 }
3562}
3563
3564// This test has the server send a large number of cookies to the client.
3565// To ensure that no number of cookies causes a crash, a galloping binary
3566// search is used to estimate that maximum number of cookies that are accepted
3567// by the browser. Beyond the maximum number, the request will fail with
3568// ERR_RESPONSE_HEADERS_TOO_BIG.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003569#if defined(OS_WIN)
3570// http://crbug.com/177916
3571#define MAYBE_GetTest_ManyCookies DISABLED_GetTest_ManyCookies
3572#else
3573#define MAYBE_GetTest_ManyCookies GetTest_ManyCookies
3574#endif // defined(OS_WIN)
3575TEST_F(URLRequestTestHTTP, MAYBE_GetTest_ManyCookies) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003576 ASSERT_TRUE(test_server_.Start());
3577
3578 int lower_bound = 0;
3579 int upper_bound = 1;
3580
3581 // Double the number of cookies until the response header limits are
3582 // exceeded.
3583 while (DoManyCookiesRequest(upper_bound)) {
3584 lower_bound = upper_bound;
3585 upper_bound *= 2;
3586 ASSERT_LT(upper_bound, 1000000);
3587 }
3588
3589 int tolerance = upper_bound * 0.005;
3590 if (tolerance < 2)
3591 tolerance = 2;
3592
3593 // Perform a binary search to find the highest possible number of cookies,
3594 // within the desired tolerance.
3595 while (upper_bound - lower_bound >= tolerance) {
3596 int num_cookies = (lower_bound + upper_bound) / 2;
3597
3598 if (DoManyCookiesRequest(num_cookies))
3599 lower_bound = num_cookies;
3600 else
3601 upper_bound = num_cookies;
3602 }
3603 // Success: the test did not crash.
3604}
3605
3606TEST_F(URLRequestTestHTTP, GetTest) {
3607 ASSERT_TRUE(test_server_.Start());
3608
3609 TestDelegate d;
3610 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003611 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
3612 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003613
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003614 r->Start();
3615 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003616
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003617 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003618
3619 EXPECT_EQ(1, d.response_started_count());
3620 EXPECT_FALSE(d.received_data_before_response());
3621 EXPECT_NE(0, d.bytes_received());
3622 EXPECT_EQ(test_server_.host_port_pair().host(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003623 r->GetSocketAddress().host());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003624 EXPECT_EQ(test_server_.host_port_pair().port(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003625 r->GetSocketAddress().port());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003626 }
3627}
3628
Ben Murdocheb525c52013-07-10 11:40:50 +01003629TEST_F(URLRequestTestHTTP, GetTest_GetFullRequestHeaders) {
3630 ASSERT_TRUE(test_server_.Start());
3631
3632 TestDelegate d;
3633 {
3634 GURL test_url(test_server_.GetURL(std::string()));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003635 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
3636 test_url, DEFAULT_PRIORITY, &d, NULL));
Ben Murdocheb525c52013-07-10 11:40:50 +01003637
3638 HttpRequestHeaders headers;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003639 EXPECT_FALSE(r->GetFullRequestHeaders(&headers));
Ben Murdocheb525c52013-07-10 11:40:50 +01003640
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003641 r->Start();
3642 EXPECT_TRUE(r->is_pending());
Ben Murdocheb525c52013-07-10 11:40:50 +01003643
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003644 base::RunLoop().Run();
Ben Murdocheb525c52013-07-10 11:40:50 +01003645
3646 EXPECT_EQ(1, d.response_started_count());
3647 EXPECT_FALSE(d.received_data_before_response());
3648 EXPECT_NE(0, d.bytes_received());
3649 EXPECT_EQ(test_server_.host_port_pair().host(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003650 r->GetSocketAddress().host());
Ben Murdocheb525c52013-07-10 11:40:50 +01003651 EXPECT_EQ(test_server_.host_port_pair().port(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003652 r->GetSocketAddress().port());
Ben Murdocheb525c52013-07-10 11:40:50 +01003653
3654 EXPECT_TRUE(d.have_full_request_headers());
3655 CheckFullRequestHeaders(d.full_request_headers(), test_url);
3656 }
3657}
3658
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003659TEST_F(URLRequestTestHTTP, GetTestLoadTiming) {
3660 ASSERT_TRUE(test_server_.Start());
3661
3662 TestDelegate d;
3663 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003664 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
3665 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003666
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003667 r->Start();
3668 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003669
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003670 base::RunLoop().Run();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003671
3672 LoadTimingInfo load_timing_info;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003673 r->GetLoadTimingInfo(&load_timing_info);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003674 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
3675
3676 EXPECT_EQ(1, d.response_started_count());
3677 EXPECT_FALSE(d.received_data_before_response());
3678 EXPECT_NE(0, d.bytes_received());
3679 EXPECT_EQ(test_server_.host_port_pair().host(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003680 r->GetSocketAddress().host());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003681 EXPECT_EQ(test_server_.host_port_pair().port(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003682 r->GetSocketAddress().port());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003683 }
3684}
3685
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003686TEST_F(URLRequestTestHTTP, GetZippedTest) {
3687 ASSERT_TRUE(test_server_.Start());
3688
3689 // Parameter that specifies the Content-Length field in the response:
3690 // C - Compressed length.
3691 // U - Uncompressed length.
3692 // L - Large length (larger than both C & U).
3693 // M - Medium length (between C & U).
3694 // S - Small length (smaller than both C & U).
3695 const char test_parameters[] = "CULMS";
3696 const int num_tests = arraysize(test_parameters)- 1; // Skip NULL.
3697 // C & U should be OK.
3698 // L & M are larger than the data sent, and show an error.
3699 // S has too little data, but we seem to accept it.
3700 const bool test_expect_success[num_tests] =
3701 { true, true, false, false, true };
3702
3703 for (int i = 0; i < num_tests ; i++) {
3704 TestDelegate d;
3705 {
3706 std::string test_file =
3707 base::StringPrintf("compressedfiles/BullRunSpeech.txt?%c",
3708 test_parameters[i]);
3709
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003710 TestNetworkDelegate network_delegate; // Must outlive URLRequest.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003711 TestURLRequestContext context(true);
3712 context.set_network_delegate(&network_delegate);
3713 context.Init();
3714
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003715 scoped_ptr<URLRequest> r(context.CreateRequest(
3716 test_server_.GetURL(test_file), DEFAULT_PRIORITY, &d, NULL));
3717 r->Start();
3718 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003719
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003720 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003721
3722 EXPECT_EQ(1, d.response_started_count());
3723 EXPECT_FALSE(d.received_data_before_response());
3724 VLOG(1) << " Received " << d.bytes_received() << " bytes"
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003725 << " status = " << r->status().status()
3726 << " error = " << r->status().error();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003727 if (test_expect_success[i]) {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003728 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status())
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003729 << " Parameter = \"" << test_file << "\"";
3730 } else {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003731 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
3732 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, r->status().error())
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003733 << " Parameter = \"" << test_file << "\"";
3734 }
3735 }
3736 }
3737}
3738
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003739TEST_F(URLRequestTestHTTP, HTTPSToHTTPRedirectNoRefererTest) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003740 ASSERT_TRUE(test_server_.Start());
3741
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01003742 SpawnedTestServer https_test_server(
3743 SpawnedTestServer::TYPE_HTTPS, SpawnedTestServer::kLocalhost,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003744 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003745 ASSERT_TRUE(https_test_server.Start());
3746
3747 // An https server is sent a request with an https referer,
3748 // and responds with a redirect to an http url. The http
3749 // server should not be sent the referer.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01003750 GURL http_destination = test_server_.GetURL(std::string());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003751 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003752 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00003753 https_test_server.GetURL("server-redirect?" + http_destination.spec()),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003754 DEFAULT_PRIORITY, &d, NULL));
3755 req->SetReferrer("https://www.referrer.com/");
3756 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003757 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003758
3759 EXPECT_EQ(1, d.response_started_count());
3760 EXPECT_EQ(1, d.received_redirect_count());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003761 EXPECT_EQ(http_destination, req->url());
3762 EXPECT_EQ(std::string(), req->referrer());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003763}
3764
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003765TEST_F(URLRequestTestHTTP, RedirectLoadTiming) {
3766 ASSERT_TRUE(test_server_.Start());
3767
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01003768 GURL destination_url = test_server_.GetURL(std::string());
3769 GURL original_url =
3770 test_server_.GetURL("server-redirect?" + destination_url.spec());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003771 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003772 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
3773 original_url, DEFAULT_PRIORITY, &d, NULL));
3774 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003775 base::RunLoop().Run();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003776
3777 EXPECT_EQ(1, d.response_started_count());
3778 EXPECT_EQ(1, d.received_redirect_count());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003779 EXPECT_EQ(destination_url, req->url());
3780 EXPECT_EQ(original_url, req->original_url());
3781 ASSERT_EQ(2U, req->url_chain().size());
3782 EXPECT_EQ(original_url, req->url_chain()[0]);
3783 EXPECT_EQ(destination_url, req->url_chain()[1]);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003784
3785 LoadTimingInfo load_timing_info_before_redirect;
3786 EXPECT_TRUE(default_network_delegate_.GetLoadTimingInfoBeforeRedirect(
3787 &load_timing_info_before_redirect));
3788 TestLoadTimingNotReused(load_timing_info_before_redirect,
3789 CONNECT_TIMING_HAS_DNS_TIMES);
3790
3791 LoadTimingInfo load_timing_info;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003792 req->GetLoadTimingInfo(&load_timing_info);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00003793 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
3794
3795 // Check that a new socket was used on redirect, since the server does not
3796 // supposed keep-alive sockets, and that the times before the redirect are
3797 // before the ones recorded for the second request.
3798 EXPECT_NE(load_timing_info_before_redirect.socket_log_id,
3799 load_timing_info.socket_log_id);
3800 EXPECT_LE(load_timing_info_before_redirect.receive_headers_end,
3801 load_timing_info.connect_timing.connect_start);
3802}
3803
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003804TEST_F(URLRequestTestHTTP, MultipleRedirectTest) {
3805 ASSERT_TRUE(test_server_.Start());
3806
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01003807 GURL destination_url = test_server_.GetURL(std::string());
3808 GURL middle_redirect_url =
3809 test_server_.GetURL("server-redirect?" + destination_url.spec());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003810 GURL original_url = test_server_.GetURL(
3811 "server-redirect?" + middle_redirect_url.spec());
3812 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003813 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
3814 original_url, DEFAULT_PRIORITY, &d, NULL));
3815 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01003816 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003817
3818 EXPECT_EQ(1, d.response_started_count());
3819 EXPECT_EQ(2, d.received_redirect_count());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01003820 EXPECT_EQ(destination_url, req->url());
3821 EXPECT_EQ(original_url, req->original_url());
3822 ASSERT_EQ(3U, req->url_chain().size());
3823 EXPECT_EQ(original_url, req->url_chain()[0]);
3824 EXPECT_EQ(middle_redirect_url, req->url_chain()[1]);
3825 EXPECT_EQ(destination_url, req->url_chain()[2]);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00003826}
3827
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00003828// First and second pieces of information logged by delegates to URLRequests.
3829const char kFirstDelegateInfo[] = "Wonderful delegate";
3830const char kSecondDelegateInfo[] = "Exciting delegate";
3831
3832// Logs delegate information to a URLRequest. The first string is logged
3833// synchronously on Start(), using DELEGATE_INFO_DEBUG_ONLY. The second is
3834// logged asynchronously, using DELEGATE_INFO_DISPLAY_TO_USER. Then
3835// another asynchronous call is used to clear the delegate information
3836// before calling a callback. The object then deletes itself.
3837class AsyncDelegateLogger : public base::RefCounted<AsyncDelegateLogger> {
3838 public:
3839 typedef base::Callback<void()> Callback;
3840
3841 // Each time delegate information is added to the URLRequest, the resulting
3842 // load state is checked. The expected load state after each request is
3843 // passed in as an argument.
3844 static void Run(URLRequest* url_request,
3845 LoadState expected_first_load_state,
3846 LoadState expected_second_load_state,
3847 LoadState expected_third_load_state,
3848 const Callback& callback) {
3849 AsyncDelegateLogger* logger = new AsyncDelegateLogger(
3850 url_request,
3851 expected_first_load_state,
3852 expected_second_load_state,
3853 expected_third_load_state,
3854 callback);
3855 logger->Start();
3856 }
3857
3858 // Checks that the log entries, starting with log_position, contain the
3859 // DELEGATE_INFO NetLog events that an AsyncDelegateLogger should have
3860 // recorded. Returns the index of entry after the expected number of
3861 // events this logged, or entries.size() if there aren't enough entries.
3862 static size_t CheckDelegateInfo(
3863 const CapturingNetLog::CapturedEntryList& entries, size_t log_position) {
3864 // There should be 4 DELEGATE_INFO events: Two begins and two ends.
3865 if (log_position + 3 >= entries.size()) {
3866 ADD_FAILURE() << "Not enough log entries";
3867 return entries.size();
3868 }
3869 std::string delegate_info;
3870 EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type);
3871 EXPECT_EQ(NetLog::PHASE_BEGIN, entries[log_position].phase);
3872 EXPECT_TRUE(entries[log_position].GetStringValue("delegate_info",
3873 &delegate_info));
3874 EXPECT_EQ(kFirstDelegateInfo, delegate_info);
3875
3876 ++log_position;
3877 EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type);
3878 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);
3879
3880 ++log_position;
3881 EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type);
3882 EXPECT_EQ(NetLog::PHASE_BEGIN, entries[log_position].phase);
3883 EXPECT_TRUE(entries[log_position].GetStringValue("delegate_info",
3884 &delegate_info));
3885 EXPECT_EQ(kSecondDelegateInfo, delegate_info);
3886
3887 ++log_position;
3888 EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type);
3889 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);
3890
3891 return log_position + 1;
3892 }
3893
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00003894 // Find delegate request begin and end messages for OnBeforeNetworkStart.
3895 // Returns the position of the end message.
3896 static size_t ExpectBeforeNetworkEvents(
3897 const CapturingNetLog::CapturedEntryList& entries,
3898 size_t log_position) {
3899 log_position =
3900 ExpectLogContainsSomewhereAfter(entries,
3901 log_position,
3902 NetLog::TYPE_URL_REQUEST_DELEGATE,
3903 NetLog::PHASE_BEGIN);
3904 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE,
3905 entries[log_position + 1].type);
3906 EXPECT_EQ(NetLog::PHASE_END, entries[log_position + 1].phase);
3907 return log_position + 1;
3908 }
3909
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00003910 private:
3911 friend class base::RefCounted<AsyncDelegateLogger>;
3912
3913 AsyncDelegateLogger(URLRequest* url_request,
3914 LoadState expected_first_load_state,
3915 LoadState expected_second_load_state,
3916 LoadState expected_third_load_state,
3917 const Callback& callback)
3918 : url_request_(url_request),
3919 expected_first_load_state_(expected_first_load_state),
3920 expected_second_load_state_(expected_second_load_state),
3921 expected_third_load_state_(expected_third_load_state),
3922 callback_(callback) {
3923 }
3924
3925 ~AsyncDelegateLogger() {}
3926
3927 void Start() {
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00003928 url_request_->LogBlockedBy(kFirstDelegateInfo);
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00003929 LoadStateWithParam load_state = url_request_->GetLoadState();
3930 EXPECT_EQ(expected_first_load_state_, load_state.state);
3931 EXPECT_NE(ASCIIToUTF16(kFirstDelegateInfo), load_state.param);
3932 base::MessageLoop::current()->PostTask(
3933 FROM_HERE,
3934 base::Bind(&AsyncDelegateLogger::LogSecondDelegate, this));
3935 }
3936
3937 void LogSecondDelegate() {
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00003938 url_request_->LogAndReportBlockedBy(kSecondDelegateInfo);
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00003939 LoadStateWithParam load_state = url_request_->GetLoadState();
3940 EXPECT_EQ(expected_second_load_state_, load_state.state);
3941 if (expected_second_load_state_ == LOAD_STATE_WAITING_FOR_DELEGATE) {
3942 EXPECT_EQ(ASCIIToUTF16(kSecondDelegateInfo), load_state.param);
3943 } else {
3944 EXPECT_NE(ASCIIToUTF16(kSecondDelegateInfo), load_state.param);
3945 }
3946 base::MessageLoop::current()->PostTask(
3947 FROM_HERE,
3948 base::Bind(&AsyncDelegateLogger::LogComplete, this));
3949 }
3950
3951 void LogComplete() {
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00003952 url_request_->LogUnblocked();
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00003953 LoadStateWithParam load_state = url_request_->GetLoadState();
3954 EXPECT_EQ(expected_third_load_state_, load_state.state);
3955 if (expected_second_load_state_ == LOAD_STATE_WAITING_FOR_DELEGATE)
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00003956 EXPECT_EQ(base::string16(), load_state.param);
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00003957 callback_.Run();
3958 }
3959
3960 URLRequest* url_request_;
3961 const int expected_first_load_state_;
3962 const int expected_second_load_state_;
3963 const int expected_third_load_state_;
3964 const Callback callback_;
3965
3966 DISALLOW_COPY_AND_ASSIGN(AsyncDelegateLogger);
3967};
3968
3969// NetworkDelegate that logs delegate information before a request is started,
3970// before headers are sent, when headers are read, and when auth information
3971// is requested. Uses AsyncDelegateLogger.
3972class AsyncLoggingNetworkDelegate : public TestNetworkDelegate {
3973 public:
3974 AsyncLoggingNetworkDelegate() {}
3975 virtual ~AsyncLoggingNetworkDelegate() {}
3976
3977 // NetworkDelegate implementation.
3978 virtual int OnBeforeURLRequest(URLRequest* request,
3979 const CompletionCallback& callback,
3980 GURL* new_url) OVERRIDE {
3981 TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url);
3982 return RunCallbackAsynchronously(request, callback);
3983 }
3984
3985 virtual int OnBeforeSendHeaders(URLRequest* request,
3986 const CompletionCallback& callback,
3987 HttpRequestHeaders* headers) OVERRIDE {
3988 TestNetworkDelegate::OnBeforeSendHeaders(request, callback, headers);
3989 return RunCallbackAsynchronously(request, callback);
3990 }
3991
3992 virtual int OnHeadersReceived(
3993 URLRequest* request,
3994 const CompletionCallback& callback,
3995 const HttpResponseHeaders* original_response_headers,
Ben Murdocheffb81e2014-03-31 11:51:25 +01003996 scoped_refptr<HttpResponseHeaders>* override_response_headers,
3997 GURL* allowed_unsafe_redirect_url) OVERRIDE {
3998 TestNetworkDelegate::OnHeadersReceived(request,
3999 callback,
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004000 original_response_headers,
Ben Murdocheffb81e2014-03-31 11:51:25 +01004001 override_response_headers,
4002 allowed_unsafe_redirect_url);
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004003 return RunCallbackAsynchronously(request, callback);
4004 }
4005
4006 virtual NetworkDelegate::AuthRequiredResponse OnAuthRequired(
4007 URLRequest* request,
4008 const AuthChallengeInfo& auth_info,
4009 const AuthCallback& callback,
4010 AuthCredentials* credentials) OVERRIDE {
4011 AsyncDelegateLogger::Run(
4012 request,
4013 LOAD_STATE_WAITING_FOR_DELEGATE,
4014 LOAD_STATE_WAITING_FOR_DELEGATE,
4015 LOAD_STATE_WAITING_FOR_DELEGATE,
4016 base::Bind(&AsyncLoggingNetworkDelegate::SetAuthAndResume,
4017 callback, credentials));
4018 return AUTH_REQUIRED_RESPONSE_IO_PENDING;
4019 }
4020
4021 private:
4022 static int RunCallbackAsynchronously(
4023 URLRequest* request,
4024 const CompletionCallback& callback) {
4025 AsyncDelegateLogger::Run(
4026 request,
4027 LOAD_STATE_WAITING_FOR_DELEGATE,
4028 LOAD_STATE_WAITING_FOR_DELEGATE,
4029 LOAD_STATE_WAITING_FOR_DELEGATE,
4030 base::Bind(callback, OK));
4031 return ERR_IO_PENDING;
4032 }
4033
4034 static void SetAuthAndResume(const AuthCallback& callback,
4035 AuthCredentials* credentials) {
4036 *credentials = AuthCredentials(kUser, kSecret);
4037 callback.Run(NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH);
4038 }
4039
4040 DISALLOW_COPY_AND_ASSIGN(AsyncLoggingNetworkDelegate);
4041};
4042
4043// URLRequest::Delegate that logs delegate information when the headers
4044// are received, when each read completes, and during redirects. Uses
4045// AsyncDelegateLogger. Can optionally cancel a request in any phase.
4046//
4047// Inherits from TestDelegate to reuse the TestDelegate code to handle
4048// advancing to the next step in most cases, as well as cancellation.
4049class AsyncLoggingUrlRequestDelegate : public TestDelegate {
4050 public:
4051 enum CancelStage {
4052 NO_CANCEL = 0,
4053 CANCEL_ON_RECEIVED_REDIRECT,
4054 CANCEL_ON_RESPONSE_STARTED,
4055 CANCEL_ON_READ_COMPLETED
4056 };
4057
4058 explicit AsyncLoggingUrlRequestDelegate(CancelStage cancel_stage)
4059 : cancel_stage_(cancel_stage) {
4060 if (cancel_stage == CANCEL_ON_RECEIVED_REDIRECT)
4061 set_cancel_in_received_redirect(true);
4062 else if (cancel_stage == CANCEL_ON_RESPONSE_STARTED)
4063 set_cancel_in_response_started(true);
4064 else if (cancel_stage == CANCEL_ON_READ_COMPLETED)
4065 set_cancel_in_received_data(true);
4066 }
4067 virtual ~AsyncLoggingUrlRequestDelegate() {}
4068
4069 // URLRequest::Delegate implementation:
4070 void virtual OnReceivedRedirect(URLRequest* request,
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01004071 const RedirectInfo& redirect_info,
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004072 bool* defer_redirect) OVERRIDE {
4073 *defer_redirect = true;
4074 AsyncDelegateLogger::Run(
4075 request,
4076 LOAD_STATE_WAITING_FOR_DELEGATE,
4077 LOAD_STATE_WAITING_FOR_DELEGATE,
4078 LOAD_STATE_WAITING_FOR_DELEGATE,
4079 base::Bind(
4080 &AsyncLoggingUrlRequestDelegate::OnReceivedRedirectLoggingComplete,
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01004081 base::Unretained(this), request, redirect_info));
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004082 }
4083
4084 virtual void OnResponseStarted(URLRequest* request) OVERRIDE {
4085 AsyncDelegateLogger::Run(
4086 request,
4087 LOAD_STATE_WAITING_FOR_DELEGATE,
4088 LOAD_STATE_WAITING_FOR_DELEGATE,
4089 LOAD_STATE_WAITING_FOR_DELEGATE,
4090 base::Bind(
4091 &AsyncLoggingUrlRequestDelegate::OnResponseStartedLoggingComplete,
4092 base::Unretained(this), request));
4093 }
4094
4095 virtual void OnReadCompleted(URLRequest* request,
4096 int bytes_read) OVERRIDE {
4097 AsyncDelegateLogger::Run(
4098 request,
4099 LOAD_STATE_IDLE,
4100 LOAD_STATE_IDLE,
4101 LOAD_STATE_IDLE,
4102 base::Bind(
4103 &AsyncLoggingUrlRequestDelegate::AfterReadCompletedLoggingComplete,
4104 base::Unretained(this), request, bytes_read));
4105 }
4106
4107 private:
4108 void OnReceivedRedirectLoggingComplete(URLRequest* request,
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01004109 const RedirectInfo& redirect_info) {
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004110 bool defer_redirect = false;
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01004111 TestDelegate::OnReceivedRedirect(request, redirect_info, &defer_redirect);
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004112 // FollowDeferredRedirect should not be called after cancellation.
4113 if (cancel_stage_ == CANCEL_ON_RECEIVED_REDIRECT)
4114 return;
4115 if (!defer_redirect)
4116 request->FollowDeferredRedirect();
4117 }
4118
4119 void OnResponseStartedLoggingComplete(URLRequest* request) {
4120 // The parent class continues the request.
4121 TestDelegate::OnResponseStarted(request);
4122 }
4123
4124 void AfterReadCompletedLoggingComplete(URLRequest* request, int bytes_read) {
4125 // The parent class continues the request.
4126 TestDelegate::OnReadCompleted(request, bytes_read);
4127 }
4128
4129 const CancelStage cancel_stage_;
4130
4131 DISALLOW_COPY_AND_ASSIGN(AsyncLoggingUrlRequestDelegate);
4132};
4133
4134// Tests handling of delegate info before a request starts.
4135TEST_F(URLRequestTestHTTP, DelegateInfoBeforeStart) {
4136 ASSERT_TRUE(test_server_.Start());
4137
4138 TestDelegate request_delegate;
4139 TestURLRequestContext context(true);
4140 context.set_network_delegate(NULL);
4141 context.set_net_log(&net_log_);
4142 context.Init();
4143
4144 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004145 scoped_ptr<URLRequest> r(context.CreateRequest(
4146 test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &request_delegate,
4147 NULL));
4148 LoadStateWithParam load_state = r->GetLoadState();
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004149 EXPECT_EQ(LOAD_STATE_IDLE, load_state.state);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00004150 EXPECT_EQ(base::string16(), load_state.param);
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004151
4152 AsyncDelegateLogger::Run(
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004153 r.get(),
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004154 LOAD_STATE_WAITING_FOR_DELEGATE,
4155 LOAD_STATE_WAITING_FOR_DELEGATE,
4156 LOAD_STATE_IDLE,
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004157 base::Bind(&URLRequest::Start, base::Unretained(r.get())));
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004158
4159 base::RunLoop().Run();
4160
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004161 EXPECT_EQ(200, r->GetResponseCode());
4162 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004163 }
4164
4165 CapturingNetLog::CapturedEntryList entries;
4166 net_log_.GetEntries(&entries);
4167 size_t log_position = ExpectLogContainsSomewhereAfter(
4168 entries,
4169 0,
4170 NetLog::TYPE_DELEGATE_INFO,
4171 NetLog::PHASE_BEGIN);
4172
4173 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, log_position);
4174
4175 // Nothing else should add any delegate info to the request.
4176 EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4177 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
4178}
4179
4180// Tests handling of delegate info from a network delegate.
4181TEST_F(URLRequestTestHTTP, NetworkDelegateInfo) {
4182 ASSERT_TRUE(test_server_.Start());
4183
4184 TestDelegate request_delegate;
4185 AsyncLoggingNetworkDelegate network_delegate;
4186 TestURLRequestContext context(true);
4187 context.set_network_delegate(&network_delegate);
4188 context.set_net_log(&net_log_);
4189 context.Init();
4190
4191 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004192 scoped_ptr<URLRequest> r(context.CreateRequest(
4193 test_server_.GetURL("simple.html"), DEFAULT_PRIORITY, &request_delegate,
4194 NULL));
4195 LoadStateWithParam load_state = r->GetLoadState();
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004196 EXPECT_EQ(LOAD_STATE_IDLE, load_state.state);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00004197 EXPECT_EQ(base::string16(), load_state.param);
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004198
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004199 r->Start();
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004200 base::RunLoop().Run();
4201
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004202 EXPECT_EQ(200, r->GetResponseCode());
4203 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004204 EXPECT_EQ(1, network_delegate.created_requests());
4205 EXPECT_EQ(0, network_delegate.destroyed_requests());
4206 }
4207 EXPECT_EQ(1, network_delegate.destroyed_requests());
4208
4209 size_t log_position = 0;
4210 CapturingNetLog::CapturedEntryList entries;
4211 net_log_.GetEntries(&entries);
4212 for (size_t i = 0; i < 3; ++i) {
4213 log_position = ExpectLogContainsSomewhereAfter(
4214 entries,
4215 log_position + 1,
4216 NetLog::TYPE_URL_REQUEST_DELEGATE,
4217 NetLog::PHASE_BEGIN);
4218
4219 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
4220 log_position + 1);
4221
4222 ASSERT_LT(log_position, entries.size());
4223 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
4224 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00004225
4226 if (i == 1) {
4227 log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents(
4228 entries, log_position + 1);
4229 }
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004230 }
4231
4232 EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4233 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
4234}
4235
4236// Tests handling of delegate info from a network delegate in the case of an
4237// HTTP redirect.
4238TEST_F(URLRequestTestHTTP, NetworkDelegateInfoRedirect) {
4239 ASSERT_TRUE(test_server_.Start());
4240
4241 TestDelegate request_delegate;
4242 AsyncLoggingNetworkDelegate network_delegate;
4243 TestURLRequestContext context(true);
4244 context.set_network_delegate(&network_delegate);
4245 context.set_net_log(&net_log_);
4246 context.Init();
4247
4248 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004249 scoped_ptr<URLRequest> r(context.CreateRequest(
4250 test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY,
4251 &request_delegate, NULL));
4252 LoadStateWithParam load_state = r->GetLoadState();
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004253 EXPECT_EQ(LOAD_STATE_IDLE, load_state.state);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00004254 EXPECT_EQ(base::string16(), load_state.param);
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004255
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004256 r->Start();
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004257 base::RunLoop().Run();
4258
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004259 EXPECT_EQ(200, r->GetResponseCode());
4260 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004261 EXPECT_EQ(2, network_delegate.created_requests());
4262 EXPECT_EQ(0, network_delegate.destroyed_requests());
4263 }
4264 EXPECT_EQ(1, network_delegate.destroyed_requests());
4265
4266 size_t log_position = 0;
4267 CapturingNetLog::CapturedEntryList entries;
4268 net_log_.GetEntries(&entries);
4269 // The NetworkDelegate logged information in OnBeforeURLRequest,
4270 // OnBeforeSendHeaders, and OnHeadersReceived.
4271 for (size_t i = 0; i < 3; ++i) {
4272 log_position = ExpectLogContainsSomewhereAfter(
4273 entries,
4274 log_position + 1,
4275 NetLog::TYPE_URL_REQUEST_DELEGATE,
4276 NetLog::PHASE_BEGIN);
4277
4278 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
4279 log_position + 1);
4280
4281 ASSERT_LT(log_position, entries.size());
4282 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
4283 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00004284
4285 if (i == 1) {
4286 log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents(
4287 entries, log_position + 1);
4288 }
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004289 }
4290
4291 // The URLRequest::Delegate then gets informed about the redirect.
4292 log_position = ExpectLogContainsSomewhereAfter(
4293 entries,
4294 log_position + 1,
4295 NetLog::TYPE_URL_REQUEST_DELEGATE,
4296 NetLog::PHASE_BEGIN);
4297
4298 // The NetworkDelegate logged information in the same three events as before.
4299 for (size_t i = 0; i < 3; ++i) {
4300 log_position = ExpectLogContainsSomewhereAfter(
4301 entries,
4302 log_position + 1,
4303 NetLog::TYPE_URL_REQUEST_DELEGATE,
4304 NetLog::PHASE_BEGIN);
4305
4306 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
4307 log_position + 1);
4308
4309 ASSERT_LT(log_position, entries.size());
4310 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
4311 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);
4312 }
4313
4314 EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4315 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
4316}
4317
4318// Tests handling of delegate info from a network delegate in the case of HTTP
4319// AUTH.
4320TEST_F(URLRequestTestHTTP, NetworkDelegateInfoAuth) {
4321 ASSERT_TRUE(test_server_.Start());
4322
4323 TestDelegate request_delegate;
4324 AsyncLoggingNetworkDelegate network_delegate;
4325 TestURLRequestContext context(true);
4326 context.set_network_delegate(&network_delegate);
4327 context.set_net_log(&net_log_);
4328 context.Init();
4329
4330 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004331 scoped_ptr<URLRequest> r(context.CreateRequest(
4332 test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &request_delegate,
4333 NULL));
4334 LoadStateWithParam load_state = r->GetLoadState();
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004335 EXPECT_EQ(LOAD_STATE_IDLE, load_state.state);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00004336 EXPECT_EQ(base::string16(), load_state.param);
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004337
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004338 r->Start();
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004339 base::RunLoop().Run();
4340
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004341 EXPECT_EQ(200, r->GetResponseCode());
4342 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004343 EXPECT_EQ(1, network_delegate.created_requests());
4344 EXPECT_EQ(0, network_delegate.destroyed_requests());
4345 }
4346 EXPECT_EQ(1, network_delegate.destroyed_requests());
4347
4348 size_t log_position = 0;
4349 CapturingNetLog::CapturedEntryList entries;
4350 net_log_.GetEntries(&entries);
4351 // The NetworkDelegate should have logged information in OnBeforeURLRequest,
4352 // OnBeforeSendHeaders, OnHeadersReceived, OnAuthRequired, and then again in
4353 // OnBeforeURLRequest and OnBeforeSendHeaders.
4354 for (size_t i = 0; i < 6; ++i) {
4355 log_position = ExpectLogContainsSomewhereAfter(
4356 entries,
4357 log_position + 1,
4358 NetLog::TYPE_URL_REQUEST_DELEGATE,
4359 NetLog::PHASE_BEGIN);
4360
4361 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
4362 log_position + 1);
4363
4364 ASSERT_LT(log_position, entries.size());
4365 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
4366 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00004367
4368 if (i == 1) {
4369 log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents(
4370 entries, log_position + 1);
4371 }
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004372 }
4373
4374 EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4375 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
4376}
4377
4378// Tests handling of delegate info from a URLRequest::Delegate.
4379TEST_F(URLRequestTestHTTP, URLRequestDelegateInfo) {
4380 ASSERT_TRUE(test_server_.Start());
4381
4382 AsyncLoggingUrlRequestDelegate request_delegate(
4383 AsyncLoggingUrlRequestDelegate::NO_CANCEL);
4384 TestURLRequestContext context(true);
4385 context.set_network_delegate(NULL);
4386 context.set_net_log(&net_log_);
4387 context.Init();
4388
4389 {
4390 // A chunked response with delays between chunks is used to make sure that
4391 // attempts by the URLRequest delegate to log information while reading the
4392 // body are ignored. Since they are ignored, this test is robust against
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00004393 // the possibility of multiple reads being combined in the unlikely event
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004394 // that it occurs.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004395 scoped_ptr<URLRequest> r(context.CreateRequest(
4396 test_server_.GetURL("chunked?waitBetweenChunks=20"), DEFAULT_PRIORITY,
4397 &request_delegate, NULL));
4398 LoadStateWithParam load_state = r->GetLoadState();
4399 r->Start();
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004400 base::RunLoop().Run();
4401
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004402 EXPECT_EQ(200, r->GetResponseCode());
4403 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004404 }
4405
4406 CapturingNetLog::CapturedEntryList entries;
4407 net_log_.GetEntries(&entries);
4408
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00004409 size_t log_position = 0;
4410
4411 log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents(
4412 entries, log_position);
4413
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004414 // The delegate info should only have been logged on header complete. Other
4415 // times it should silently be ignored.
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00004416 log_position =
4417 ExpectLogContainsSomewhereAfter(entries,
4418 log_position + 1,
4419 NetLog::TYPE_URL_REQUEST_DELEGATE,
4420 NetLog::PHASE_BEGIN);
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004421
4422 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
4423 log_position + 1);
4424
4425 ASSERT_LT(log_position, entries.size());
4426 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
4427 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);
4428
4429 EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4430 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
4431 EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4432 entries, log_position + 1, NetLog::TYPE_URL_REQUEST_DELEGATE));
4433}
4434
4435// Tests handling of delegate info from a URLRequest::Delegate in the case of
4436// an HTTP redirect.
4437TEST_F(URLRequestTestHTTP, URLRequestDelegateInfoOnRedirect) {
4438 ASSERT_TRUE(test_server_.Start());
4439
4440 AsyncLoggingUrlRequestDelegate request_delegate(
4441 AsyncLoggingUrlRequestDelegate::NO_CANCEL);
4442 TestURLRequestContext context(true);
4443 context.set_network_delegate(NULL);
4444 context.set_net_log(&net_log_);
4445 context.Init();
4446
4447 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004448 scoped_ptr<URLRequest> r(context.CreateRequest(
4449 test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY,
4450 &request_delegate, NULL));
4451 LoadStateWithParam load_state = r->GetLoadState();
4452 r->Start();
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004453 base::RunLoop().Run();
4454
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004455 EXPECT_EQ(200, r->GetResponseCode());
4456 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004457 }
4458
4459 CapturingNetLog::CapturedEntryList entries;
4460 net_log_.GetEntries(&entries);
4461
4462 // Delegate info should only have been logged in OnReceivedRedirect and
4463 // OnResponseStarted.
4464 size_t log_position = 0;
4465 for (int i = 0; i < 2; ++i) {
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00004466 if (i == 0) {
4467 log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents(
4468 entries, log_position) + 1;
4469 }
4470
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004471 log_position = ExpectLogContainsSomewhereAfter(
4472 entries,
4473 log_position,
4474 NetLog::TYPE_URL_REQUEST_DELEGATE,
4475 NetLog::PHASE_BEGIN);
4476
4477 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
4478 log_position + 1);
4479
4480 ASSERT_LT(log_position, entries.size());
4481 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
4482 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);
4483 }
4484
4485 EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4486 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
4487 EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4488 entries, log_position + 1, NetLog::TYPE_URL_REQUEST_DELEGATE));
4489}
4490
4491// Tests handling of delegate info from a URLRequest::Delegate in the case of
4492// an HTTP redirect, with cancellation at various points.
4493TEST_F(URLRequestTestHTTP, URLRequestDelegateOnRedirectCancelled) {
4494 ASSERT_TRUE(test_server_.Start());
4495
4496 const AsyncLoggingUrlRequestDelegate::CancelStage kCancelStages[] = {
4497 AsyncLoggingUrlRequestDelegate::CANCEL_ON_RECEIVED_REDIRECT,
4498 AsyncLoggingUrlRequestDelegate::CANCEL_ON_RESPONSE_STARTED,
4499 AsyncLoggingUrlRequestDelegate::CANCEL_ON_READ_COMPLETED,
4500 };
4501
4502 for (size_t test_case = 0; test_case < arraysize(kCancelStages);
4503 ++test_case) {
4504 AsyncLoggingUrlRequestDelegate request_delegate(kCancelStages[test_case]);
4505 TestURLRequestContext context(true);
4506 CapturingNetLog net_log;
4507 context.set_network_delegate(NULL);
4508 context.set_net_log(&net_log);
4509 context.Init();
4510
4511 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004512 scoped_ptr<URLRequest> r(context.CreateRequest(
4513 test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY,
4514 &request_delegate, NULL));
4515 LoadStateWithParam load_state = r->GetLoadState();
4516 r->Start();
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004517 base::RunLoop().Run();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004518 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004519 }
4520
4521 CapturingNetLog::CapturedEntryList entries;
4522 net_log.GetEntries(&entries);
4523
4524 // Delegate info is always logged in both OnReceivedRedirect and
4525 // OnResponseStarted. In the CANCEL_ON_RECEIVED_REDIRECT, the
4526 // OnResponseStarted delegate call is after cancellation, but logging is
4527 // still currently supported in that call.
4528 size_t log_position = 0;
4529 for (int i = 0; i < 2; ++i) {
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00004530 if (i == 0) {
4531 log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents(
4532 entries, log_position) + 1;
4533 }
4534
Torne (Richard Coles)1e9bf3e2013-10-31 11:16:26 +00004535 log_position = ExpectLogContainsSomewhereAfter(
4536 entries,
4537 log_position,
4538 NetLog::TYPE_URL_REQUEST_DELEGATE,
4539 NetLog::PHASE_BEGIN);
4540
4541 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
4542 log_position + 1);
4543
4544 ASSERT_LT(log_position, entries.size());
4545 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
4546 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);
4547 }
4548
4549 EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4550 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
4551 EXPECT_FALSE(LogContainsEntryWithTypeAfter(
4552 entries, log_position + 1, NetLog::TYPE_URL_REQUEST_DELEGATE));
4553 }
4554}
4555
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004556namespace {
4557
4558const char kExtraHeader[] = "Allow-Snafu";
4559const char kExtraValue[] = "fubar";
4560
4561class RedirectWithAdditionalHeadersDelegate : public TestDelegate {
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01004562 virtual void OnReceivedRedirect(URLRequest* request,
4563 const RedirectInfo& redirect_info,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004564 bool* defer_redirect) OVERRIDE {
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01004565 TestDelegate::OnReceivedRedirect(request, redirect_info, defer_redirect);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004566 request->SetExtraRequestHeaderByName(kExtraHeader, kExtraValue, false);
4567 }
4568};
4569
4570} // namespace
4571
4572TEST_F(URLRequestTestHTTP, RedirectWithAdditionalHeadersTest) {
4573 ASSERT_TRUE(test_server_.Start());
4574
4575 GURL destination_url = test_server_.GetURL(
4576 "echoheader?" + std::string(kExtraHeader));
4577 GURL original_url = test_server_.GetURL(
4578 "server-redirect?" + destination_url.spec());
4579 RedirectWithAdditionalHeadersDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004580 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
4581 original_url, DEFAULT_PRIORITY, &d, NULL));
4582 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004583 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004584
4585 std::string value;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004586 const HttpRequestHeaders& headers = req->extra_request_headers();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004587 EXPECT_TRUE(headers.GetHeader(kExtraHeader, &value));
4588 EXPECT_EQ(kExtraValue, value);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004589 EXPECT_FALSE(req->is_pending());
4590 EXPECT_FALSE(req->is_redirecting());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004591 EXPECT_EQ(kExtraValue, d.data_received());
4592}
4593
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004594namespace {
4595
4596const char kExtraHeaderToRemove[] = "To-Be-Removed";
4597
4598class RedirectWithHeaderRemovalDelegate : public TestDelegate {
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01004599 virtual void OnReceivedRedirect(URLRequest* request,
4600 const RedirectInfo& redirect_info,
4601 bool* defer_redirect) OVERRIDE {
4602 TestDelegate::OnReceivedRedirect(request, redirect_info, defer_redirect);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004603 request->RemoveRequestHeaderByName(kExtraHeaderToRemove);
4604 }
4605};
4606
4607} // namespace
4608
4609TEST_F(URLRequestTestHTTP, RedirectWithHeaderRemovalTest) {
4610 ASSERT_TRUE(test_server_.Start());
4611
4612 GURL destination_url = test_server_.GetURL(
4613 "echoheader?" + std::string(kExtraHeaderToRemove));
4614 GURL original_url = test_server_.GetURL(
4615 "server-redirect?" + destination_url.spec());
4616 RedirectWithHeaderRemovalDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004617 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
4618 original_url, DEFAULT_PRIORITY, &d, NULL));
4619 req->SetExtraRequestHeaderByName(kExtraHeaderToRemove, "dummy", false);
4620 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004621 base::RunLoop().Run();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004622
4623 std::string value;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004624 const HttpRequestHeaders& headers = req->extra_request_headers();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004625 EXPECT_FALSE(headers.GetHeader(kExtraHeaderToRemove, &value));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004626 EXPECT_FALSE(req->is_pending());
4627 EXPECT_FALSE(req->is_redirecting());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004628 EXPECT_EQ("None", d.data_received());
4629}
4630
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004631TEST_F(URLRequestTestHTTP, CancelTest) {
4632 TestDelegate d;
4633 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004634 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
4635 GURL("http://www.google.com/"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004636
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004637 r->Start();
4638 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004639
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004640 r->Cancel();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004641
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004642 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004643
4644 // We expect to receive OnResponseStarted even though the request has been
4645 // cancelled.
4646 EXPECT_EQ(1, d.response_started_count());
4647 EXPECT_EQ(0, d.bytes_received());
4648 EXPECT_FALSE(d.received_data_before_response());
4649 }
4650}
4651
4652TEST_F(URLRequestTestHTTP, CancelTest2) {
4653 ASSERT_TRUE(test_server_.Start());
4654
4655 TestDelegate d;
4656 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004657 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
4658 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004659
4660 d.set_cancel_in_response_started(true);
4661
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004662 r->Start();
4663 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004664
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004665 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004666
4667 EXPECT_EQ(1, d.response_started_count());
4668 EXPECT_EQ(0, d.bytes_received());
4669 EXPECT_FALSE(d.received_data_before_response());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004670 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004671 }
4672}
4673
4674TEST_F(URLRequestTestHTTP, CancelTest3) {
4675 ASSERT_TRUE(test_server_.Start());
4676
4677 TestDelegate d;
4678 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004679 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
4680 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004681
4682 d.set_cancel_in_received_data(true);
4683
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004684 r->Start();
4685 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004686
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004687 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004688
4689 EXPECT_EQ(1, d.response_started_count());
4690 // There is no guarantee about how much data was received
4691 // before the cancel was issued. It could have been 0 bytes,
4692 // or it could have been all the bytes.
4693 // EXPECT_EQ(0, d.bytes_received());
4694 EXPECT_FALSE(d.received_data_before_response());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004695 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004696 }
4697}
4698
4699TEST_F(URLRequestTestHTTP, CancelTest4) {
4700 ASSERT_TRUE(test_server_.Start());
4701
4702 TestDelegate d;
4703 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004704 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
4705 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004706
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004707 r->Start();
4708 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004709
4710 // The request will be implicitly canceled when it is destroyed. The
4711 // test delegate must not post a quit message when this happens because
4712 // this test doesn't actually have a message loop. The quit message would
4713 // get put on this thread's message queue and the next test would exit
4714 // early, causing problems.
4715 d.set_quit_on_complete(false);
4716 }
4717 // expect things to just cleanup properly.
4718
4719 // we won't actually get a received reponse here because we've never run the
4720 // message loop
4721 EXPECT_FALSE(d.received_data_before_response());
4722 EXPECT_EQ(0, d.bytes_received());
4723}
4724
4725TEST_F(URLRequestTestHTTP, CancelTest5) {
4726 ASSERT_TRUE(test_server_.Start());
4727
4728 // populate cache
4729 {
4730 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004731 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
4732 test_server_.GetURL("cachetime"), DEFAULT_PRIORITY, &d, NULL));
4733 r->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004734 base::RunLoop().Run();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004735 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004736 }
4737
4738 // cancel read from cache (see bug 990242)
4739 {
4740 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004741 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
4742 test_server_.GetURL("cachetime"), DEFAULT_PRIORITY, &d, NULL));
4743 r->Start();
4744 r->Cancel();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004745 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004746
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004747 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004748 EXPECT_EQ(1, d.response_started_count());
4749 EXPECT_EQ(0, d.bytes_received());
4750 EXPECT_FALSE(d.received_data_before_response());
4751 }
4752}
4753
4754TEST_F(URLRequestTestHTTP, PostTest) {
4755 ASSERT_TRUE(test_server_.Start());
4756 HTTPUploadDataOperationTest("POST");
4757}
4758
4759TEST_F(URLRequestTestHTTP, PutTest) {
4760 ASSERT_TRUE(test_server_.Start());
4761 HTTPUploadDataOperationTest("PUT");
4762}
4763
4764TEST_F(URLRequestTestHTTP, PostEmptyTest) {
4765 ASSERT_TRUE(test_server_.Start());
4766
4767 TestDelegate d;
4768 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004769 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
4770 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL));
4771 r->set_method("POST");
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004772
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004773 r->Start();
4774 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004775
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004776 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004777
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004778 ASSERT_EQ(1, d.response_started_count())
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004779 << "request failed: " << r->status().status()
4780 << ", error: " << r->status().error();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004781
4782 EXPECT_FALSE(d.received_data_before_response());
4783 EXPECT_TRUE(d.data_received().empty());
4784 }
4785}
4786
4787TEST_F(URLRequestTestHTTP, PostFileTest) {
4788 ASSERT_TRUE(test_server_.Start());
4789
4790 TestDelegate d;
4791 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004792 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
4793 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL));
4794 r->set_method("POST");
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004795
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004796 base::FilePath dir;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004797 PathService::Get(base::DIR_EXE, &dir);
Torne (Richard Coles)a1401312014-03-18 10:20:56 +00004798 base::SetCurrentDirectory(dir);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004799
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004800 ScopedVector<UploadElementReader> element_readers;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004801
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004802 base::FilePath path;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004803 PathService::Get(base::DIR_SOURCE_ROOT, &path);
4804 path = path.Append(FILE_PATH_LITERAL("net"));
4805 path = path.Append(FILE_PATH_LITERAL("data"));
4806 path = path.Append(FILE_PATH_LITERAL("url_request_unittest"));
4807 path = path.Append(FILE_PATH_LITERAL("with-headers.html"));
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01004808 element_readers.push_back(
4809 new UploadFileElementReader(base::MessageLoopProxy::current().get(),
4810 path,
4811 0,
4812 kuint64max,
4813 base::Time()));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004814 r->set_upload(make_scoped_ptr(
Torne (Richard Coles)68043e12013-09-26 13:24:57 +01004815 new UploadDataStream(element_readers.Pass(), 0)));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004816
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004817 r->Start();
4818 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004819
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004820 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004821
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004822 int64 size = 0;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00004823 ASSERT_EQ(true, base::GetFileSize(path, &size));
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01004824 scoped_ptr<char[]> buf(new char[size]);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004825
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00004826 ASSERT_EQ(size, base::ReadFile(path, buf.get(), size));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004827
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004828 ASSERT_EQ(1, d.response_started_count())
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004829 << "request failed: " << r->status().status()
4830 << ", error: " << r->status().error();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004831
4832 EXPECT_FALSE(d.received_data_before_response());
4833
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004834 EXPECT_EQ(size, d.bytes_received());
4835 EXPECT_EQ(std::string(&buf[0], size), d.data_received());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004836 }
4837}
4838
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +00004839TEST_F(URLRequestTestHTTP, PostUnreadableFileTest) {
4840 ASSERT_TRUE(test_server_.Start());
4841
4842 TestDelegate d;
4843 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004844 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
4845 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL));
4846 r->set_method("POST");
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +00004847
4848 ScopedVector<UploadElementReader> element_readers;
4849
4850 element_readers.push_back(new UploadFileElementReader(
4851 base::MessageLoopProxy::current().get(),
4852 base::FilePath(FILE_PATH_LITERAL(
4853 "c:\\path\\to\\non\\existant\\file.randomness.12345")),
4854 0,
4855 kuint64max,
4856 base::Time()));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004857 r->set_upload(make_scoped_ptr(
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +00004858 new UploadDataStream(element_readers.Pass(), 0)));
4859
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004860 r->Start();
4861 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +00004862
4863 base::RunLoop().Run();
4864
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +00004865 EXPECT_TRUE(d.request_failed());
4866 EXPECT_FALSE(d.received_data_before_response());
4867 EXPECT_EQ(0, d.bytes_received());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004868 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
4869 EXPECT_EQ(ERR_FILE_NOT_FOUND, r->status().error());
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +00004870 }
4871}
4872
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004873TEST_F(URLRequestTestHTTP, TestPostChunkedDataBeforeStart) {
4874 ASSERT_TRUE(test_server_.Start());
4875
4876 TestDelegate d;
4877 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004878 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
4879 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL));
4880 r->EnableChunkedUpload();
4881 r->set_method("POST");
4882 AddChunksToUpload(r.get());
4883 r->Start();
4884 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004885
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004886 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004887
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004888 VerifyReceivedDataMatchesChunks(r.get(), &d);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004889 }
4890}
4891
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004892TEST_F(URLRequestTestHTTP, TestPostChunkedDataJustAfterStart) {
4893 ASSERT_TRUE(test_server_.Start());
4894
4895 TestDelegate d;
4896 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004897 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
4898 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL));
4899 r->EnableChunkedUpload();
4900 r->set_method("POST");
4901 r->Start();
4902 EXPECT_TRUE(r->is_pending());
4903 AddChunksToUpload(r.get());
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004904 base::RunLoop().Run();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004905
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004906 VerifyReceivedDataMatchesChunks(r.get(), &d);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004907 }
4908}
4909
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004910TEST_F(URLRequestTestHTTP, TestPostChunkedDataAfterStart) {
4911 ASSERT_TRUE(test_server_.Start());
4912
4913 TestDelegate d;
4914 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004915 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
4916 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL));
4917 r->EnableChunkedUpload();
4918 r->set_method("POST");
4919 r->Start();
4920 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004921
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004922 base::RunLoop().RunUntilIdle();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004923 AddChunksToUpload(r.get());
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004924 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004925
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004926 VerifyReceivedDataMatchesChunks(r.get(), &d);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004927 }
4928}
4929
4930TEST_F(URLRequestTestHTTP, ResponseHeadersTest) {
4931 ASSERT_TRUE(test_server_.Start());
4932
4933 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004934 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
4935 test_server_.GetURL("files/with-headers.html"), DEFAULT_PRIORITY, &d,
4936 NULL));
4937 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004938 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004939
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004940 const HttpResponseHeaders* headers = req->response_headers();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004941
4942 // Simple sanity check that response_info() accesses the same data.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004943 EXPECT_EQ(headers, req->response_info().headers.get());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004944
4945 std::string header;
4946 EXPECT_TRUE(headers->GetNormalizedHeader("cache-control", &header));
4947 EXPECT_EQ("private", header);
4948
4949 header.clear();
4950 EXPECT_TRUE(headers->GetNormalizedHeader("content-type", &header));
4951 EXPECT_EQ("text/html; charset=ISO-8859-1", header);
4952
4953 // The response has two "X-Multiple-Entries" headers.
4954 // This verfies our output has them concatenated together.
4955 header.clear();
4956 EXPECT_TRUE(headers->GetNormalizedHeader("x-multiple-entries", &header));
4957 EXPECT_EQ("a, b", header);
4958}
4959
4960TEST_F(URLRequestTestHTTP, ProcessSTS) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01004961 SpawnedTestServer::SSLOptions ssl_options;
4962 SpawnedTestServer https_test_server(
4963 SpawnedTestServer::TYPE_HTTPS,
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004964 ssl_options,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00004965 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004966 ASSERT_TRUE(https_test_server.Start());
4967
4968 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01004969 scoped_ptr<URLRequest> request(default_context_.CreateRequest(
4970 https_test_server.GetURL("files/hsts-headers.html"), DEFAULT_PRIORITY, &d,
4971 NULL));
4972 request->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01004973 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004974
4975 TransportSecurityState* security_state =
4976 default_context_.transport_security_state();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004977 TransportSecurityState::DomainState domain_state;
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01004978 EXPECT_TRUE(security_state->GetDynamicDomainState(
4979 SpawnedTestServer::kLocalhost, &domain_state));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00004980 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS,
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01004981 domain_state.sts.upgrade_mode);
4982 EXPECT_TRUE(domain_state.sts.include_subdomains);
4983 EXPECT_FALSE(domain_state.pkp.include_subdomains);
Ben Murdocheb525c52013-07-10 11:40:50 +01004984#if defined(OS_ANDROID)
4985 // Android's CertVerifyProc does not (yet) handle pins.
4986#else
4987 EXPECT_FALSE(domain_state.HasPublicKeyPins());
4988#endif
4989}
4990
4991// Android's CertVerifyProc does not (yet) handle pins. Therefore, it will
4992// reject HPKP headers, and a test setting only HPKP headers will fail (no
4993// DomainState present because header rejected).
4994#if defined(OS_ANDROID)
4995#define MAYBE_ProcessPKP DISABLED_ProcessPKP
4996#else
4997#define MAYBE_ProcessPKP ProcessPKP
4998#endif
4999
5000// Tests that enabling HPKP on a domain does not affect the HSTS
5001// validity/expiration.
5002TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKP) {
5003 SpawnedTestServer::SSLOptions ssl_options;
5004 SpawnedTestServer https_test_server(
5005 SpawnedTestServer::TYPE_HTTPS,
5006 ssl_options,
5007 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
5008 ASSERT_TRUE(https_test_server.Start());
5009
5010 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005011 scoped_ptr<URLRequest> request(default_context_.CreateRequest(
5012 https_test_server.GetURL("files/hpkp-headers.html"), DEFAULT_PRIORITY, &d,
5013 NULL));
5014 request->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005015 base::RunLoop().Run();
Ben Murdocheb525c52013-07-10 11:40:50 +01005016
5017 TransportSecurityState* security_state =
5018 default_context_.transport_security_state();
Ben Murdocheb525c52013-07-10 11:40:50 +01005019 TransportSecurityState::DomainState domain_state;
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005020 EXPECT_TRUE(security_state->GetDynamicDomainState(
5021 SpawnedTestServer::kLocalhost, &domain_state));
Ben Murdocheb525c52013-07-10 11:40:50 +01005022 EXPECT_EQ(TransportSecurityState::DomainState::MODE_DEFAULT,
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005023 domain_state.sts.upgrade_mode);
5024 EXPECT_FALSE(domain_state.sts.include_subdomains);
5025 EXPECT_FALSE(domain_state.pkp.include_subdomains);
Ben Murdocheb525c52013-07-10 11:40:50 +01005026 EXPECT_TRUE(domain_state.HasPublicKeyPins());
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005027 EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005028}
5029
5030TEST_F(URLRequestTestHTTP, ProcessSTSOnce) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01005031 SpawnedTestServer::SSLOptions ssl_options;
5032 SpawnedTestServer https_test_server(
5033 SpawnedTestServer::TYPE_HTTPS,
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005034 ssl_options,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005035 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005036 ASSERT_TRUE(https_test_server.Start());
5037
5038 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005039 scoped_ptr<URLRequest> request(default_context_.CreateRequest(
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005040 https_test_server.GetURL("files/hsts-multiple-headers.html"),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005041 DEFAULT_PRIORITY, &d, NULL));
5042 request->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005043 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005044
5045 // We should have set parameters from the first header, not the second.
5046 TransportSecurityState* security_state =
5047 default_context_.transport_security_state();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005048 TransportSecurityState::DomainState domain_state;
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005049 EXPECT_TRUE(security_state->GetDynamicDomainState(
5050 SpawnedTestServer::kLocalhost, &domain_state));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005051 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS,
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005052 domain_state.sts.upgrade_mode);
5053 EXPECT_FALSE(domain_state.sts.include_subdomains);
5054 EXPECT_FALSE(domain_state.pkp.include_subdomains);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005055}
5056
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01005057TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP) {
5058 SpawnedTestServer::SSLOptions ssl_options;
5059 SpawnedTestServer https_test_server(
5060 SpawnedTestServer::TYPE_HTTPS,
5061 ssl_options,
5062 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
5063 ASSERT_TRUE(https_test_server.Start());
5064
5065 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005066 scoped_ptr<URLRequest> request(default_context_.CreateRequest(
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01005067 https_test_server.GetURL("files/hsts-and-hpkp-headers.html"),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005068 DEFAULT_PRIORITY, &d, NULL));
5069 request->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005070 base::RunLoop().Run();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01005071
5072 // We should have set parameters from the first header, not the second.
5073 TransportSecurityState* security_state =
5074 default_context_.transport_security_state();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01005075 TransportSecurityState::DomainState domain_state;
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005076 EXPECT_TRUE(security_state->GetDynamicDomainState(
5077 SpawnedTestServer::kLocalhost, &domain_state));
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01005078 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS,
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005079 domain_state.sts.upgrade_mode);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01005080#if defined(OS_ANDROID)
5081 // Android's CertVerifyProc does not (yet) handle pins.
5082#else
5083 EXPECT_TRUE(domain_state.HasPublicKeyPins());
5084#endif
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005085 EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01005086
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01005087 // Even though there is an HSTS header asserting includeSubdomains, it is
5088 // the *second* such header, and we MUST process only the first.
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005089 EXPECT_FALSE(domain_state.sts.include_subdomains);
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01005090 // includeSubdomains does not occur in the test HPKP header.
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005091 EXPECT_FALSE(domain_state.pkp.include_subdomains);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01005092}
5093
Ben Murdocheb525c52013-07-10 11:40:50 +01005094// Tests that when multiple HPKP headers are present, asserting different
5095// policies, that only the first such policy is processed.
5096TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP2) {
5097 SpawnedTestServer::SSLOptions ssl_options;
5098 SpawnedTestServer https_test_server(
5099 SpawnedTestServer::TYPE_HTTPS,
5100 ssl_options,
5101 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
5102 ASSERT_TRUE(https_test_server.Start());
5103
5104 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005105 scoped_ptr<URLRequest> request(default_context_.CreateRequest(
Ben Murdocheb525c52013-07-10 11:40:50 +01005106 https_test_server.GetURL("files/hsts-and-hpkp-headers2.html"),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005107 DEFAULT_PRIORITY, &d, NULL));
5108 request->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005109 base::RunLoop().Run();
Ben Murdocheb525c52013-07-10 11:40:50 +01005110
5111 TransportSecurityState* security_state =
5112 default_context_.transport_security_state();
Ben Murdocheb525c52013-07-10 11:40:50 +01005113 TransportSecurityState::DomainState domain_state;
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005114 EXPECT_TRUE(security_state->GetDynamicDomainState(
5115 SpawnedTestServer::kLocalhost, &domain_state));
Ben Murdocheb525c52013-07-10 11:40:50 +01005116 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS,
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005117 domain_state.sts.upgrade_mode);
Ben Murdocheb525c52013-07-10 11:40:50 +01005118#if defined(OS_ANDROID)
5119 // Android's CertVerifyProc does not (yet) handle pins.
5120#else
5121 EXPECT_TRUE(domain_state.HasPublicKeyPins());
5122#endif
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005123 EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry);
Ben Murdocheb525c52013-07-10 11:40:50 +01005124
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005125 EXPECT_TRUE(domain_state.sts.include_subdomains);
5126 EXPECT_FALSE(domain_state.pkp.include_subdomains);
Ben Murdocheb525c52013-07-10 11:40:50 +01005127}
5128
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005129TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) {
5130 ASSERT_TRUE(test_server_.Start());
5131
5132 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005133 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5134 test_server_.GetURL("files/content-type-normalization.html"),
5135 DEFAULT_PRIORITY, &d, NULL));
5136 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005137 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005138
5139 std::string mime_type;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005140 req->GetMimeType(&mime_type);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005141 EXPECT_EQ("text/html", mime_type);
5142
5143 std::string charset;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005144 req->GetCharset(&charset);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005145 EXPECT_EQ("utf-8", charset);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005146 req->Cancel();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005147}
5148
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005149TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictDataRedirects) {
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01005150 // Test URLRequestJobFactory::ProtocolHandler::IsSafeRedirectTarget().
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01005151 GURL data_url("data:,foo");
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01005152 DataProtocolHandler data_protocol_handler;
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005153 EXPECT_FALSE(data_protocol_handler.IsSafeRedirectTarget(data_url));
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01005154
5155 // Test URLRequestJobFactoryImpl::IsSafeRedirectTarget().
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005156 EXPECT_FALSE(job_factory_.IsSafeRedirectTarget(data_url));
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01005157}
5158
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005159#if !defined(DISABLE_FILE_SUPPORT)
5160TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictFileRedirects) {
5161 // Test URLRequestJobFactory::ProtocolHandler::IsSafeRedirectTarget().
5162 GURL file_url("file:///foo.txt");
5163 FileProtocolHandler file_protocol_handler(base::MessageLoopProxy::current());
5164 EXPECT_FALSE(file_protocol_handler.IsSafeRedirectTarget(file_url));
5165
5166 // Test URLRequestJobFactoryImpl::IsSafeRedirectTarget().
5167 EXPECT_FALSE(job_factory_.IsSafeRedirectTarget(file_url));
5168}
5169
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005170TEST_F(URLRequestTestHTTP, RestrictFileRedirects) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005171 ASSERT_TRUE(test_server_.Start());
5172
5173 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005174 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5175 test_server_.GetURL("files/redirect-to-file.html"), DEFAULT_PRIORITY, &d,
5176 NULL));
5177 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005178 base::RunLoop().Run();
5179
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005180 EXPECT_EQ(URLRequestStatus::FAILED, req->status().status());
5181 EXPECT_EQ(ERR_UNSAFE_REDIRECT, req->status().error());
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005182}
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01005183#endif // !defined(DISABLE_FILE_SUPPORT)
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005184
5185TEST_F(URLRequestTestHTTP, RestrictDataRedirects) {
5186 ASSERT_TRUE(test_server_.Start());
5187
5188 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005189 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5190 test_server_.GetURL("files/redirect-to-data.html"), DEFAULT_PRIORITY, &d,
5191 NULL));
5192 req->Start();
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01005193 base::MessageLoop::current()->Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005194
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005195 EXPECT_EQ(URLRequestStatus::FAILED, req->status().status());
5196 EXPECT_EQ(ERR_UNSAFE_REDIRECT, req->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005197}
5198
5199TEST_F(URLRequestTestHTTP, RedirectToInvalidURL) {
5200 ASSERT_TRUE(test_server_.Start());
5201
5202 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005203 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5204 test_server_.GetURL("files/redirect-to-invalid-url.html"),
5205 DEFAULT_PRIORITY, &d, NULL));
5206 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005207 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005208
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005209 EXPECT_EQ(URLRequestStatus::FAILED, req->status().status());
5210 EXPECT_EQ(ERR_INVALID_URL, req->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005211}
5212
Ben Murdocheffb81e2014-03-31 11:51:25 +01005213// Make sure redirects are cached, despite not reading their bodies.
5214TEST_F(URLRequestTestHTTP, CacheRedirect) {
5215 ASSERT_TRUE(test_server_.Start());
5216 GURL redirect_url =
5217 test_server_.GetURL("files/redirect302-to-echo-cacheable");
5218
5219 {
5220 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005221 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5222 redirect_url, DEFAULT_PRIORITY, &d, NULL));
5223 req->Start();
Ben Murdocheffb81e2014-03-31 11:51:25 +01005224 base::RunLoop().Run();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005225 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
Ben Murdocheffb81e2014-03-31 11:51:25 +01005226 EXPECT_EQ(1, d.received_redirect_count());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005227 EXPECT_EQ(test_server_.GetURL("echo"), req->url());
Ben Murdocheffb81e2014-03-31 11:51:25 +01005228 }
5229
5230 {
5231 TestDelegate d;
5232 d.set_quit_on_redirect(true);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005233 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5234 redirect_url, DEFAULT_PRIORITY, &d, NULL));
5235 req->Start();
Ben Murdocheffb81e2014-03-31 11:51:25 +01005236 base::RunLoop().Run();
5237
5238 EXPECT_EQ(1, d.received_redirect_count());
5239 EXPECT_EQ(0, d.response_started_count());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005240 EXPECT_TRUE(req->was_cached());
Ben Murdocheffb81e2014-03-31 11:51:25 +01005241
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005242 req->FollowDeferredRedirect();
Ben Murdocheffb81e2014-03-31 11:51:25 +01005243 base::RunLoop().Run();
5244 EXPECT_EQ(1, d.received_redirect_count());
5245 EXPECT_EQ(1, d.response_started_count());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005246 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
5247 EXPECT_EQ(test_server_.GetURL("echo"), req->url());
Ben Murdocheffb81e2014-03-31 11:51:25 +01005248 }
5249}
5250
5251// Make sure a request isn't cached when a NetworkDelegate forces a redirect
5252// when the headers are read, since the body won't have been read.
5253TEST_F(URLRequestTestHTTP, NoCacheOnNetworkDelegateRedirect) {
5254 ASSERT_TRUE(test_server_.Start());
5255 // URL that is normally cached.
5256 GURL initial_url = test_server_.GetURL("cachetime");
5257
5258 {
5259 // Set up the TestNetworkDelegate tp force a redirect.
5260 GURL redirect_to_url = test_server_.GetURL("echo");
5261 default_network_delegate_.set_redirect_on_headers_received_url(
5262 redirect_to_url);
5263
5264 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005265 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5266 initial_url, DEFAULT_PRIORITY, &d, NULL));
5267 req->Start();
Ben Murdocheffb81e2014-03-31 11:51:25 +01005268 base::RunLoop().Run();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005269 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
Ben Murdocheffb81e2014-03-31 11:51:25 +01005270 EXPECT_EQ(1, d.received_redirect_count());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005271 EXPECT_EQ(redirect_to_url, req->url());
Ben Murdocheffb81e2014-03-31 11:51:25 +01005272 }
5273
5274 {
5275 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005276 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5277 initial_url, DEFAULT_PRIORITY, &d, NULL));
5278 req->Start();
Ben Murdocheffb81e2014-03-31 11:51:25 +01005279 base::RunLoop().Run();
5280
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005281 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
5282 EXPECT_FALSE(req->was_cached());
Ben Murdocheffb81e2014-03-31 11:51:25 +01005283 EXPECT_EQ(0, d.received_redirect_count());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005284 EXPECT_EQ(initial_url, req->url());
Ben Murdocheffb81e2014-03-31 11:51:25 +01005285 }
5286}
5287
5288// Tests that redirection to an unsafe URL is allowed when it has been marked as
5289// safe.
5290TEST_F(URLRequestTestHTTP, UnsafeRedirectToWhitelistedUnsafeURL) {
5291 ASSERT_TRUE(test_server_.Start());
5292
5293 GURL unsafe_url("data:text/html,this-is-considered-an-unsafe-url");
5294 default_network_delegate_.set_redirect_on_headers_received_url(unsafe_url);
5295 default_network_delegate_.set_allowed_unsafe_redirect_url(unsafe_url);
5296
5297 TestDelegate d;
5298 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005299 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
5300 test_server_.GetURL("whatever"), DEFAULT_PRIORITY, &d, NULL));
Ben Murdocheffb81e2014-03-31 11:51:25 +01005301
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005302 r->Start();
Ben Murdocheffb81e2014-03-31 11:51:25 +01005303 base::RunLoop().Run();
5304
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005305 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
Ben Murdocheffb81e2014-03-31 11:51:25 +01005306
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005307 EXPECT_EQ(2U, r->url_chain().size());
5308 EXPECT_EQ(OK, r->status().error());
5309 EXPECT_EQ(unsafe_url, r->url());
Ben Murdocheffb81e2014-03-31 11:51:25 +01005310 EXPECT_EQ("this-is-considered-an-unsafe-url", d.data_received());
5311 }
5312}
5313
5314// Tests that a redirect to a different unsafe URL is blocked, even after adding
5315// some other URL to the whitelist.
5316TEST_F(URLRequestTestHTTP, UnsafeRedirectToDifferentUnsafeURL) {
5317 ASSERT_TRUE(test_server_.Start());
5318
5319 GURL unsafe_url("data:text/html,something");
5320 GURL different_unsafe_url("data:text/html,something-else");
5321 default_network_delegate_.set_redirect_on_headers_received_url(unsafe_url);
5322 default_network_delegate_.set_allowed_unsafe_redirect_url(
5323 different_unsafe_url);
5324
5325 TestDelegate d;
5326 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005327 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
5328 test_server_.GetURL("whatever"), DEFAULT_PRIORITY, &d, NULL));
Ben Murdocheffb81e2014-03-31 11:51:25 +01005329
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005330 r->Start();
Ben Murdocheffb81e2014-03-31 11:51:25 +01005331 base::RunLoop().Run();
5332
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005333 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
5334 EXPECT_EQ(ERR_UNSAFE_REDIRECT, r->status().error());
Ben Murdocheffb81e2014-03-31 11:51:25 +01005335 }
5336}
5337
Ben Murdocheffb81e2014-03-31 11:51:25 +01005338// Redirects from an URL with fragment to an unsafe URL with fragment should
5339// be allowed, and the reference fragment of the target URL should be preserved.
5340TEST_F(URLRequestTestHTTP, UnsafeRedirectWithDifferentReferenceFragment) {
5341 ASSERT_TRUE(test_server_.Start());
5342
5343 GURL original_url(test_server_.GetURL("original#fragment1"));
5344 GURL unsafe_url("data:,url-marked-safe-and-used-in-redirect#fragment2");
5345 GURL expected_url("data:,url-marked-safe-and-used-in-redirect#fragment2");
5346
5347 default_network_delegate_.set_redirect_on_headers_received_url(unsafe_url);
5348 default_network_delegate_.set_allowed_unsafe_redirect_url(unsafe_url);
5349
5350 TestDelegate d;
5351 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005352 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
5353 original_url, DEFAULT_PRIORITY, &d, NULL));
Ben Murdocheffb81e2014-03-31 11:51:25 +01005354
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005355 r->Start();
Ben Murdocheffb81e2014-03-31 11:51:25 +01005356 base::RunLoop().Run();
5357
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005358 EXPECT_EQ(2U, r->url_chain().size());
5359 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
5360 EXPECT_EQ(OK, r->status().error());
5361 EXPECT_EQ(original_url, r->original_url());
5362 EXPECT_EQ(expected_url, r->url());
Ben Murdocheffb81e2014-03-31 11:51:25 +01005363 }
5364}
5365
5366// When a delegate has specified a safe redirect URL, but it does not match the
5367// redirect target, then do not prevent the reference fragment from being added.
Ben Murdochc5cede92014-04-10 11:22:14 +01005368TEST_F(URLRequestTestHTTP, RedirectWithReferenceFragmentAndUnrelatedUnsafeUrl) {
Ben Murdocheffb81e2014-03-31 11:51:25 +01005369 ASSERT_TRUE(test_server_.Start());
5370
5371 GURL original_url(test_server_.GetURL("original#expected-fragment"));
5372 GURL unsafe_url("data:text/html,this-url-does-not-match-redirect-url");
5373 GURL redirect_url(test_server_.GetURL("target"));
5374 GURL expected_redirect_url(test_server_.GetURL("target#expected-fragment"));
5375
5376 default_network_delegate_.set_redirect_on_headers_received_url(redirect_url);
5377 default_network_delegate_.set_allowed_unsafe_redirect_url(unsafe_url);
5378
5379 TestDelegate d;
5380 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005381 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
5382 original_url, DEFAULT_PRIORITY, &d, NULL));
Ben Murdocheffb81e2014-03-31 11:51:25 +01005383
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005384 r->Start();
Ben Murdocheffb81e2014-03-31 11:51:25 +01005385 base::RunLoop().Run();
5386
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005387 EXPECT_EQ(2U, r->url_chain().size());
5388 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
5389 EXPECT_EQ(OK, r->status().error());
5390 EXPECT_EQ(original_url, r->original_url());
5391 EXPECT_EQ(expected_redirect_url, r->url());
Ben Murdocheffb81e2014-03-31 11:51:25 +01005392 }
5393}
5394
Ben Murdochc5cede92014-04-10 11:22:14 +01005395// When a delegate has specified a safe redirect URL, assume that the redirect
5396// URL should not be changed. In particular, the reference fragment should not
5397// be modified.
5398TEST_F(URLRequestTestHTTP, RedirectWithReferenceFragment) {
5399 ASSERT_TRUE(test_server_.Start());
5400
5401 GURL original_url(test_server_.GetURL("original#should-not-be-appended"));
5402 GURL redirect_url("data:text/html,expect-no-reference-fragment");
5403
5404 default_network_delegate_.set_redirect_on_headers_received_url(redirect_url);
5405 default_network_delegate_.set_allowed_unsafe_redirect_url(redirect_url);
5406
5407 TestDelegate d;
5408 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005409 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
5410 original_url, DEFAULT_PRIORITY, &d, NULL));
Ben Murdochc5cede92014-04-10 11:22:14 +01005411
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005412 r->Start();
Ben Murdochc5cede92014-04-10 11:22:14 +01005413 base::RunLoop().Run();
5414
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005415 EXPECT_EQ(2U, r->url_chain().size());
5416 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
5417 EXPECT_EQ(OK, r->status().error());
5418 EXPECT_EQ(original_url, r->original_url());
5419 EXPECT_EQ(redirect_url, r->url());
Ben Murdochc5cede92014-04-10 11:22:14 +01005420 }
5421}
5422
5423// When a URLRequestRedirectJob is created, the redirection must be followed and
5424// the reference fragment of the target URL must not be modified.
5425TEST_F(URLRequestTestHTTP, RedirectJobWithReferenceFragment) {
5426 ASSERT_TRUE(test_server_.Start());
5427
5428 GURL original_url(test_server_.GetURL("original#should-not-be-appended"));
5429 GURL redirect_url(test_server_.GetURL("echo"));
5430
5431 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005432 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
5433 original_url, DEFAULT_PRIORITY, &d, NULL));
Ben Murdochc5cede92014-04-10 11:22:14 +01005434
5435 URLRequestRedirectJob* job = new URLRequestRedirectJob(
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005436 r.get(), &default_network_delegate_, redirect_url,
Ben Murdochc5cede92014-04-10 11:22:14 +01005437 URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason");
5438 AddTestInterceptor()->set_main_intercept_job(job);
5439
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005440 r->Start();
Ben Murdochc5cede92014-04-10 11:22:14 +01005441 base::RunLoop().Run();
5442
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005443 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
5444 EXPECT_EQ(OK, r->status().error());
5445 EXPECT_EQ(original_url, r->original_url());
5446 EXPECT_EQ(redirect_url, r->url());
Ben Murdochc5cede92014-04-10 11:22:14 +01005447}
5448
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005449TEST_F(URLRequestTestHTTP, NoUserPassInReferrer) {
5450 ASSERT_TRUE(test_server_.Start());
5451
5452 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005453 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5454 test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL));
5455 req->SetReferrer("http://user:pass@foo.com/");
5456 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005457 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005458
5459 EXPECT_EQ(std::string("http://foo.com/"), d.data_received());
5460}
5461
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01005462TEST_F(URLRequestTestHTTP, NoFragmentInReferrer) {
5463 ASSERT_TRUE(test_server_.Start());
5464
5465 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005466 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5467 test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL));
5468 req->SetReferrer("http://foo.com/test#fragment");
5469 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005470 base::RunLoop().Run();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01005471
5472 EXPECT_EQ(std::string("http://foo.com/test"), d.data_received());
5473}
5474
5475TEST_F(URLRequestTestHTTP, EmptyReferrerAfterValidReferrer) {
5476 ASSERT_TRUE(test_server_.Start());
5477
5478 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005479 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5480 test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL));
5481 req->SetReferrer("http://foo.com/test#fragment");
5482 req->SetReferrer("");
5483 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005484 base::RunLoop().Run();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01005485
5486 EXPECT_EQ(std::string("None"), d.data_received());
5487}
5488
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005489// Defer network start and then resume, checking that the request was a success
5490// and bytes were received.
5491TEST_F(URLRequestTestHTTP, DeferredBeforeNetworkStart) {
5492 ASSERT_TRUE(test_server_.Start());
5493
5494 TestDelegate d;
5495 {
5496 d.set_quit_on_network_start(true);
5497 GURL test_url(test_server_.GetURL("echo"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005498 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5499 test_url, DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005500
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005501 req->Start();
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005502 base::RunLoop().Run();
5503
5504 EXPECT_EQ(1, d.received_before_network_start_count());
5505 EXPECT_EQ(0, d.response_started_count());
5506
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005507 req->ResumeNetworkStart();
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005508 base::RunLoop().Run();
5509
5510 EXPECT_EQ(1, d.response_started_count());
5511 EXPECT_NE(0, d.bytes_received());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005512 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005513 }
5514}
5515
5516// Check that OnBeforeNetworkStart is only called once even if there is a
5517// redirect.
5518TEST_F(URLRequestTestHTTP, BeforeNetworkStartCalledOnce) {
5519 ASSERT_TRUE(test_server_.Start());
5520
5521 TestDelegate d;
5522 {
5523 d.set_quit_on_redirect(true);
5524 d.set_quit_on_network_start(true);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005525 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5526 test_server_.GetURL("server-redirect?echo"), DEFAULT_PRIORITY, &d,
5527 NULL));
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005528
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005529 req->Start();
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005530 base::RunLoop().Run();
5531
5532 EXPECT_EQ(1, d.received_before_network_start_count());
5533 EXPECT_EQ(0, d.response_started_count());
5534 EXPECT_EQ(0, d.received_redirect_count());
5535
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005536 req->ResumeNetworkStart();
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005537 base::RunLoop().Run();
5538
5539 EXPECT_EQ(1, d.received_redirect_count());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005540 req->FollowDeferredRedirect();
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005541 base::RunLoop().Run();
5542
5543 // Check that the redirect's new network transaction does not get propagated
5544 // to a second OnBeforeNetworkStart() notification.
5545 EXPECT_EQ(1, d.received_before_network_start_count());
5546
5547 EXPECT_EQ(1, d.response_started_count());
5548 EXPECT_NE(0, d.bytes_received());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005549 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005550 }
5551}
5552
5553// Cancel the request after learning that the request would use the network.
5554TEST_F(URLRequestTestHTTP, CancelOnBeforeNetworkStart) {
5555 ASSERT_TRUE(test_server_.Start());
5556
5557 TestDelegate d;
5558 {
5559 d.set_quit_on_network_start(true);
5560 GURL test_url(test_server_.GetURL("echo"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005561 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5562 test_url, DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005563
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005564 req->Start();
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005565 base::RunLoop().Run();
5566
5567 EXPECT_EQ(1, d.received_before_network_start_count());
5568 EXPECT_EQ(0, d.response_started_count());
5569
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005570 req->Cancel();
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005571 base::RunLoop().Run();
5572
5573 EXPECT_EQ(1, d.response_started_count());
5574 EXPECT_EQ(0, d.bytes_received());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005575 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00005576 }
5577}
5578
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005579TEST_F(URLRequestTestHTTP, CancelRedirect) {
5580 ASSERT_TRUE(test_server_.Start());
5581
5582 TestDelegate d;
5583 {
5584 d.set_cancel_in_received_redirect(true);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005585 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5586 test_server_.GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, &d,
5587 NULL));
5588 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005589 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005590
5591 EXPECT_EQ(1, d.response_started_count());
5592 EXPECT_EQ(0, d.bytes_received());
5593 EXPECT_FALSE(d.received_data_before_response());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005594 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005595 }
5596}
5597
5598TEST_F(URLRequestTestHTTP, DeferredRedirect) {
5599 ASSERT_TRUE(test_server_.Start());
5600
5601 TestDelegate d;
5602 {
5603 d.set_quit_on_redirect(true);
Ben Murdocheb525c52013-07-10 11:40:50 +01005604 GURL test_url(test_server_.GetURL("files/redirect-test.html"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005605 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5606 test_url, DEFAULT_PRIORITY, &d, NULL));
Ben Murdocheb525c52013-07-10 11:40:50 +01005607
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005608 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005609 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005610
5611 EXPECT_EQ(1, d.received_redirect_count());
5612
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005613 req->FollowDeferredRedirect();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005614 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005615
5616 EXPECT_EQ(1, d.response_started_count());
5617 EXPECT_FALSE(d.received_data_before_response());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005618 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005619
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005620 base::FilePath path;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005621 PathService::Get(base::DIR_SOURCE_ROOT, &path);
5622 path = path.Append(FILE_PATH_LITERAL("net"));
5623 path = path.Append(FILE_PATH_LITERAL("data"));
5624 path = path.Append(FILE_PATH_LITERAL("url_request_unittest"));
5625 path = path.Append(FILE_PATH_LITERAL("with-headers.html"));
5626
5627 std::string contents;
Torne (Richard Coles)58537e22013-09-12 12:10:22 +01005628 EXPECT_TRUE(base::ReadFileToString(path, &contents));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005629 EXPECT_EQ(contents, d.data_received());
5630 }
5631}
5632
Ben Murdocheb525c52013-07-10 11:40:50 +01005633TEST_F(URLRequestTestHTTP, DeferredRedirect_GetFullRequestHeaders) {
5634 ASSERT_TRUE(test_server_.Start());
5635
5636 TestDelegate d;
5637 {
5638 d.set_quit_on_redirect(true);
5639 GURL test_url(test_server_.GetURL("files/redirect-test.html"));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005640 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5641 test_url, DEFAULT_PRIORITY, &d, NULL));
Ben Murdocheb525c52013-07-10 11:40:50 +01005642
5643 EXPECT_FALSE(d.have_full_request_headers());
5644
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005645 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005646 base::RunLoop().Run();
Ben Murdocheb525c52013-07-10 11:40:50 +01005647
5648 EXPECT_EQ(1, d.received_redirect_count());
5649 EXPECT_TRUE(d.have_full_request_headers());
5650 CheckFullRequestHeaders(d.full_request_headers(), test_url);
5651 d.ClearFullRequestHeaders();
5652
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005653 req->FollowDeferredRedirect();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005654 base::RunLoop().Run();
Ben Murdocheb525c52013-07-10 11:40:50 +01005655
5656 GURL target_url(test_server_.GetURL("files/with-headers.html"));
5657 EXPECT_EQ(1, d.response_started_count());
5658 EXPECT_TRUE(d.have_full_request_headers());
5659 CheckFullRequestHeaders(d.full_request_headers(), target_url);
5660 EXPECT_FALSE(d.received_data_before_response());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005661 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
Ben Murdocheb525c52013-07-10 11:40:50 +01005662
5663 base::FilePath path;
5664 PathService::Get(base::DIR_SOURCE_ROOT, &path);
5665 path = path.Append(FILE_PATH_LITERAL("net"));
5666 path = path.Append(FILE_PATH_LITERAL("data"));
5667 path = path.Append(FILE_PATH_LITERAL("url_request_unittest"));
5668 path = path.Append(FILE_PATH_LITERAL("with-headers.html"));
5669
5670 std::string contents;
Torne (Richard Coles)58537e22013-09-12 12:10:22 +01005671 EXPECT_TRUE(base::ReadFileToString(path, &contents));
Ben Murdocheb525c52013-07-10 11:40:50 +01005672 EXPECT_EQ(contents, d.data_received());
5673 }
5674}
5675
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005676TEST_F(URLRequestTestHTTP, CancelDeferredRedirect) {
5677 ASSERT_TRUE(test_server_.Start());
5678
5679 TestDelegate d;
5680 {
5681 d.set_quit_on_redirect(true);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005682 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5683 test_server_.GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, &d,
5684 NULL));
5685 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005686 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005687
5688 EXPECT_EQ(1, d.received_redirect_count());
5689
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005690 req->Cancel();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005691 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005692
5693 EXPECT_EQ(1, d.response_started_count());
5694 EXPECT_EQ(0, d.bytes_received());
5695 EXPECT_FALSE(d.received_data_before_response());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005696 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005697 }
5698}
5699
5700TEST_F(URLRequestTestHTTP, VaryHeader) {
5701 ASSERT_TRUE(test_server_.Start());
5702
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01005703 // Populate the cache.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005704 {
5705 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005706 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5707 test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d,
5708 NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005709 HttpRequestHeaders headers;
5710 headers.SetHeader("foo", "1");
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005711 req->SetExtraRequestHeaders(headers);
5712 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005713 base::RunLoop().Run();
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01005714
5715 LoadTimingInfo load_timing_info;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005716 req->GetLoadTimingInfo(&load_timing_info);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01005717 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005718 }
5719
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01005720 // Expect a cache hit.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005721 {
5722 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005723 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5724 test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d,
5725 NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005726 HttpRequestHeaders headers;
5727 headers.SetHeader("foo", "1");
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005728 req->SetExtraRequestHeaders(headers);
5729 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005730 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005731
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005732 EXPECT_TRUE(req->was_cached());
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01005733
5734 LoadTimingInfo load_timing_info;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005735 req->GetLoadTimingInfo(&load_timing_info);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01005736 TestLoadTimingCacheHitNoNetwork(load_timing_info);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005737 }
5738
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01005739 // Expect a cache miss.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005740 {
5741 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005742 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5743 test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d,
5744 NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005745 HttpRequestHeaders headers;
5746 headers.SetHeader("foo", "2");
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005747 req->SetExtraRequestHeaders(headers);
5748 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005749 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005750
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005751 EXPECT_FALSE(req->was_cached());
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01005752
5753 LoadTimingInfo load_timing_info;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005754 req->GetLoadTimingInfo(&load_timing_info);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01005755 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005756 }
5757}
5758
5759TEST_F(URLRequestTestHTTP, BasicAuth) {
5760 ASSERT_TRUE(test_server_.Start());
5761
5762 // populate the cache
5763 {
5764 TestDelegate d;
5765 d.set_credentials(AuthCredentials(kUser, kSecret));
5766
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005767 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
5768 test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL));
5769 r->Start();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005770
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005771 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005772
5773 EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);
5774 }
5775
5776 // repeat request with end-to-end validation. since auth-basic results in a
5777 // cachable page, we expect this test to result in a 304. in which case, the
5778 // response should be fetched from the cache.
5779 {
5780 TestDelegate d;
5781 d.set_credentials(AuthCredentials(kUser, kSecret));
5782
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005783 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
5784 test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL));
5785 r->SetLoadFlags(LOAD_VALIDATE_CACHE);
5786 r->Start();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005787
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005788 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005789
5790 EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);
5791
5792 // Should be the same cached document.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005793 EXPECT_TRUE(r->was_cached());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005794 }
5795}
5796
5797// Check that Set-Cookie headers in 401 responses are respected.
5798// http://crbug.com/6450
5799TEST_F(URLRequestTestHTTP, BasicAuthWithCookies) {
5800 ASSERT_TRUE(test_server_.Start());
5801
5802 GURL url_requiring_auth =
5803 test_server_.GetURL("auth-basic?set-cookie-if-challenged");
5804
5805 // Request a page that will give a 401 containing a Set-Cookie header.
5806 // Verify that when the transaction is restarted, it includes the new cookie.
5807 {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005808 TestNetworkDelegate network_delegate; // Must outlive URLRequest.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005809 TestURLRequestContext context(true);
5810 context.set_network_delegate(&network_delegate);
5811 context.Init();
5812
5813 TestDelegate d;
5814 d.set_credentials(AuthCredentials(kUser, kSecret));
5815
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005816 scoped_ptr<URLRequest> r(context.CreateRequest(
5817 url_requiring_auth, DEFAULT_PRIORITY, &d, NULL));
5818 r->Start();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005819
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005820 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005821
5822 EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);
5823
5824 // Make sure we sent the cookie in the restarted transaction.
5825 EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true")
5826 != std::string::npos);
5827 }
5828
5829 // Same test as above, except this time the restart is initiated earlier
5830 // (without user intervention since identity is embedded in the URL).
5831 {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005832 TestNetworkDelegate network_delegate; // Must outlive URLRequest.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005833 TestURLRequestContext context(true);
5834 context.set_network_delegate(&network_delegate);
5835 context.Init();
5836
5837 TestDelegate d;
5838
5839 GURL::Replacements replacements;
5840 std::string username("user2");
5841 std::string password("secret");
5842 replacements.SetUsernameStr(username);
5843 replacements.SetPasswordStr(password);
5844 GURL url_with_identity = url_requiring_auth.ReplaceComponents(replacements);
5845
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005846 scoped_ptr<URLRequest> r(context.CreateRequest(
5847 url_with_identity, DEFAULT_PRIORITY, &d, NULL));
5848 r->Start();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005849
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005850 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005851
5852 EXPECT_TRUE(d.data_received().find("user2/secret") != std::string::npos);
5853
5854 // Make sure we sent the cookie in the restarted transaction.
5855 EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true")
5856 != std::string::npos);
5857 }
5858}
5859
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005860// Tests that load timing works as expected with auth and the cache.
5861TEST_F(URLRequestTestHTTP, BasicAuthLoadTiming) {
5862 ASSERT_TRUE(test_server_.Start());
5863
5864 // populate the cache
5865 {
5866 TestDelegate d;
5867 d.set_credentials(AuthCredentials(kUser, kSecret));
5868
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005869 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
5870 test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL));
5871 r->Start();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005872
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005873 base::RunLoop().Run();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005874
5875 EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);
5876
5877 LoadTimingInfo load_timing_info_before_auth;
5878 EXPECT_TRUE(default_network_delegate_.GetLoadTimingInfoBeforeAuth(
5879 &load_timing_info_before_auth));
5880 TestLoadTimingNotReused(load_timing_info_before_auth,
5881 CONNECT_TIMING_HAS_DNS_TIMES);
5882
5883 LoadTimingInfo load_timing_info;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005884 r->GetLoadTimingInfo(&load_timing_info);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005885 // The test server does not support keep alive sockets, so the second
5886 // request with auth should use a new socket.
5887 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
5888 EXPECT_NE(load_timing_info_before_auth.socket_log_id,
5889 load_timing_info.socket_log_id);
5890 EXPECT_LE(load_timing_info_before_auth.receive_headers_end,
5891 load_timing_info.connect_timing.connect_start);
5892 }
5893
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01005894 // Repeat request with end-to-end validation. Since auth-basic results in a
5895 // cachable page, we expect this test to result in a 304. In which case, the
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005896 // response should be fetched from the cache.
5897 {
5898 TestDelegate d;
5899 d.set_credentials(AuthCredentials(kUser, kSecret));
5900
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005901 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
5902 test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL));
5903 r->SetLoadFlags(LOAD_VALIDATE_CACHE);
5904 r->Start();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005905
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005906 base::RunLoop().Run();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005907
5908 EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);
5909
5910 // Should be the same cached document.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005911 EXPECT_TRUE(r->was_cached());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005912
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01005913 // Since there was a request that went over the wire, the load timing
5914 // information should include connection times.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005915 LoadTimingInfo load_timing_info;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005916 r->GetLoadTimingInfo(&load_timing_info);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01005917 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005918 }
5919}
5920
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005921// In this test, we do a POST which the server will 302 redirect.
5922// The subsequent transaction should use GET, and should not send the
5923// Content-Type header.
5924// http://code.google.com/p/chromium/issues/detail?id=843
5925TEST_F(URLRequestTestHTTP, Post302RedirectGet) {
5926 ASSERT_TRUE(test_server_.Start());
5927
5928 const char kData[] = "hello world";
5929
5930 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005931 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
5932 test_server_.GetURL("files/redirect-to-echoall"), DEFAULT_PRIORITY, &d,
5933 NULL));
5934 req->set_method("POST");
5935 req->set_upload(make_scoped_ptr(CreateSimpleUploadData(kData)));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005936
5937 // Set headers (some of which are specific to the POST).
5938 HttpRequestHeaders headers;
5939 headers.AddHeadersFromString(
5940 "Content-Type: multipart/form-data; "
5941 "boundary=----WebKitFormBoundaryAADeAA+NAAWMAAwZ\r\n"
5942 "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,"
5943 "text/plain;q=0.8,image/png,*/*;q=0.5\r\n"
5944 "Accept-Language: en-US,en\r\n"
5945 "Accept-Charset: ISO-8859-1,*,utf-8\r\n"
5946 "Content-Length: 11\r\n"
5947 "Origin: http://localhost:1337/");
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005948 req->SetExtraRequestHeaders(headers);
5949 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01005950 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005951
5952 std::string mime_type;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01005953 req->GetMimeType(&mime_type);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00005954 EXPECT_EQ("text/html", mime_type);
5955
5956 const std::string& data = d.data_received();
5957
5958 // Check that the post-specific headers were stripped:
5959 EXPECT_FALSE(ContainsString(data, "Content-Length:"));
5960 EXPECT_FALSE(ContainsString(data, "Content-Type:"));
5961 EXPECT_FALSE(ContainsString(data, "Origin:"));
5962
5963 // These extra request headers should not have been stripped.
5964 EXPECT_TRUE(ContainsString(data, "Accept:"));
5965 EXPECT_TRUE(ContainsString(data, "Accept-Language:"));
5966 EXPECT_TRUE(ContainsString(data, "Accept-Charset:"));
5967}
5968
5969// The following tests check that we handle mutating the request method for
5970// HTTP redirects as expected.
5971// See http://crbug.com/56373 and http://crbug.com/102130.
5972
5973TEST_F(URLRequestTestHTTP, Redirect301Tests) {
5974 ASSERT_TRUE(test_server_.Start());
5975
5976 const GURL url = test_server_.GetURL("files/redirect301-to-echo");
5977
5978 HTTPRedirectMethodTest(url, "POST", "GET", true);
5979 HTTPRedirectMethodTest(url, "PUT", "PUT", true);
5980 HTTPRedirectMethodTest(url, "HEAD", "HEAD", false);
5981}
5982
5983TEST_F(URLRequestTestHTTP, Redirect302Tests) {
5984 ASSERT_TRUE(test_server_.Start());
5985
5986 const GURL url = test_server_.GetURL("files/redirect302-to-echo");
5987
5988 HTTPRedirectMethodTest(url, "POST", "GET", true);
5989 HTTPRedirectMethodTest(url, "PUT", "PUT", true);
5990 HTTPRedirectMethodTest(url, "HEAD", "HEAD", false);
5991}
5992
5993TEST_F(URLRequestTestHTTP, Redirect303Tests) {
5994 ASSERT_TRUE(test_server_.Start());
5995
5996 const GURL url = test_server_.GetURL("files/redirect303-to-echo");
5997
5998 HTTPRedirectMethodTest(url, "POST", "GET", true);
5999 HTTPRedirectMethodTest(url, "PUT", "GET", true);
6000 HTTPRedirectMethodTest(url, "HEAD", "HEAD", false);
6001}
6002
6003TEST_F(URLRequestTestHTTP, Redirect307Tests) {
6004 ASSERT_TRUE(test_server_.Start());
6005
6006 const GURL url = test_server_.GetURL("files/redirect307-to-echo");
6007
6008 HTTPRedirectMethodTest(url, "POST", "POST", true);
6009 HTTPRedirectMethodTest(url, "PUT", "PUT", true);
6010 HTTPRedirectMethodTest(url, "HEAD", "HEAD", false);
6011}
6012
Bo Liu5c02ac12014-05-01 10:37:37 -07006013TEST_F(URLRequestTestHTTP, Redirect308Tests) {
6014 ASSERT_TRUE(test_server_.Start());
6015
6016 const GURL url = test_server_.GetURL("files/redirect308-to-echo");
6017
6018 HTTPRedirectMethodTest(url, "POST", "POST", true);
6019 HTTPRedirectMethodTest(url, "PUT", "PUT", true);
6020 HTTPRedirectMethodTest(url, "HEAD", "HEAD", false);
6021}
6022
6023// Make sure that 308 responses without bodies are not treated as redirects.
6024// Certain legacy apis that pre-date the response code expect this behavior
6025// (Like Google Drive).
6026TEST_F(URLRequestTestHTTP, NoRedirectOn308WithoutLocationHeader) {
6027 ASSERT_TRUE(test_server_.Start());
6028
6029 TestDelegate d;
6030 const GURL url = test_server_.GetURL("files/308-without-location-header");
6031
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006032 scoped_ptr<URLRequest> request(default_context_.CreateRequest(
6033 url, DEFAULT_PRIORITY, &d, NULL));
Bo Liu5c02ac12014-05-01 10:37:37 -07006034
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006035 request->Start();
Bo Liu5c02ac12014-05-01 10:37:37 -07006036 base::RunLoop().Run();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006037 EXPECT_EQ(URLRequestStatus::SUCCESS, request->status().status());
6038 EXPECT_EQ(OK, request->status().error());
Bo Liu5c02ac12014-05-01 10:37:37 -07006039 EXPECT_EQ(0, d.received_redirect_count());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006040 EXPECT_EQ(308, request->response_headers()->response_code());
Bo Liu5c02ac12014-05-01 10:37:37 -07006041 EXPECT_EQ("This is not a redirect.", d.data_received());
6042}
6043
Ben Murdochc5cede92014-04-10 11:22:14 +01006044TEST_F(URLRequestTestHTTP, Redirect302PreserveReferenceFragment) {
6045 ASSERT_TRUE(test_server_.Start());
6046
6047 GURL original_url(test_server_.GetURL("files/redirect302-to-echo#fragment"));
6048 GURL expected_url(test_server_.GetURL("echo#fragment"));
6049
6050 TestDelegate d;
6051 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006052 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
6053 original_url, DEFAULT_PRIORITY, &d, NULL));
Ben Murdochc5cede92014-04-10 11:22:14 +01006054
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006055 r->Start();
Ben Murdochc5cede92014-04-10 11:22:14 +01006056 base::RunLoop().Run();
6057
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006058 EXPECT_EQ(2U, r->url_chain().size());
6059 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
6060 EXPECT_EQ(OK, r->status().error());
6061 EXPECT_EQ(original_url, r->original_url());
6062 EXPECT_EQ(expected_url, r->url());
Ben Murdochc5cede92014-04-10 11:22:14 +01006063 }
6064}
6065
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01006066TEST_F(URLRequestTestHTTP, RedirectPreserveFirstPartyURL) {
6067 ASSERT_TRUE(test_server_.Start());
6068
6069 GURL url(test_server_.GetURL("files/redirect302-to-echo"));
6070 GURL first_party_url("http://example.com");
6071
6072 TestDelegate d;
6073 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006074 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
6075 url, DEFAULT_PRIORITY, &d, NULL));
6076 r->set_first_party_for_cookies(first_party_url);
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01006077
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006078 r->Start();
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01006079 base::RunLoop().Run();
6080
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006081 EXPECT_EQ(2U, r->url_chain().size());
6082 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
6083 EXPECT_EQ(OK, r->status().error());
6084 EXPECT_EQ(first_party_url, r->first_party_for_cookies());
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01006085 }
6086}
6087
6088TEST_F(URLRequestTestHTTP, RedirectUpdateFirstPartyURL) {
6089 ASSERT_TRUE(test_server_.Start());
6090
6091 GURL url(test_server_.GetURL("files/redirect302-to-echo"));
6092 GURL original_first_party_url("http://example.com");
6093 GURL expected_first_party_url(test_server_.GetURL("echo"));
6094
6095 TestDelegate d;
6096 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006097 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
6098 url, DEFAULT_PRIORITY, &d, NULL));
6099 r->set_first_party_for_cookies(original_first_party_url);
6100 r->set_first_party_url_policy(
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01006101 URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT);
6102
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006103 r->Start();
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01006104 base::RunLoop().Run();
6105
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006106 EXPECT_EQ(2U, r->url_chain().size());
6107 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
6108 EXPECT_EQ(OK, r->status().error());
6109 EXPECT_EQ(expected_first_party_url, r->first_party_for_cookies());
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01006110 }
6111}
6112
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006113TEST_F(URLRequestTestHTTP, InterceptPost302RedirectGet) {
6114 ASSERT_TRUE(test_server_.Start());
6115
6116 const char kData[] = "hello world";
6117
6118 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006119 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
6120 test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d, NULL));
6121 req->set_method("POST");
6122 req->set_upload(make_scoped_ptr(CreateSimpleUploadData(kData)));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006123 HttpRequestHeaders headers;
6124 headers.SetHeader(HttpRequestHeaders::kContentLength,
6125 base::UintToString(arraysize(kData) - 1));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006126 req->SetExtraRequestHeaders(headers);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006127
6128 URLRequestRedirectJob* job = new URLRequestRedirectJob(
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006129 req.get(), &default_network_delegate_, test_server_.GetURL("echo"),
Torne (Richard Coles)a1401312014-03-18 10:20:56 +00006130 URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason");
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006131 AddTestInterceptor()->set_main_intercept_job(job);
6132
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006133 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006134 base::RunLoop().Run();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006135 EXPECT_EQ("GET", req->method());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006136}
6137
6138TEST_F(URLRequestTestHTTP, InterceptPost307RedirectPost) {
6139 ASSERT_TRUE(test_server_.Start());
6140
6141 const char kData[] = "hello world";
6142
6143 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006144 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
6145 test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d, NULL));
6146 req->set_method("POST");
6147 req->set_upload(make_scoped_ptr(CreateSimpleUploadData(kData)));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006148 HttpRequestHeaders headers;
6149 headers.SetHeader(HttpRequestHeaders::kContentLength,
6150 base::UintToString(arraysize(kData) - 1));
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006151 req->SetExtraRequestHeaders(headers);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006152
6153 URLRequestRedirectJob* job = new URLRequestRedirectJob(
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006154 req.get(), &default_network_delegate_, test_server_.GetURL("echo"),
Torne (Richard Coles)a1401312014-03-18 10:20:56 +00006155 URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT,
6156 "Very Good Reason");
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006157 AddTestInterceptor()->set_main_intercept_job(job);
6158
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006159 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006160 base::RunLoop().Run();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006161 EXPECT_EQ("POST", req->method());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006162 EXPECT_EQ(kData, d.data_received());
6163}
6164
6165// Check that default A-L header is sent.
6166TEST_F(URLRequestTestHTTP, DefaultAcceptLanguage) {
6167 ASSERT_TRUE(test_server_.Start());
6168
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00006169 StaticHttpUserAgentSettings settings("en", std::string());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006170 TestNetworkDelegate network_delegate; // Must outlive URLRequests.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006171 TestURLRequestContext context(true);
6172 context.set_network_delegate(&network_delegate);
6173 context.set_http_user_agent_settings(&settings);
6174 context.Init();
6175
6176 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006177 scoped_ptr<URLRequest> req(context.CreateRequest(
6178 test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d,
6179 NULL));
6180 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006181 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006182 EXPECT_EQ("en", d.data_received());
6183}
6184
6185// Check that an empty A-L header is not sent. http://crbug.com/77365.
6186TEST_F(URLRequestTestHTTP, EmptyAcceptLanguage) {
6187 ASSERT_TRUE(test_server_.Start());
6188
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00006189 std::string empty_string; // Avoid most vexing parse on line below.
6190 StaticHttpUserAgentSettings settings(empty_string, empty_string);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006191 TestNetworkDelegate network_delegate; // Must outlive URLRequests.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006192 TestURLRequestContext context(true);
6193 context.set_network_delegate(&network_delegate);
6194 context.Init();
6195 // We override the language after initialization because empty entries
6196 // get overridden by Init().
6197 context.set_http_user_agent_settings(&settings);
6198
6199 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006200 scoped_ptr<URLRequest> req(context.CreateRequest(
6201 test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d,
6202 NULL));
6203 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006204 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006205 EXPECT_EQ("None", d.data_received());
6206}
6207
6208// Check that if request overrides the A-L header, the default is not appended.
6209// See http://crbug.com/20894
6210TEST_F(URLRequestTestHTTP, OverrideAcceptLanguage) {
6211 ASSERT_TRUE(test_server_.Start());
6212
6213 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006214 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
6215 test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d,
6216 NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006217 HttpRequestHeaders headers;
6218 headers.SetHeader(HttpRequestHeaders::kAcceptLanguage, "ru");
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006219 req->SetExtraRequestHeaders(headers);
6220 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006221 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006222 EXPECT_EQ(std::string("ru"), d.data_received());
6223}
6224
6225// Check that default A-E header is sent.
6226TEST_F(URLRequestTestHTTP, DefaultAcceptEncoding) {
6227 ASSERT_TRUE(test_server_.Start());
6228
6229 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006230 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
6231 test_server_.GetURL("echoheader?Accept-Encoding"), DEFAULT_PRIORITY, &d,
6232 NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006233 HttpRequestHeaders headers;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006234 req->SetExtraRequestHeaders(headers);
6235 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006236 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006237 EXPECT_TRUE(ContainsString(d.data_received(), "gzip"));
6238}
6239
6240// Check that if request overrides the A-E header, the default is not appended.
6241// See http://crbug.com/47381
6242TEST_F(URLRequestTestHTTP, OverrideAcceptEncoding) {
6243 ASSERT_TRUE(test_server_.Start());
6244
6245 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006246 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
6247 test_server_.GetURL("echoheader?Accept-Encoding"), DEFAULT_PRIORITY, &d,
6248 NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006249 HttpRequestHeaders headers;
6250 headers.SetHeader(HttpRequestHeaders::kAcceptEncoding, "identity");
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006251 req->SetExtraRequestHeaders(headers);
6252 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006253 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006254 EXPECT_FALSE(ContainsString(d.data_received(), "gzip"));
6255 EXPECT_TRUE(ContainsString(d.data_received(), "identity"));
6256}
6257
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006258// Check that setting the A-C header sends the proper header.
6259TEST_F(URLRequestTestHTTP, SetAcceptCharset) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006260 ASSERT_TRUE(test_server_.Start());
6261
6262 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006263 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
6264 test_server_.GetURL("echoheader?Accept-Charset"), DEFAULT_PRIORITY, &d,
6265 NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006266 HttpRequestHeaders headers;
6267 headers.SetHeader(HttpRequestHeaders::kAcceptCharset, "koi-8r");
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006268 req->SetExtraRequestHeaders(headers);
6269 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006270 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006271 EXPECT_EQ(std::string("koi-8r"), d.data_received());
6272}
6273
6274// Check that default User-Agent header is sent.
6275TEST_F(URLRequestTestHTTP, DefaultUserAgent) {
6276 ASSERT_TRUE(test_server_.Start());
6277
6278 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006279 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
6280 test_server_.GetURL("echoheader?User-Agent"), DEFAULT_PRIORITY, &d,
6281 NULL));
6282 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006283 base::RunLoop().Run();
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006284 EXPECT_EQ(default_context_.http_user_agent_settings()->GetUserAgent(),
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00006285 d.data_received());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006286}
6287
6288// Check that if request overrides the User-Agent header,
6289// the default is not appended.
6290TEST_F(URLRequestTestHTTP, OverrideUserAgent) {
6291 ASSERT_TRUE(test_server_.Start());
6292
6293 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006294 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
6295 test_server_.GetURL("echoheader?User-Agent"), DEFAULT_PRIORITY, &d,
6296 NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006297 HttpRequestHeaders headers;
6298 headers.SetHeader(HttpRequestHeaders::kUserAgent, "Lynx (textmode)");
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006299 req->SetExtraRequestHeaders(headers);
6300 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006301 base::RunLoop().Run();
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00006302 EXPECT_EQ(std::string("Lynx (textmode)"), d.data_received());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006303}
6304
6305// Check that a NULL HttpUserAgentSettings causes the corresponding empty
6306// User-Agent header to be sent but does not send the Accept-Language and
6307// Accept-Charset headers.
6308TEST_F(URLRequestTestHTTP, EmptyHttpUserAgentSettings) {
6309 ASSERT_TRUE(test_server_.Start());
6310
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006311 TestNetworkDelegate network_delegate; // Must outlive URLRequests.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006312 TestURLRequestContext context(true);
6313 context.set_network_delegate(&network_delegate);
6314 context.Init();
6315 // We override the HttpUserAgentSettings after initialization because empty
6316 // entries get overridden by Init().
6317 context.set_http_user_agent_settings(NULL);
6318
6319 struct {
6320 const char* request;
6321 const char* expected_response;
6322 } tests[] = { { "echoheader?Accept-Language", "None" },
6323 { "echoheader?Accept-Charset", "None" },
6324 { "echoheader?User-Agent", "" } };
6325
6326 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); i++) {
6327 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006328 scoped_ptr<URLRequest> req(context.CreateRequest(
6329 test_server_.GetURL(tests[i].request), DEFAULT_PRIORITY, &d, NULL));
6330 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006331 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006332 EXPECT_EQ(tests[i].expected_response, d.data_received())
6333 << " Request = \"" << tests[i].request << "\"";
6334 }
6335}
6336
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006337// Make sure that URLRequest passes on its priority updates to
6338// newly-created jobs after the first one.
6339TEST_F(URLRequestTestHTTP, SetSubsequentJobPriority) {
6340 ASSERT_TRUE(test_server_.Start());
6341
6342 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006343 scoped_ptr<URLRequest> req(default_context_.CreateRequest(
6344 test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d, NULL));
6345 EXPECT_EQ(DEFAULT_PRIORITY, req->priority());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006346
6347 scoped_refptr<URLRequestRedirectJob> redirect_job =
6348 new URLRequestRedirectJob(
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006349 req.get(), &default_network_delegate_, test_server_.GetURL("echo"),
Torne (Richard Coles)a1401312014-03-18 10:20:56 +00006350 URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason");
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01006351 AddTestInterceptor()->set_main_intercept_job(redirect_job.get());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006352
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006353 req->SetPriority(LOW);
6354 req->Start();
6355 EXPECT_TRUE(req->is_pending());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006356
6357 scoped_refptr<URLRequestTestJob> job =
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006358 new URLRequestTestJob(req.get(), &default_network_delegate_);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01006359 AddTestInterceptor()->set_main_intercept_job(job.get());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006360
6361 // Should trigger |job| to be started.
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006362 base::RunLoop().Run();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006363 EXPECT_EQ(LOW, job->priority());
6364}
6365
Torne (Richard Coles)a1401312014-03-18 10:20:56 +00006366// Check that creating a network request while entering/exiting suspend mode
6367// fails as it should. This is the only case where an HttpTransactionFactory
6368// does not return an HttpTransaction.
6369TEST_F(URLRequestTestHTTP, NetworkSuspendTest) {
6370 // Create a new HttpNetworkLayer that thinks it's suspended.
6371 HttpNetworkSession::Params params;
6372 params.host_resolver = default_context_.host_resolver();
6373 params.cert_verifier = default_context_.cert_verifier();
6374 params.transport_security_state = default_context_.transport_security_state();
6375 params.proxy_service = default_context_.proxy_service();
6376 params.ssl_config_service = default_context_.ssl_config_service();
6377 params.http_auth_handler_factory =
6378 default_context_.http_auth_handler_factory();
6379 params.network_delegate = &default_network_delegate_;
6380 params.http_server_properties = default_context_.http_server_properties();
6381 scoped_ptr<HttpNetworkLayer> network_layer(
6382 new HttpNetworkLayer(new HttpNetworkSession(params)));
6383 network_layer->OnSuspend();
6384
6385 HttpCache http_cache(network_layer.release(), default_context_.net_log(),
6386 HttpCache::DefaultBackend::InMemory(0));
6387
6388 TestURLRequestContext context(true);
6389 context.set_http_transaction_factory(&http_cache);
6390 context.Init();
6391
6392 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006393 scoped_ptr<URLRequest> req(context.CreateRequest(
6394 GURL("http://127.0.0.1/"), DEFAULT_PRIORITY, &d, NULL));
6395 req->Start();
Torne (Richard Coles)a1401312014-03-18 10:20:56 +00006396 base::RunLoop().Run();
6397
6398 EXPECT_TRUE(d.request_failed());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006399 EXPECT_EQ(URLRequestStatus::FAILED, req->status().status());
6400 EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, req->status().error());
Torne (Richard Coles)a1401312014-03-18 10:20:56 +00006401}
6402
6403// Check that creating a network request while entering/exiting suspend mode
6404// fails as it should in the case there is no cache. This is the only case
6405// where an HttpTransactionFactory does not return an HttpTransaction.
6406TEST_F(URLRequestTestHTTP, NetworkSuspendTestNoCache) {
6407 // Create a new HttpNetworkLayer that thinks it's suspended.
6408 HttpNetworkSession::Params params;
6409 params.host_resolver = default_context_.host_resolver();
6410 params.cert_verifier = default_context_.cert_verifier();
6411 params.transport_security_state = default_context_.transport_security_state();
6412 params.proxy_service = default_context_.proxy_service();
6413 params.ssl_config_service = default_context_.ssl_config_service();
6414 params.http_auth_handler_factory =
6415 default_context_.http_auth_handler_factory();
6416 params.network_delegate = &default_network_delegate_;
6417 params.http_server_properties = default_context_.http_server_properties();
6418 HttpNetworkLayer network_layer(new HttpNetworkSession(params));
6419 network_layer.OnSuspend();
6420
6421 TestURLRequestContext context(true);
6422 context.set_http_transaction_factory(&network_layer);
6423 context.Init();
6424
6425 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006426 scoped_ptr<URLRequest> req(context.CreateRequest(
6427 GURL("http://127.0.0.1/"), DEFAULT_PRIORITY, &d, NULL));
6428 req->Start();
Torne (Richard Coles)a1401312014-03-18 10:20:56 +00006429 base::RunLoop().Run();
6430
6431 EXPECT_TRUE(d.request_failed());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006432 EXPECT_EQ(URLRequestStatus::FAILED, req->status().status());
6433 EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, req->status().error());
Torne (Richard Coles)a1401312014-03-18 10:20:56 +00006434}
6435
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006436class HTTPSRequestTest : public testing::Test {
6437 public:
6438 HTTPSRequestTest() : default_context_(true) {
6439 default_context_.set_network_delegate(&default_network_delegate_);
6440 default_context_.Init();
6441 }
6442 virtual ~HTTPSRequestTest() {}
6443
6444 protected:
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006445 TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006446 TestURLRequestContext default_context_;
6447};
6448
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006449TEST_F(HTTPSRequestTest, HTTPSGetTest) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01006450 SpawnedTestServer test_server(
6451 SpawnedTestServer::TYPE_HTTPS,
6452 SpawnedTestServer::kLocalhost,
6453 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006454 ASSERT_TRUE(test_server.Start());
6455
6456 TestDelegate d;
6457 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006458 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
6459 test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
6460 r->Start();
6461 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006462
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006463 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006464
6465 EXPECT_EQ(1, d.response_started_count());
6466 EXPECT_FALSE(d.received_data_before_response());
6467 EXPECT_NE(0, d.bytes_received());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006468 CheckSSLInfo(r->ssl_info());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006469 EXPECT_EQ(test_server.host_port_pair().host(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006470 r->GetSocketAddress().host());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006471 EXPECT_EQ(test_server.host_port_pair().port(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006472 r->GetSocketAddress().port());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006473 }
6474}
6475
6476TEST_F(HTTPSRequestTest, HTTPSMismatchedTest) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01006477 SpawnedTestServer::SSLOptions ssl_options(
6478 SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME);
6479 SpawnedTestServer test_server(
6480 SpawnedTestServer::TYPE_HTTPS,
6481 ssl_options,
6482 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006483 ASSERT_TRUE(test_server.Start());
6484
6485 bool err_allowed = true;
6486 for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) {
6487 TestDelegate d;
6488 {
6489 d.set_allow_certificate_errors(err_allowed);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006490 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
6491 test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006492
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006493 r->Start();
6494 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006495
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006496 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006497
6498 EXPECT_EQ(1, d.response_started_count());
6499 EXPECT_FALSE(d.received_data_before_response());
6500 EXPECT_TRUE(d.have_certificate_errors());
6501 if (err_allowed) {
6502 EXPECT_NE(0, d.bytes_received());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006503 CheckSSLInfo(r->ssl_info());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006504 } else {
6505 EXPECT_EQ(0, d.bytes_received());
6506 }
6507 }
6508 }
6509}
6510
6511TEST_F(HTTPSRequestTest, HTTPSExpiredTest) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01006512 SpawnedTestServer::SSLOptions ssl_options(
6513 SpawnedTestServer::SSLOptions::CERT_EXPIRED);
6514 SpawnedTestServer test_server(
6515 SpawnedTestServer::TYPE_HTTPS,
6516 ssl_options,
6517 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006518 ASSERT_TRUE(test_server.Start());
6519
6520 // Iterate from false to true, just so that we do the opposite of the
6521 // previous test in order to increase test coverage.
6522 bool err_allowed = false;
6523 for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) {
6524 TestDelegate d;
6525 {
6526 d.set_allow_certificate_errors(err_allowed);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006527 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
6528 test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006529
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006530 r->Start();
6531 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006532
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006533 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006534
6535 EXPECT_EQ(1, d.response_started_count());
6536 EXPECT_FALSE(d.received_data_before_response());
6537 EXPECT_TRUE(d.have_certificate_errors());
6538 if (err_allowed) {
6539 EXPECT_NE(0, d.bytes_received());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006540 CheckSSLInfo(r->ssl_info());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006541 } else {
6542 EXPECT_EQ(0, d.bytes_received());
6543 }
6544 }
6545 }
6546}
6547
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006548// This tests that a load of www.google.com with a certificate error sets
6549// the |certificate_errors_are_fatal| flag correctly. This flag will cause
6550// the interstitial to be fatal.
6551TEST_F(HTTPSRequestTest, HTTPSPreloadedHSTSTest) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01006552 SpawnedTestServer::SSLOptions ssl_options(
6553 SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME);
6554 SpawnedTestServer test_server(
6555 SpawnedTestServer::TYPE_HTTPS,
6556 ssl_options,
6557 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006558 ASSERT_TRUE(test_server.Start());
6559
6560 // We require that the URL be www.google.com in order to pick up the
6561 // preloaded HSTS entries in the TransportSecurityState. This means that we
6562 // have to use a MockHostResolver in order to direct www.google.com to the
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006563 // testserver. By default, MockHostResolver maps all hosts to 127.0.0.1.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006564
6565 MockHostResolver host_resolver;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006566 TestNetworkDelegate network_delegate; // Must outlive URLRequest.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006567 TestURLRequestContext context(true);
6568 context.set_network_delegate(&network_delegate);
6569 context.set_host_resolver(&host_resolver);
6570 TransportSecurityState transport_security_state;
6571 context.set_transport_security_state(&transport_security_state);
6572 context.Init();
6573
6574 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006575 scoped_ptr<URLRequest> r(context.CreateRequest(
6576 GURL(base::StringPrintf("https://www.google.com:%d",
6577 test_server.host_port_pair().port())),
6578 DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006579
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006580 r->Start();
6581 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006582
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006583 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006584
6585 EXPECT_EQ(1, d.response_started_count());
6586 EXPECT_FALSE(d.received_data_before_response());
6587 EXPECT_TRUE(d.have_certificate_errors());
6588 EXPECT_TRUE(d.certificate_errors_are_fatal());
6589}
6590
6591// This tests that cached HTTPS page loads do not cause any updates to the
6592// TransportSecurityState.
6593TEST_F(HTTPSRequestTest, HTTPSErrorsNoClobberTSSTest) {
6594 // The actual problem -- CERT_MISMATCHED_NAME in this case -- doesn't
6595 // matter. It just has to be any error.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01006596 SpawnedTestServer::SSLOptions ssl_options(
6597 SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME);
6598 SpawnedTestServer test_server(
6599 SpawnedTestServer::TYPE_HTTPS,
6600 ssl_options,
6601 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006602 ASSERT_TRUE(test_server.Start());
6603
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01006604 // We require that the URL be www.google.com in order to pick up the static
6605 // and dynamic STS and PKP entries in the TransportSecurityState. This means
6606 // that we have to use a MockHostResolver in order to direct www.google.com to
6607 // the testserver. By default, MockHostResolver maps all hosts to 127.0.0.1.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006608
6609 MockHostResolver host_resolver;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006610 TestNetworkDelegate network_delegate; // Must outlive URLRequest.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006611 TestURLRequestContext context(true);
6612 context.set_network_delegate(&network_delegate);
6613 context.set_host_resolver(&host_resolver);
6614 TransportSecurityState transport_security_state;
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01006615
6616 TransportSecurityState::DomainState static_domain_state;
6617 EXPECT_TRUE(transport_security_state.GetStaticDomainState(
6618 "www.google.com", true, &static_domain_state));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006619 context.set_transport_security_state(&transport_security_state);
6620 context.Init();
6621
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01006622 TransportSecurityState::DomainState dynamic_domain_state;
6623 EXPECT_FALSE(transport_security_state.GetDynamicDomainState(
6624 "www.google.com", &dynamic_domain_state));
6625
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006626 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006627 scoped_ptr<URLRequest> r(context.CreateRequest(
6628 GURL(base::StringPrintf("https://www.google.com:%d",
6629 test_server.host_port_pair().port())),
6630 DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006631
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006632 r->Start();
6633 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006634
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006635 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006636
6637 EXPECT_EQ(1, d.response_started_count());
6638 EXPECT_FALSE(d.received_data_before_response());
6639 EXPECT_TRUE(d.have_certificate_errors());
6640 EXPECT_TRUE(d.certificate_errors_are_fatal());
6641
Torne (Richard Coles)010d83a2014-05-14 12:12:37 +01006642 // Get a fresh copy of the states, and check that they haven't changed.
6643 TransportSecurityState::DomainState new_static_domain_state;
6644 EXPECT_TRUE(transport_security_state.GetStaticDomainState(
6645 "www.google.com", true, &new_static_domain_state));
6646 TransportSecurityState::DomainState new_dynamic_domain_state;
6647 EXPECT_FALSE(transport_security_state.GetDynamicDomainState(
6648 "www.google.com", &new_dynamic_domain_state));
6649
6650 EXPECT_EQ(new_static_domain_state.sts.upgrade_mode,
6651 static_domain_state.sts.upgrade_mode);
6652 EXPECT_EQ(new_static_domain_state.sts.include_subdomains,
6653 static_domain_state.sts.include_subdomains);
6654 EXPECT_EQ(new_static_domain_state.pkp.include_subdomains,
6655 static_domain_state.pkp.include_subdomains);
6656 EXPECT_TRUE(FingerprintsEqual(new_static_domain_state.pkp.spki_hashes,
6657 static_domain_state.pkp.spki_hashes));
6658 EXPECT_TRUE(FingerprintsEqual(new_static_domain_state.pkp.bad_spki_hashes,
6659 static_domain_state.pkp.bad_spki_hashes));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006660}
6661
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006662// Make sure HSTS preserves a POST request's method and body.
6663TEST_F(HTTPSRequestTest, HSTSPreservesPosts) {
6664 static const char kData[] = "hello world";
6665
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01006666 SpawnedTestServer::SSLOptions ssl_options(
6667 SpawnedTestServer::SSLOptions::CERT_OK);
6668 SpawnedTestServer test_server(
6669 SpawnedTestServer::TYPE_HTTPS,
6670 ssl_options,
6671 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006672 ASSERT_TRUE(test_server.Start());
6673
6674
6675 // Per spec, TransportSecurityState expects a domain name, rather than an IP
6676 // address, so a MockHostResolver is needed to redirect www.somewhere.com to
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01006677 // the SpawnedTestServer. By default, MockHostResolver maps all hosts
6678 // to 127.0.0.1.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006679 MockHostResolver host_resolver;
6680
6681 // Force https for www.somewhere.com.
6682 TransportSecurityState transport_security_state;
6683 base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1000);
6684 bool include_subdomains = false;
6685 transport_security_state.AddHSTS("www.somewhere.com", expiry,
6686 include_subdomains);
6687
6688 TestNetworkDelegate network_delegate; // Must outlive URLRequest.
6689
6690 TestURLRequestContext context(true);
6691 context.set_host_resolver(&host_resolver);
6692 context.set_transport_security_state(&transport_security_state);
6693 context.set_network_delegate(&network_delegate);
6694 context.Init();
6695
6696 TestDelegate d;
6697 // Navigating to https://www.somewhere.com instead of https://127.0.0.1 will
6698 // cause a certificate error. Ignore the error.
6699 d.set_allow_certificate_errors(true);
6700
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006701 scoped_ptr<URLRequest> req(context.CreateRequest(
6702 GURL(base::StringPrintf("http://www.somewhere.com:%d/echo",
6703 test_server.host_port_pair().port())),
6704 DEFAULT_PRIORITY, &d, NULL));
6705 req->set_method("POST");
6706 req->set_upload(make_scoped_ptr(CreateSimpleUploadData(kData)));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006707
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006708 req->Start();
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006709 base::RunLoop().Run();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006710
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006711 EXPECT_EQ("https", req->url().scheme());
6712 EXPECT_EQ("POST", req->method());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006713 EXPECT_EQ(kData, d.data_received());
Ben Murdocheb525c52013-07-10 11:40:50 +01006714
6715 LoadTimingInfo load_timing_info;
6716 network_delegate.GetLoadTimingInfoBeforeRedirect(&load_timing_info);
6717 // LoadTimingInfo of HSTS redirects is similar to that of network cache hits
6718 TestLoadTimingCacheHitNoNetwork(load_timing_info);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006719}
6720
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006721namespace {
6722
6723class SSLClientAuthTestDelegate : public TestDelegate {
6724 public:
6725 SSLClientAuthTestDelegate() : on_certificate_requested_count_(0) {
6726 }
6727 virtual void OnCertificateRequested(
6728 URLRequest* request,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006729 SSLCertRequestInfo* cert_request_info) OVERRIDE {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006730 on_certificate_requested_count_++;
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01006731 base::MessageLoop::current()->Quit();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006732 }
6733 int on_certificate_requested_count() {
6734 return on_certificate_requested_count_;
6735 }
6736 private:
6737 int on_certificate_requested_count_;
6738};
6739
6740} // namespace
6741
6742// TODO(davidben): Test the rest of the code. Specifically,
6743// - Filtering which certificates to select.
6744// - Sending a certificate back.
6745// - Getting a certificate request in an SSL renegotiation sending the
6746// HTTP request.
6747TEST_F(HTTPSRequestTest, ClientAuthTest) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01006748 SpawnedTestServer::SSLOptions ssl_options;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006749 ssl_options.request_client_certificate = true;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01006750 SpawnedTestServer test_server(
6751 SpawnedTestServer::TYPE_HTTPS,
6752 ssl_options,
6753 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006754 ASSERT_TRUE(test_server.Start());
6755
6756 SSLClientAuthTestDelegate d;
6757 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006758 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
6759 test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006760
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006761 r->Start();
6762 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006763
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006764 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006765
6766 EXPECT_EQ(1, d.on_certificate_requested_count());
6767 EXPECT_FALSE(d.received_data_before_response());
6768 EXPECT_EQ(0, d.bytes_received());
6769
6770 // Send no certificate.
6771 // TODO(davidben): Get temporary client cert import (with keys) working on
6772 // all platforms so we can test sending a cert as well.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006773 r->ContinueWithCertificate(NULL);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006774
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006775 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006776
6777 EXPECT_EQ(1, d.response_started_count());
6778 EXPECT_FALSE(d.received_data_before_response());
6779 EXPECT_NE(0, d.bytes_received());
6780 }
6781}
6782
6783TEST_F(HTTPSRequestTest, ResumeTest) {
6784 // Test that we attempt a session resume when making two connections to the
6785 // same host.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01006786 SpawnedTestServer::SSLOptions ssl_options;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006787 ssl_options.record_resume = true;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01006788 SpawnedTestServer test_server(
6789 SpawnedTestServer::TYPE_HTTPS,
6790 ssl_options,
6791 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006792 ASSERT_TRUE(test_server.Start());
6793
6794 SSLClientSocket::ClearSessionCache();
6795
6796 {
6797 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006798 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
6799 test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006800
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006801 r->Start();
6802 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006803
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006804 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006805
6806 EXPECT_EQ(1, d.response_started_count());
6807 }
6808
6809 reinterpret_cast<HttpCache*>(default_context_.http_transaction_factory())->
6810 CloseAllConnections();
6811
6812 {
6813 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006814 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
6815 test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006816
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006817 r->Start();
6818 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006819
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006820 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006821
6822 // The response will look like;
6823 // insert abc
6824 // lookup abc
6825 // insert xyz
6826 //
6827 // With a newline at the end which makes the split think that there are
6828 // four lines.
6829
6830 EXPECT_EQ(1, d.response_started_count());
6831 std::vector<std::string> lines;
6832 base::SplitString(d.data_received(), '\n', &lines);
6833 ASSERT_EQ(4u, lines.size()) << d.data_received();
6834
6835 std::string session_id;
6836
6837 for (size_t i = 0; i < 2; i++) {
6838 std::vector<std::string> parts;
6839 base::SplitString(lines[i], '\t', &parts);
6840 ASSERT_EQ(2u, parts.size());
6841 if (i == 0) {
6842 EXPECT_EQ("insert", parts[0]);
6843 session_id = parts[1];
6844 } else {
6845 EXPECT_EQ("lookup", parts[0]);
6846 EXPECT_EQ(session_id, parts[1]);
6847 }
6848 }
6849 }
6850}
6851
6852TEST_F(HTTPSRequestTest, SSLSessionCacheShardTest) {
6853 // Test that sessions aren't resumed when the value of ssl_session_cache_shard
6854 // differs.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01006855 SpawnedTestServer::SSLOptions ssl_options;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006856 ssl_options.record_resume = true;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01006857 SpawnedTestServer test_server(
6858 SpawnedTestServer::TYPE_HTTPS,
6859 ssl_options,
6860 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006861 ASSERT_TRUE(test_server.Start());
6862
6863 SSLClientSocket::ClearSessionCache();
6864
6865 {
6866 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006867 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
6868 test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006869
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006870 r->Start();
6871 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006872
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006873 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006874
6875 EXPECT_EQ(1, d.response_started_count());
6876 }
6877
6878 // Now create a new HttpCache with a different ssl_session_cache_shard value.
6879 HttpNetworkSession::Params params;
6880 params.host_resolver = default_context_.host_resolver();
6881 params.cert_verifier = default_context_.cert_verifier();
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +01006882 params.transport_security_state = default_context_.transport_security_state();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006883 params.proxy_service = default_context_.proxy_service();
6884 params.ssl_config_service = default_context_.ssl_config_service();
6885 params.http_auth_handler_factory =
6886 default_context_.http_auth_handler_factory();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00006887 params.network_delegate = &default_network_delegate_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006888 params.http_server_properties = default_context_.http_server_properties();
6889 params.ssl_session_cache_shard = "alternate";
6890
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01006891 scoped_ptr<HttpCache> cache(new HttpCache(
6892 new HttpNetworkSession(params),
6893 HttpCache::DefaultBackend::InMemory(0)));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006894
6895 default_context_.set_http_transaction_factory(cache.get());
6896
6897 {
6898 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006899 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
6900 test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006901
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006902 r->Start();
6903 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006904
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01006905 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00006906
6907 // The response will look like;
6908 // insert abc
6909 // insert xyz
6910 //
6911 // With a newline at the end which makes the split think that there are
6912 // three lines.
6913
6914 EXPECT_EQ(1, d.response_started_count());
6915 std::vector<std::string> lines;
6916 base::SplitString(d.data_received(), '\n', &lines);
6917 ASSERT_EQ(3u, lines.size());
6918
6919 std::string session_id;
6920 for (size_t i = 0; i < 2; i++) {
6921 std::vector<std::string> parts;
6922 base::SplitString(lines[i], '\t', &parts);
6923 ASSERT_EQ(2u, parts.size());
6924 EXPECT_EQ("insert", parts[0]);
6925 if (i == 0) {
6926 session_id = parts[1];
6927 } else {
6928 EXPECT_NE(session_id, parts[1]);
6929 }
6930 }
6931 }
6932}
6933
Ben Murdoch116680a2014-07-20 18:25:52 -07006934class HTTPSFallbackTest : public testing::Test {
6935 public:
6936 HTTPSFallbackTest() : context_(true) {
6937 context_.Init();
6938 delegate_.set_allow_certificate_errors(true);
6939 }
6940 virtual ~HTTPSFallbackTest() {}
6941
6942 protected:
6943 void DoFallbackTest(const SpawnedTestServer::SSLOptions& ssl_options) {
6944 DCHECK(!request_);
6945 SpawnedTestServer test_server(
6946 SpawnedTestServer::TYPE_HTTPS,
6947 ssl_options,
6948 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
6949 ASSERT_TRUE(test_server.Start());
6950
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01006951 request_ = context_.CreateRequest(
6952 test_server.GetURL(std::string()), DEFAULT_PRIORITY, &delegate_, NULL);
Ben Murdoch116680a2014-07-20 18:25:52 -07006953 request_->Start();
6954
6955 base::RunLoop().Run();
6956 }
6957
6958 void ExpectConnection(int version) {
6959 EXPECT_EQ(1, delegate_.response_started_count());
6960 EXPECT_NE(0, delegate_.bytes_received());
6961 EXPECT_EQ(version, SSLConnectionStatusToVersion(
6962 request_->ssl_info().connection_status));
6963 EXPECT_TRUE(request_->ssl_info().connection_status &
6964 SSL_CONNECTION_VERSION_FALLBACK);
6965 }
6966
6967 void ExpectFailure(int error) {
6968 EXPECT_EQ(1, delegate_.response_started_count());
6969 EXPECT_FALSE(request_->status().is_success());
6970 EXPECT_EQ(URLRequestStatus::FAILED, request_->status().status());
6971 EXPECT_EQ(error, request_->status().error());
6972 }
6973
6974 private:
6975 TestDelegate delegate_;
6976 TestURLRequestContext context_;
6977 scoped_ptr<URLRequest> request_;
6978};
6979
6980// Tests TLSv1.1 -> TLSv1 fallback. Verifies that we don't fall back more
6981// than necessary.
6982TEST_F(HTTPSFallbackTest, TLSv1Fallback) {
6983 SpawnedTestServer::SSLOptions ssl_options(
6984 SpawnedTestServer::SSLOptions::CERT_OK);
6985 ssl_options.tls_intolerant =
6986 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1;
6987
6988 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options));
6989 ExpectConnection(SSL_CONNECTION_VERSION_TLS1);
6990}
6991
6992// This test is disabled on Android because the remote test server doesn't cause
6993// a TCP reset.
6994#if !defined(OS_ANDROID)
6995// Tests fallback to TLS 1.0 on connection reset.
6996TEST_F(HTTPSFallbackTest, TLSv1FallbackReset) {
6997 SpawnedTestServer::SSLOptions ssl_options(
6998 SpawnedTestServer::SSLOptions::CERT_OK);
6999 ssl_options.tls_intolerant =
7000 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1;
7001 ssl_options.tls_intolerance_type =
7002 SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_RESET;
7003
7004 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options));
7005 ExpectConnection(SSL_CONNECTION_VERSION_TLS1);
7006}
7007#endif // !OS_ANDROID
7008
7009// Tests that we don't fallback on handshake failure with servers that implement
7010// TLS_FALLBACK_SCSV. Also ensure that the original error code is reported.
Ben Murdoch116680a2014-07-20 18:25:52 -07007011TEST_F(HTTPSFallbackTest, FallbackSCSV) {
Ben Murdoch116680a2014-07-20 18:25:52 -07007012 SpawnedTestServer::SSLOptions ssl_options(
7013 SpawnedTestServer::SSLOptions::CERT_OK);
7014 // Configure HTTPS server to be intolerant of TLS >= 1.0 in order to trigger
7015 // a version fallback.
7016 ssl_options.tls_intolerant =
7017 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL;
7018 // Have the server process TLS_FALLBACK_SCSV so that version fallback
7019 // connections are rejected.
7020 ssl_options.fallback_scsv_enabled = true;
7021
7022 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options));
7023
7024 // ERR_SSL_VERSION_OR_CIPHER_MISMATCH is how the server simulates version
7025 // intolerance. If the fallback SCSV is processed when the original error
7026 // that caused the fallback should be returned, which should be
7027 // ERR_SSL_VERSION_OR_CIPHER_MISMATCH.
7028 ExpectFailure(ERR_SSL_VERSION_OR_CIPHER_MISMATCH);
7029}
7030
7031// Tests that we don't fallback on connection closed with servers that implement
7032// TLS_FALLBACK_SCSV. Also ensure that the original error code is reported.
Ben Murdoch116680a2014-07-20 18:25:52 -07007033TEST_F(HTTPSFallbackTest, FallbackSCSVClosed) {
Ben Murdoch116680a2014-07-20 18:25:52 -07007034 SpawnedTestServer::SSLOptions ssl_options(
7035 SpawnedTestServer::SSLOptions::CERT_OK);
7036 // Configure HTTPS server to be intolerant of TLS >= 1.0 in order to trigger
7037 // a version fallback.
7038 ssl_options.tls_intolerant =
7039 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL;
7040 ssl_options.tls_intolerance_type =
7041 SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_CLOSE;
7042 // Have the server process TLS_FALLBACK_SCSV so that version fallback
7043 // connections are rejected.
7044 ssl_options.fallback_scsv_enabled = true;
7045
7046 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options));
7047
7048 // The original error should be replayed on rejected fallback.
7049 ExpectFailure(ERR_CONNECTION_CLOSED);
7050}
7051
7052// Tests that the SSLv3 fallback triggers on alert.
7053TEST_F(HTTPSFallbackTest, SSLv3Fallback) {
7054 SpawnedTestServer::SSLOptions ssl_options(
7055 SpawnedTestServer::SSLOptions::CERT_OK);
7056 ssl_options.tls_intolerant =
7057 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL;
7058
7059 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options));
7060 ExpectConnection(SSL_CONNECTION_VERSION_SSL3);
7061}
7062
7063// Tests that the SSLv3 fallback triggers on closed connections.
7064TEST_F(HTTPSFallbackTest, SSLv3FallbackClosed) {
7065 SpawnedTestServer::SSLOptions ssl_options(
7066 SpawnedTestServer::SSLOptions::CERT_OK);
7067 ssl_options.tls_intolerant =
7068 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL;
7069 ssl_options.tls_intolerance_type =
7070 SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_CLOSE;
7071
7072 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options));
7073 ExpectConnection(SSL_CONNECTION_VERSION_SSL3);
7074}
7075
7076// This test is disabled on Android because the remote test server doesn't cause
7077// a TCP reset.
7078#if !defined(OS_ANDROID)
7079// Tests that a reset connection does not fallback down to SSL3.
7080TEST_F(HTTPSFallbackTest, SSLv3NoFallbackReset) {
7081 SpawnedTestServer::SSLOptions ssl_options(
7082 SpawnedTestServer::SSLOptions::CERT_OK);
7083 ssl_options.tls_intolerant =
7084 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL;
7085 ssl_options.tls_intolerance_type =
7086 SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_RESET;
7087
7088 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options));
7089 ExpectFailure(ERR_CONNECTION_RESET);
7090}
7091#endif // !OS_ANDROID
7092
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00007093class HTTPSSessionTest : public testing::Test {
7094 public:
7095 HTTPSSessionTest() : default_context_(true) {
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01007096 cert_verifier_.set_default_result(OK);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00007097
7098 default_context_.set_network_delegate(&default_network_delegate_);
7099 default_context_.set_cert_verifier(&cert_verifier_);
7100 default_context_.Init();
7101 }
7102 virtual ~HTTPSSessionTest() {}
7103
7104 protected:
7105 MockCertVerifier cert_verifier_;
7106 TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest.
7107 TestURLRequestContext default_context_;
7108};
7109
7110// Tests that session resumption is not attempted if an invalid certificate
7111// is presented.
7112TEST_F(HTTPSSessionTest, DontResumeSessionsForInvalidCertificates) {
7113 SpawnedTestServer::SSLOptions ssl_options;
7114 ssl_options.record_resume = true;
7115 SpawnedTestServer test_server(
7116 SpawnedTestServer::TYPE_HTTPS,
7117 ssl_options,
7118 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
7119 ASSERT_TRUE(test_server.Start());
7120
7121 SSLClientSocket::ClearSessionCache();
7122
7123 // Simulate the certificate being expired and attempt a connection.
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01007124 cert_verifier_.set_default_result(ERR_CERT_DATE_INVALID);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00007125 {
7126 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007127 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
7128 test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00007129
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007130 r->Start();
7131 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00007132
7133 base::RunLoop().Run();
7134
7135 EXPECT_EQ(1, d.response_started_count());
7136 }
7137
7138 reinterpret_cast<HttpCache*>(default_context_.http_transaction_factory())->
7139 CloseAllConnections();
7140
7141 // Now change the certificate to be acceptable (so that the response is
7142 // loaded), and ensure that no session id is presented to the peer.
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01007143 cert_verifier_.set_default_result(OK);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00007144 {
7145 TestDelegate d;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007146 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
7147 test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL));
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00007148
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007149 r->Start();
7150 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00007151
7152 base::RunLoop().Run();
7153
7154 // The response will look like;
7155 // insert abc
7156 // insert xyz
7157 //
7158 // With a newline at the end which makes the split think that there are
7159 // three lines.
7160 //
7161 // If a session was presented (eg: a bug), then the response would look
7162 // like;
7163 // insert abc
7164 // lookup abc
7165 // insert xyz
7166
7167 EXPECT_EQ(1, d.response_started_count());
7168 std::vector<std::string> lines;
7169 base::SplitString(d.data_received(), '\n', &lines);
7170 ASSERT_EQ(3u, lines.size()) << d.data_received();
7171
7172 std::string session_id;
7173 for (size_t i = 0; i < 2; i++) {
7174 std::vector<std::string> parts;
7175 base::SplitString(lines[i], '\t', &parts);
7176 ASSERT_EQ(2u, parts.size());
7177 EXPECT_EQ("insert", parts[0]);
7178 if (i == 0) {
7179 session_id = parts[1];
7180 } else {
7181 EXPECT_NE(session_id, parts[1]);
7182 }
7183 }
7184 }
7185}
7186
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007187class TestSSLConfigService : public SSLConfigService {
7188 public:
Ben Murdoch558790d2013-07-30 15:19:42 +01007189 TestSSLConfigService(bool ev_enabled,
7190 bool online_rev_checking,
7191 bool rev_checking_required_local_anchors)
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007192 : ev_enabled_(ev_enabled),
Ben Murdoch558790d2013-07-30 15:19:42 +01007193 online_rev_checking_(online_rev_checking),
7194 rev_checking_required_local_anchors_(
7195 rev_checking_required_local_anchors) {}
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007196
7197 // SSLConfigService:
7198 virtual void GetSSLConfig(SSLConfig* config) OVERRIDE {
7199 *config = SSLConfig();
7200 config->rev_checking_enabled = online_rev_checking_;
7201 config->verify_ev_cert = ev_enabled_;
Ben Murdoch558790d2013-07-30 15:19:42 +01007202 config->rev_checking_required_local_anchors =
7203 rev_checking_required_local_anchors_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007204 }
7205
7206 protected:
7207 virtual ~TestSSLConfigService() {}
7208
7209 private:
7210 const bool ev_enabled_;
7211 const bool online_rev_checking_;
Ben Murdoch558790d2013-07-30 15:19:42 +01007212 const bool rev_checking_required_local_anchors_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007213};
7214
7215// This the fingerprint of the "Testing CA" certificate used by the testserver.
7216// See net/data/ssl/certificates/ocsp-test-root.pem.
7217static const SHA1HashValue kOCSPTestCertFingerprint =
7218 { { 0xf1, 0xad, 0xf6, 0xce, 0x42, 0xac, 0xe7, 0xb4, 0xf4, 0x24,
7219 0xdb, 0x1a, 0xf7, 0xa0, 0x9f, 0x09, 0xa1, 0xea, 0xf1, 0x5c } };
7220
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01007221// This is the SHA256, SPKI hash of the "Testing CA" certificate used by the
7222// testserver.
7223static const SHA256HashValue kOCSPTestCertSPKI = { {
7224 0xee, 0xe6, 0x51, 0x2d, 0x4c, 0xfa, 0xf7, 0x3e,
7225 0x6c, 0xd8, 0xca, 0x67, 0xed, 0xb5, 0x5d, 0x49,
7226 0x76, 0xe1, 0x52, 0xa7, 0x6e, 0x0e, 0xa0, 0x74,
7227 0x09, 0x75, 0xe6, 0x23, 0x24, 0xbd, 0x1b, 0x28,
7228} };
7229
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007230// This is the policy OID contained in the certificates that testserver
7231// generates.
7232static const char kOCSPTestCertPolicy[] = "1.3.6.1.4.1.11129.2.4.1";
7233
7234class HTTPSOCSPTest : public HTTPSRequestTest {
7235 public:
7236 HTTPSOCSPTest()
7237 : context_(true),
7238 ev_test_policy_(
7239 new ScopedTestEVPolicy(EVRootCAMetadata::GetInstance(),
7240 kOCSPTestCertFingerprint,
7241 kOCSPTestCertPolicy)) {
7242 }
7243
7244 virtual void SetUp() OVERRIDE {
7245 SetupContext(&context_);
7246 context_.Init();
7247
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +01007248 scoped_refptr<X509Certificate> root_cert =
Ben Murdoch558790d2013-07-30 15:19:42 +01007249 ImportCertFromFile(GetTestCertsDirectory(), "ocsp-test-root.pem");
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007250 CHECK_NE(static_cast<X509Certificate*>(NULL), root_cert);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01007251 test_root_.reset(new ScopedTestRoot(root_cert.get()));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007252
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007253#if defined(USE_NSS) || defined(OS_IOS)
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007254 SetURLRequestContextForNSSHttpIO(&context_);
7255 EnsureNSSHttpIOInit();
7256#endif
7257 }
7258
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007259 void DoConnection(const SpawnedTestServer::SSLOptions& ssl_options,
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007260 CertStatus* out_cert_status) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007261 // We always overwrite out_cert_status.
7262 *out_cert_status = 0;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007263 SpawnedTestServer test_server(
7264 SpawnedTestServer::TYPE_HTTPS,
7265 ssl_options,
7266 base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007267 ASSERT_TRUE(test_server.Start());
7268
7269 TestDelegate d;
7270 d.set_allow_certificate_errors(true);
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007271 scoped_ptr<URLRequest> r(context_.CreateRequest(
7272 test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL));
7273 r->Start();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007274
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01007275 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007276
7277 EXPECT_EQ(1, d.response_started_count());
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007278 *out_cert_status = r->ssl_info().cert_status;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007279 }
7280
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007281 virtual ~HTTPSOCSPTest() {
7282#if defined(USE_NSS) || defined(OS_IOS)
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007283 ShutdownNSSHttpIO();
7284#endif
7285 }
7286
7287 protected:
7288 // SetupContext configures the URLRequestContext that will be used for making
7289 // connetions to testserver. This can be overridden in test subclasses for
7290 // different behaviour.
7291 virtual void SetupContext(URLRequestContext* context) {
7292 context->set_ssl_config_service(
7293 new TestSSLConfigService(true /* check for EV */,
Ben Murdoch558790d2013-07-30 15:19:42 +01007294 true /* online revocation checking */,
7295 false /* require rev. checking for local
7296 anchors */));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007297 }
7298
7299 scoped_ptr<ScopedTestRoot> test_root_;
7300 TestURLRequestContext context_;
7301 scoped_ptr<ScopedTestEVPolicy> ev_test_policy_;
7302};
7303
7304static CertStatus ExpectedCertStatusForFailedOnlineRevocationCheck() {
7305#if defined(OS_WIN)
7306 // Windows can return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION but we don't
7307 // have that ability on other platforms.
7308 return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
7309#else
7310 return 0;
7311#endif
7312}
7313
Ben Murdoch558790d2013-07-30 15:19:42 +01007314// SystemSupportsHardFailRevocationChecking returns true iff the current
7315// operating system supports revocation checking and can distinguish between
7316// situations where a given certificate lacks any revocation information (eg:
7317// no CRLDistributionPoints and no OCSP Responder AuthorityInfoAccess) and when
7318// revocation information cannot be obtained (eg: the CRL was unreachable).
7319// If it does not, then tests which rely on 'hard fail' behaviour should be
7320// skipped.
7321static bool SystemSupportsHardFailRevocationChecking() {
7322#if defined(OS_WIN) || defined(USE_NSS) || defined(OS_IOS)
7323 return true;
7324#else
7325 return false;
7326#endif
7327}
7328
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007329// SystemUsesChromiumEVMetadata returns true iff the current operating system
7330// uses Chromium's EV metadata (i.e. EVRootCAMetadata). If it does not, then
7331// several tests are effected because our testing EV certificate won't be
7332// recognised as EV.
7333static bool SystemUsesChromiumEVMetadata() {
Ben Murdocheffb81e2014-03-31 11:51:25 +01007334#if defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007335 // http://crbug.com/117478 - OpenSSL does not support EV validation.
7336 return false;
Ben Murdocheffb81e2014-03-31 11:51:25 +01007337#elif (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_ANDROID)
7338 // On OS X and Android, we use the system to tell us whether a certificate is
7339 // EV or not and the system won't recognise our testing root.
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007340 return false;
7341#else
7342 return true;
7343#endif
7344}
7345
7346static bool SystemSupportsOCSP() {
7347#if defined(USE_OPENSSL)
7348 // http://crbug.com/117478 - OpenSSL does not support OCSP.
7349 return false;
7350#elif defined(OS_WIN)
7351 return base::win::GetVersion() >= base::win::VERSION_VISTA;
7352#elif defined(OS_ANDROID)
7353 // TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported.
7354 return false;
7355#else
7356 return true;
7357#endif
7358}
7359
7360TEST_F(HTTPSOCSPTest, Valid) {
7361 if (!SystemSupportsOCSP()) {
7362 LOG(WARNING) << "Skipping test because system doesn't support OCSP";
7363 return;
7364 }
7365
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007366 SpawnedTestServer::SSLOptions ssl_options(
7367 SpawnedTestServer::SSLOptions::CERT_AUTO);
7368 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007369
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007370 CertStatus cert_status;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007371 DoConnection(ssl_options, &cert_status);
7372
7373 EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);
7374
7375 EXPECT_EQ(SystemUsesChromiumEVMetadata(),
7376 static_cast<bool>(cert_status & CERT_STATUS_IS_EV));
7377
7378 EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
7379}
7380
7381TEST_F(HTTPSOCSPTest, Revoked) {
7382 if (!SystemSupportsOCSP()) {
7383 LOG(WARNING) << "Skipping test because system doesn't support OCSP";
7384 return;
7385 }
7386
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007387 SpawnedTestServer::SSLOptions ssl_options(
7388 SpawnedTestServer::SSLOptions::CERT_AUTO);
7389 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007390
7391 CertStatus cert_status;
7392 DoConnection(ssl_options, &cert_status);
7393
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007394#if !(defined(OS_MACOSX) && !defined(OS_IOS))
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007395 // Doesn't pass on OS X yet for reasons that need to be investigated.
7396 EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS);
7397#endif
7398 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
7399 EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
7400}
7401
7402TEST_F(HTTPSOCSPTest, Invalid) {
7403 if (!SystemSupportsOCSP()) {
7404 LOG(WARNING) << "Skipping test because system doesn't support OCSP";
7405 return;
7406 }
7407
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007408 SpawnedTestServer::SSLOptions ssl_options(
7409 SpawnedTestServer::SSLOptions::CERT_AUTO);
7410 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007411
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007412 CertStatus cert_status;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007413 DoConnection(ssl_options, &cert_status);
7414
7415 EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(),
7416 cert_status & CERT_STATUS_ALL_ERRORS);
7417
7418 // Without a positive OCSP response, we shouldn't show the EV status.
7419 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
7420 EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
7421}
7422
Ben Murdoch558790d2013-07-30 15:19:42 +01007423class HTTPSHardFailTest : public HTTPSOCSPTest {
7424 protected:
7425 virtual void SetupContext(URLRequestContext* context) OVERRIDE {
7426 context->set_ssl_config_service(
7427 new TestSSLConfigService(false /* check for EV */,
7428 false /* online revocation checking */,
7429 true /* require rev. checking for local
7430 anchors */));
7431 }
7432};
7433
7434
7435TEST_F(HTTPSHardFailTest, FailsOnOCSPInvalid) {
7436 if (!SystemSupportsOCSP()) {
7437 LOG(WARNING) << "Skipping test because system doesn't support OCSP";
7438 return;
7439 }
7440
7441 if (!SystemSupportsHardFailRevocationChecking()) {
7442 LOG(WARNING) << "Skipping test because system doesn't support hard fail "
7443 << "revocation checking";
7444 return;
7445 }
7446
7447 SpawnedTestServer::SSLOptions ssl_options(
7448 SpawnedTestServer::SSLOptions::CERT_AUTO);
7449 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;
7450
7451 CertStatus cert_status;
7452 DoConnection(ssl_options, &cert_status);
7453
7454 EXPECT_EQ(CERT_STATUS_REVOKED,
7455 cert_status & CERT_STATUS_REVOKED);
7456
7457 // Without a positive OCSP response, we shouldn't show the EV status.
7458 EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
7459}
7460
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007461class HTTPSEVCRLSetTest : public HTTPSOCSPTest {
7462 protected:
7463 virtual void SetupContext(URLRequestContext* context) OVERRIDE {
7464 context->set_ssl_config_service(
7465 new TestSSLConfigService(true /* check for EV */,
Ben Murdoch558790d2013-07-30 15:19:42 +01007466 false /* online revocation checking */,
7467 false /* require rev. checking for local
7468 anchors */));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007469 }
7470};
7471
7472TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndInvalidOCSP) {
7473 if (!SystemSupportsOCSP()) {
7474 LOG(WARNING) << "Skipping test because system doesn't support OCSP";
7475 return;
7476 }
7477
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007478 SpawnedTestServer::SSLOptions ssl_options(
7479 SpawnedTestServer::SSLOptions::CERT_AUTO);
7480 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007481 SSLConfigService::SetCRLSet(scoped_refptr<CRLSet>());
7482
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007483 CertStatus cert_status;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007484 DoConnection(ssl_options, &cert_status);
7485
7486 EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(),
7487 cert_status & CERT_STATUS_ALL_ERRORS);
7488
7489 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
7490 EXPECT_EQ(SystemUsesChromiumEVMetadata(),
7491 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
7492}
7493
Torne (Richard Coles)424c4d72013-08-30 15:14:49 +01007494TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndRevokedOCSP) {
7495 if (!SystemSupportsOCSP()) {
7496 LOG(WARNING) << "Skipping test because system doesn't support OCSP";
7497 return;
7498 }
7499
7500 SpawnedTestServer::SSLOptions ssl_options(
7501 SpawnedTestServer::SSLOptions::CERT_AUTO);
7502 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED;
7503 SSLConfigService::SetCRLSet(scoped_refptr<CRLSet>());
7504
7505 CertStatus cert_status;
7506 DoConnection(ssl_options, &cert_status);
7507
7508 // Currently only works for Windows. When using NSS or OS X, it's not
7509 // possible to determine whether the check failed because of actual
7510 // revocation or because there was an OCSP failure.
7511#if defined(OS_WIN)
7512 EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS);
7513#else
7514 EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);
7515#endif
7516
7517 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
7518 EXPECT_EQ(SystemUsesChromiumEVMetadata(),
7519 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
7520}
7521
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007522TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndGoodOCSP) {
7523 if (!SystemSupportsOCSP()) {
7524 LOG(WARNING) << "Skipping test because system doesn't support OCSP";
7525 return;
7526 }
7527
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007528 SpawnedTestServer::SSLOptions ssl_options(
7529 SpawnedTestServer::SSLOptions::CERT_AUTO);
7530 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007531 SSLConfigService::SetCRLSet(scoped_refptr<CRLSet>());
7532
7533 CertStatus cert_status;
7534 DoConnection(ssl_options, &cert_status);
7535
7536 EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);
7537
7538 EXPECT_EQ(SystemUsesChromiumEVMetadata(),
7539 static_cast<bool>(cert_status & CERT_STATUS_IS_EV));
7540 EXPECT_EQ(SystemUsesChromiumEVMetadata(),
7541 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
7542}
7543
7544TEST_F(HTTPSEVCRLSetTest, ExpiredCRLSet) {
7545 if (!SystemSupportsOCSP()) {
7546 LOG(WARNING) << "Skipping test because system doesn't support OCSP";
7547 return;
7548 }
7549
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007550 SpawnedTestServer::SSLOptions ssl_options(
7551 SpawnedTestServer::SSLOptions::CERT_AUTO);
7552 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007553 SSLConfigService::SetCRLSet(
7554 scoped_refptr<CRLSet>(CRLSet::ExpiredCRLSetForTesting()));
7555
7556 CertStatus cert_status;
7557 DoConnection(ssl_options, &cert_status);
7558
7559 EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(),
7560 cert_status & CERT_STATUS_ALL_ERRORS);
7561
7562 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
7563 EXPECT_EQ(SystemUsesChromiumEVMetadata(),
7564 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
7565}
7566
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01007567TEST_F(HTTPSEVCRLSetTest, FreshCRLSetCovered) {
7568 if (!SystemSupportsOCSP()) {
7569 LOG(WARNING) << "Skipping test because system doesn't support OCSP";
7570 return;
7571 }
7572
7573 SpawnedTestServer::SSLOptions ssl_options(
7574 SpawnedTestServer::SSLOptions::CERT_AUTO);
7575 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;
7576 SSLConfigService::SetCRLSet(
7577 scoped_refptr<CRLSet>(CRLSet::ForTesting(
7578 false, &kOCSPTestCertSPKI, "")));
7579
7580 CertStatus cert_status;
7581 DoConnection(ssl_options, &cert_status);
7582
7583 // With a fresh CRLSet that covers the issuing certificate, we shouldn't do a
7584 // revocation check for EV.
7585 EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);
7586 EXPECT_EQ(SystemUsesChromiumEVMetadata(),
7587 static_cast<bool>(cert_status & CERT_STATUS_IS_EV));
7588 EXPECT_FALSE(
7589 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
7590}
7591
7592TEST_F(HTTPSEVCRLSetTest, FreshCRLSetNotCovered) {
7593 if (!SystemSupportsOCSP()) {
7594 LOG(WARNING) << "Skipping test because system doesn't support OCSP";
7595 return;
7596 }
7597
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007598 SpawnedTestServer::SSLOptions ssl_options(
7599 SpawnedTestServer::SSLOptions::CERT_AUTO);
7600 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007601 SSLConfigService::SetCRLSet(
7602 scoped_refptr<CRLSet>(CRLSet::EmptyCRLSetForTesting()));
7603
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01007604 CertStatus cert_status = 0;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007605 DoConnection(ssl_options, &cert_status);
7606
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01007607 // Even with a fresh CRLSet, we should still do online revocation checks when
7608 // the certificate chain isn't covered by the CRLSet, which it isn't in this
7609 // test.
7610 EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(),
7611 cert_status & CERT_STATUS_ALL_ERRORS);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007612
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01007613 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007614 EXPECT_EQ(SystemUsesChromiumEVMetadata(),
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01007615 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007616}
7617
7618TEST_F(HTTPSEVCRLSetTest, ExpiredCRLSetAndRevokedNonEVCert) {
7619 // Test that when EV verification is requested, but online revocation
7620 // checking is disabled, and the leaf certificate is not in fact EV, that
7621 // no revocation checking actually happens.
7622 if (!SystemSupportsOCSP()) {
7623 LOG(WARNING) << "Skipping test because system doesn't support OCSP";
7624 return;
7625 }
7626
7627 // Unmark the certificate's OID as EV, which should disable revocation
7628 // checking (as per the user preference)
7629 ev_test_policy_.reset();
7630
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007631 SpawnedTestServer::SSLOptions ssl_options(
7632 SpawnedTestServer::SSLOptions::CERT_AUTO);
7633 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007634 SSLConfigService::SetCRLSet(
7635 scoped_refptr<CRLSet>(CRLSet::ExpiredCRLSetForTesting()));
7636
7637 CertStatus cert_status;
7638 DoConnection(ssl_options, &cert_status);
7639
7640 EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);
7641
7642 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
7643 EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
7644}
7645
7646class HTTPSCRLSetTest : public HTTPSOCSPTest {
7647 protected:
7648 virtual void SetupContext(URLRequestContext* context) OVERRIDE {
7649 context->set_ssl_config_service(
7650 new TestSSLConfigService(false /* check for EV */,
Ben Murdoch558790d2013-07-30 15:19:42 +01007651 false /* online revocation checking */,
7652 false /* require rev. checking for local
7653 anchors */));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007654 }
7655};
7656
7657TEST_F(HTTPSCRLSetTest, ExpiredCRLSet) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007658 SpawnedTestServer::SSLOptions ssl_options(
7659 SpawnedTestServer::SSLOptions::CERT_AUTO);
7660 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007661 SSLConfigService::SetCRLSet(
7662 scoped_refptr<CRLSet>(CRLSet::ExpiredCRLSetForTesting()));
7663
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007664 CertStatus cert_status;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007665 DoConnection(ssl_options, &cert_status);
7666
7667 // If we're not trying EV verification then, even if the CRLSet has expired,
7668 // we don't fall back to online revocation checks.
7669 EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);
7670 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
7671 EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
7672}
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01007673
7674TEST_F(HTTPSCRLSetTest, CRLSetRevoked) {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007675#if defined(OS_ANDROID)
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +01007676 LOG(WARNING) << "Skipping test because system doesn't support CRLSets";
7677 return;
7678#endif
7679
7680 SpawnedTestServer::SSLOptions ssl_options(
7681 SpawnedTestServer::SSLOptions::CERT_AUTO);
7682 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK;
7683 ssl_options.cert_serial = 10;
7684 SSLConfigService::SetCRLSet(
7685 scoped_refptr<CRLSet>(CRLSet::ForTesting(
7686 false, &kOCSPTestCertSPKI, "\x0a")));
7687
7688 CertStatus cert_status = 0;
7689 DoConnection(ssl_options, &cert_status);
7690
7691 // If the certificate is recorded as revoked in the CRLSet, that should be
7692 // reflected without online revocation checking.
7693 EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS);
7694 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
7695 EXPECT_FALSE(
7696 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
7697}
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007698#endif // !defined(OS_IOS)
7699
7700#if !defined(DISABLE_FTP_SUPPORT)
7701class URLRequestTestFTP : public URLRequestTest {
7702 public:
7703 URLRequestTestFTP()
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007704 : test_server_(SpawnedTestServer::TYPE_FTP, SpawnedTestServer::kLocalhost,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007705 base::FilePath()) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007706 }
7707
7708 protected:
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +01007709 SpawnedTestServer test_server_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007710};
7711
7712// Make sure an FTP request using an unsafe ports fails.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007713TEST_F(URLRequestTestFTP, UnsafePort) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007714 ASSERT_TRUE(test_server_.Start());
7715
7716 URLRequestJobFactoryImpl job_factory;
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01007717 FtpNetworkLayer ftp_transaction_factory(default_context_.host_resolver());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007718
7719 GURL url("ftp://127.0.0.1:7");
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007720 job_factory.SetProtocolHandler(
7721 "ftp",
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01007722 new FtpProtocolHandler(&ftp_transaction_factory));
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007723 default_context_.set_job_factory(&job_factory);
7724
7725 TestDelegate d;
7726 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007727 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
7728 url, DEFAULT_PRIORITY, &d, NULL));
7729 r->Start();
7730 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007731
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01007732 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007733
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007734 EXPECT_FALSE(r->is_pending());
7735 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
7736 EXPECT_EQ(ERR_UNSAFE_PORT, r->status().error());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007737 }
7738}
7739
7740// Flaky, see http://crbug.com/25045.
7741TEST_F(URLRequestTestFTP, DISABLED_FTPDirectoryListing) {
7742 ASSERT_TRUE(test_server_.Start());
7743
7744 TestDelegate d;
7745 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007746 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
7747 test_server_.GetURL("/"), DEFAULT_PRIORITY, &d, NULL));
7748 r->Start();
7749 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007750
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01007751 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007752
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007753 EXPECT_FALSE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007754 EXPECT_EQ(1, d.response_started_count());
7755 EXPECT_FALSE(d.received_data_before_response());
7756 EXPECT_LT(0, d.bytes_received());
7757 EXPECT_EQ(test_server_.host_port_pair().host(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007758 r->GetSocketAddress().host());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007759 EXPECT_EQ(test_server_.host_port_pair().port(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007760 r->GetSocketAddress().port());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007761 }
7762}
7763
7764// Flaky, see http://crbug.com/25045.
7765TEST_F(URLRequestTestFTP, DISABLED_FTPGetTestAnonymous) {
7766 ASSERT_TRUE(test_server_.Start());
7767
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007768 base::FilePath app_path;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007769 PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
7770 app_path = app_path.AppendASCII("LICENSE");
7771 TestDelegate d;
7772 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007773 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
7774 test_server_.GetURL("/LICENSE"), DEFAULT_PRIORITY, &d, NULL));
7775 r->Start();
7776 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007777
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01007778 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007779
7780 int64 file_size = 0;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00007781 base::GetFileSize(app_path, &file_size);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007782
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007783 EXPECT_FALSE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007784 EXPECT_EQ(1, d.response_started_count());
7785 EXPECT_FALSE(d.received_data_before_response());
7786 EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
7787 EXPECT_EQ(test_server_.host_port_pair().host(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007788 r->GetSocketAddress().host());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007789 EXPECT_EQ(test_server_.host_port_pair().port(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007790 r->GetSocketAddress().port());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007791 }
7792}
7793
7794// Flaky, see http://crbug.com/25045.
7795TEST_F(URLRequestTestFTP, DISABLED_FTPGetTest) {
7796 ASSERT_TRUE(test_server_.Start());
7797
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007798 base::FilePath app_path;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007799 PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
7800 app_path = app_path.AppendASCII("LICENSE");
7801 TestDelegate d;
7802 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007803 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007804 test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome", "chrome"),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007805 DEFAULT_PRIORITY, &d, NULL));
7806 r->Start();
7807 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007808
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01007809 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007810
7811 int64 file_size = 0;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00007812 base::GetFileSize(app_path, &file_size);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007813
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007814 EXPECT_FALSE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007815 EXPECT_EQ(test_server_.host_port_pair().host(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007816 r->GetSocketAddress().host());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007817 EXPECT_EQ(test_server_.host_port_pair().port(),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007818 r->GetSocketAddress().port());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007819 EXPECT_EQ(1, d.response_started_count());
7820 EXPECT_FALSE(d.received_data_before_response());
7821 EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007822
7823 LoadTimingInfo load_timing_info;
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007824 r->GetLoadTimingInfo(&load_timing_info);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01007825 TestLoadTimingNoHttpResponse(load_timing_info);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007826 }
7827}
7828
7829// Flaky, see http://crbug.com/25045.
7830TEST_F(URLRequestTestFTP, DISABLED_FTPCheckWrongPassword) {
7831 ASSERT_TRUE(test_server_.Start());
7832
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007833 base::FilePath app_path;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007834 PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
7835 app_path = app_path.AppendASCII("LICENSE");
7836 TestDelegate d;
7837 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007838 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
7839 test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome",
7840 "wrong_password"),
7841 DEFAULT_PRIORITY, &d, NULL));
7842 r->Start();
7843 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007844
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01007845 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007846
7847 int64 file_size = 0;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00007848 base::GetFileSize(app_path, &file_size);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007849
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007850 EXPECT_FALSE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007851 EXPECT_EQ(1, d.response_started_count());
7852 EXPECT_FALSE(d.received_data_before_response());
7853 EXPECT_EQ(d.bytes_received(), 0);
7854 }
7855}
7856
7857// Flaky, see http://crbug.com/25045.
7858TEST_F(URLRequestTestFTP, DISABLED_FTPCheckWrongPasswordRestart) {
7859 ASSERT_TRUE(test_server_.Start());
7860
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007861 base::FilePath app_path;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007862 PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
7863 app_path = app_path.AppendASCII("LICENSE");
7864 TestDelegate d;
7865 // Set correct login credentials. The delegate will be asked for them when
7866 // the initial login with wrong credentials will fail.
7867 d.set_credentials(AuthCredentials(kChrome, kChrome));
7868 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007869 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
7870 test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome",
7871 "wrong_password"),
7872 DEFAULT_PRIORITY, &d, NULL));
7873 r->Start();
7874 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007875
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01007876 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007877
7878 int64 file_size = 0;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00007879 base::GetFileSize(app_path, &file_size);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007880
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007881 EXPECT_FALSE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007882 EXPECT_EQ(1, d.response_started_count());
7883 EXPECT_FALSE(d.received_data_before_response());
7884 EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
7885 }
7886}
7887
7888// Flaky, see http://crbug.com/25045.
7889TEST_F(URLRequestTestFTP, DISABLED_FTPCheckWrongUser) {
7890 ASSERT_TRUE(test_server_.Start());
7891
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007892 base::FilePath app_path;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007893 PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
7894 app_path = app_path.AppendASCII("LICENSE");
7895 TestDelegate d;
7896 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007897 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
7898 test_server_.GetURLWithUserAndPassword("/LICENSE", "wrong_user",
7899 "chrome"),
7900 DEFAULT_PRIORITY, &d, NULL));
7901 r->Start();
7902 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007903
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01007904 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007905
7906 int64 file_size = 0;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00007907 base::GetFileSize(app_path, &file_size);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007908
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007909 EXPECT_FALSE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007910 EXPECT_EQ(1, d.response_started_count());
7911 EXPECT_FALSE(d.received_data_before_response());
7912 EXPECT_EQ(d.bytes_received(), 0);
7913 }
7914}
7915
7916// Flaky, see http://crbug.com/25045.
7917TEST_F(URLRequestTestFTP, DISABLED_FTPCheckWrongUserRestart) {
7918 ASSERT_TRUE(test_server_.Start());
7919
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007920 base::FilePath app_path;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007921 PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
7922 app_path = app_path.AppendASCII("LICENSE");
7923 TestDelegate d;
7924 // Set correct login credentials. The delegate will be asked for them when
7925 // the initial login with wrong credentials will fail.
7926 d.set_credentials(AuthCredentials(kChrome, kChrome));
7927 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007928 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
7929 test_server_.GetURLWithUserAndPassword("/LICENSE", "wrong_user",
7930 "chrome"),
7931 DEFAULT_PRIORITY, &d, NULL));
7932 r->Start();
7933 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007934
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01007935 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007936
7937 int64 file_size = 0;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00007938 base::GetFileSize(app_path, &file_size);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007939
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007940 EXPECT_FALSE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007941 EXPECT_EQ(1, d.response_started_count());
7942 EXPECT_FALSE(d.received_data_before_response());
7943 EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
7944 }
7945}
7946
7947// Flaky, see http://crbug.com/25045.
7948TEST_F(URLRequestTestFTP, DISABLED_FTPCacheURLCredentials) {
7949 ASSERT_TRUE(test_server_.Start());
7950
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007951 base::FilePath app_path;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007952 PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
7953 app_path = app_path.AppendASCII("LICENSE");
7954
7955 scoped_ptr<TestDelegate> d(new TestDelegate);
7956 {
7957 // Pass correct login identity in the URL.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007958 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
Torne (Richard Coles)0f1bc082013-11-06 12:27:47 +00007959 test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome", "chrome"),
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007960 DEFAULT_PRIORITY, d.get(), NULL));
7961 r->Start();
7962 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007963
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01007964 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007965
7966 int64 file_size = 0;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00007967 base::GetFileSize(app_path, &file_size);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007968
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007969 EXPECT_FALSE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007970 EXPECT_EQ(1, d->response_started_count());
7971 EXPECT_FALSE(d->received_data_before_response());
7972 EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size));
7973 }
7974
7975 d.reset(new TestDelegate);
7976 {
7977 // This request should use cached identity from previous request.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007978 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
7979 test_server_.GetURL("/LICENSE"), DEFAULT_PRIORITY, d.get(), NULL));
7980 r->Start();
7981 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007982
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01007983 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007984
7985 int64 file_size = 0;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00007986 base::GetFileSize(app_path, &file_size);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007987
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01007988 EXPECT_FALSE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007989 EXPECT_EQ(1, d->response_started_count());
7990 EXPECT_FALSE(d->received_data_before_response());
7991 EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size));
7992 }
7993}
7994
7995// Flaky, see http://crbug.com/25045.
7996TEST_F(URLRequestTestFTP, DISABLED_FTPCacheLoginBoxCredentials) {
7997 ASSERT_TRUE(test_server_.Start());
7998
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00007999 base::FilePath app_path;
Torne (Richard Coles)58218062012-11-14 11:43:16 +00008000 PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
8001 app_path = app_path.AppendASCII("LICENSE");
8002
8003 scoped_ptr<TestDelegate> d(new TestDelegate);
8004 // Set correct login credentials. The delegate will be asked for them when
8005 // the initial login with wrong credentials will fail.
8006 d->set_credentials(AuthCredentials(kChrome, kChrome));
8007 {
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01008008 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
8009 test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome",
8010 "wrong_password"),
8011 DEFAULT_PRIORITY, d.get(), NULL));
8012 r->Start();
8013 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00008014
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01008015 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00008016
8017 int64 file_size = 0;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00008018 base::GetFileSize(app_path, &file_size);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00008019
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01008020 EXPECT_FALSE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00008021 EXPECT_EQ(1, d->response_started_count());
8022 EXPECT_FALSE(d->received_data_before_response());
8023 EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size));
8024 }
8025
8026 // Use a new delegate without explicit credentials. The cached ones should be
8027 // used.
8028 d.reset(new TestDelegate);
8029 {
8030 // Don't pass wrong credentials in the URL, they would override valid cached
8031 // ones.
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01008032 scoped_ptr<URLRequest> r(default_context_.CreateRequest(
8033 test_server_.GetURL("/LICENSE"), DEFAULT_PRIORITY, d.get(), NULL));
8034 r->Start();
8035 EXPECT_TRUE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00008036
Torne (Richard Coles)3551c9c2013-08-23 16:39:15 +01008037 base::RunLoop().Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +00008038
8039 int64 file_size = 0;
Torne (Richard Coles)a3f6a492013-12-18 16:25:09 +00008040 base::GetFileSize(app_path, &file_size);
Torne (Richard Coles)58218062012-11-14 11:43:16 +00008041
Torne (Richard Coles)03b57e02014-08-28 12:05:23 +01008042 EXPECT_FALSE(r->is_pending());
Torne (Richard Coles)58218062012-11-14 11:43:16 +00008043 EXPECT_EQ(1, d->response_started_count());
8044 EXPECT_FALSE(d->received_data_before_response());
8045 EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size));
8046 }
8047}
8048#endif // !defined(DISABLE_FTP_SUPPORT)
8049
8050} // namespace net