OLD | NEW |
| (Empty) |
1 // 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 | |
14 #include "base/basictypes.h" | |
15 #include "base/bind.h" | |
16 #include "base/compiler_specific.h" | |
17 #include "base/files/file_util.h" | |
18 #include "base/files/scoped_temp_dir.h" | |
19 #include "base/format_macros.h" | |
20 #include "base/memory/scoped_ptr.h" | |
21 #include "base/memory/weak_ptr.h" | |
22 #include "base/message_loop/message_loop.h" | |
23 #include "base/message_loop/message_loop_proxy.h" | |
24 #include "base/path_service.h" | |
25 #include "base/run_loop.h" | |
26 #include "base/strings/string_number_conversions.h" | |
27 #include "base/strings/string_piece.h" | |
28 #include "base/strings/string_split.h" | |
29 #include "base/strings/string_util.h" | |
30 #include "base/strings/stringprintf.h" | |
31 #include "base/strings/utf_string_conversions.h" | |
32 #include "net/base/capturing_net_log.h" | |
33 #include "net/base/chunked_upload_data_stream.h" | |
34 #include "net/base/elements_upload_data_stream.h" | |
35 #include "net/base/load_flags.h" | |
36 #include "net/base/load_timing_info.h" | |
37 #include "net/base/load_timing_info_test_util.h" | |
38 #include "net/base/net_errors.h" | |
39 #include "net/base/net_log.h" | |
40 #include "net/base/net_log_unittest.h" | |
41 #include "net/base/net_module.h" | |
42 #include "net/base/net_util.h" | |
43 #include "net/base/request_priority.h" | |
44 #include "net/base/test_data_directory.h" | |
45 #include "net/base/upload_bytes_element_reader.h" | |
46 #include "net/base/upload_data_stream.h" | |
47 #include "net/base/upload_file_element_reader.h" | |
48 #include "net/cert/ev_root_ca_metadata.h" | |
49 #include "net/cert/mock_cert_verifier.h" | |
50 #include "net/cert/test_root_certs.h" | |
51 #include "net/cookies/cookie_monster.h" | |
52 #include "net/cookies/cookie_store_test_helpers.h" | |
53 #include "net/disk_cache/disk_cache.h" | |
54 #include "net/dns/mock_host_resolver.h" | |
55 #include "net/ftp/ftp_network_layer.h" | |
56 #include "net/http/http_byte_range.h" | |
57 #include "net/http/http_cache.h" | |
58 #include "net/http/http_network_layer.h" | |
59 #include "net/http/http_network_session.h" | |
60 #include "net/http/http_request_headers.h" | |
61 #include "net/http/http_response_headers.h" | |
62 #include "net/http/http_util.h" | |
63 #include "net/ocsp/nss_ocsp.h" | |
64 #include "net/proxy/proxy_service.h" | |
65 #include "net/socket/ssl_client_socket.h" | |
66 #include "net/ssl/ssl_cipher_suite_names.h" | |
67 #include "net/ssl/ssl_connection_status_flags.h" | |
68 #include "net/test/cert_test_util.h" | |
69 #include "net/test/spawned_test_server/spawned_test_server.h" | |
70 #include "net/url_request/data_protocol_handler.h" | |
71 #include "net/url_request/static_http_user_agent_settings.h" | |
72 #include "net/url_request/url_request.h" | |
73 #include "net/url_request/url_request_http_job.h" | |
74 #include "net/url_request/url_request_intercepting_job_factory.h" | |
75 #include "net/url_request/url_request_interceptor.h" | |
76 #include "net/url_request/url_request_job_factory_impl.h" | |
77 #include "net/url_request/url_request_redirect_job.h" | |
78 #include "net/url_request/url_request_test_job.h" | |
79 #include "net/url_request/url_request_test_util.h" | |
80 #include "testing/gtest/include/gtest/gtest.h" | |
81 #include "testing/platform_test.h" | |
82 | |
83 #if !defined(DISABLE_FILE_SUPPORT) | |
84 #include "net/base/filename_util.h" | |
85 #include "net/url_request/file_protocol_handler.h" | |
86 #include "net/url_request/url_request_file_dir_job.h" | |
87 #endif | |
88 | |
89 #if !defined(DISABLE_FTP_SUPPORT) | |
90 #include "net/url_request/ftp_protocol_handler.h" | |
91 #endif | |
92 | |
93 #if defined(OS_WIN) | |
94 #include "base/win/scoped_com_initializer.h" | |
95 #include "base/win/scoped_comptr.h" | |
96 #include "base/win/windows_version.h" | |
97 #endif | |
98 | |
99 using base::ASCIIToUTF16; | |
100 using base::Time; | |
101 using std::string; | |
102 | |
103 namespace net { | |
104 | |
105 namespace { | |
106 | |
107 const base::string16 kChrome(ASCIIToUTF16("chrome")); | |
108 const base::string16 kSecret(ASCIIToUTF16("secret")); | |
109 const base::string16 kUser(ASCIIToUTF16("user")); | |
110 | |
111 // Tests load timing information in the case a fresh connection was used, with | |
112 // no proxy. | |
113 void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info, | |
114 int connect_timing_flags) { | |
115 EXPECT_FALSE(load_timing_info.socket_reused); | |
116 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); | |
117 | |
118 EXPECT_FALSE(load_timing_info.request_start_time.is_null()); | |
119 EXPECT_FALSE(load_timing_info.request_start.is_null()); | |
120 | |
121 EXPECT_LE(load_timing_info.request_start, | |
122 load_timing_info.connect_timing.connect_start); | |
123 ExpectConnectTimingHasTimes(load_timing_info.connect_timing, | |
124 connect_timing_flags); | |
125 EXPECT_LE(load_timing_info.connect_timing.connect_end, | |
126 load_timing_info.send_start); | |
127 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); | |
128 EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end); | |
129 | |
130 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); | |
131 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); | |
132 } | |
133 | |
134 // Same as above, but with proxy times. | |
135 void TestLoadTimingNotReusedWithProxy( | |
136 const LoadTimingInfo& load_timing_info, | |
137 int connect_timing_flags) { | |
138 EXPECT_FALSE(load_timing_info.socket_reused); | |
139 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); | |
140 | |
141 EXPECT_FALSE(load_timing_info.request_start_time.is_null()); | |
142 EXPECT_FALSE(load_timing_info.request_start.is_null()); | |
143 | |
144 EXPECT_LE(load_timing_info.request_start, | |
145 load_timing_info.proxy_resolve_start); | |
146 EXPECT_LE(load_timing_info.proxy_resolve_start, | |
147 load_timing_info.proxy_resolve_end); | |
148 EXPECT_LE(load_timing_info.proxy_resolve_end, | |
149 load_timing_info.connect_timing.connect_start); | |
150 ExpectConnectTimingHasTimes(load_timing_info.connect_timing, | |
151 connect_timing_flags); | |
152 EXPECT_LE(load_timing_info.connect_timing.connect_end, | |
153 load_timing_info.send_start); | |
154 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); | |
155 EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end); | |
156 } | |
157 | |
158 // Same as above, but with a reused socket and proxy times. | |
159 void TestLoadTimingReusedWithProxy( | |
160 const LoadTimingInfo& load_timing_info) { | |
161 EXPECT_TRUE(load_timing_info.socket_reused); | |
162 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); | |
163 | |
164 EXPECT_FALSE(load_timing_info.request_start_time.is_null()); | |
165 EXPECT_FALSE(load_timing_info.request_start.is_null()); | |
166 | |
167 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); | |
168 | |
169 EXPECT_LE(load_timing_info.request_start, | |
170 load_timing_info.proxy_resolve_start); | |
171 EXPECT_LE(load_timing_info.proxy_resolve_start, | |
172 load_timing_info.proxy_resolve_end); | |
173 EXPECT_LE(load_timing_info.proxy_resolve_end, | |
174 load_timing_info.send_start); | |
175 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); | |
176 EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end); | |
177 } | |
178 | |
179 // Tests load timing information in the case of a cache hit, when no cache | |
180 // validation request was sent over the wire. | |
181 base::StringPiece TestNetResourceProvider(int key) { | |
182 return "header"; | |
183 } | |
184 | |
185 void FillBuffer(char* buffer, size_t len) { | |
186 static bool called = false; | |
187 if (!called) { | |
188 called = true; | |
189 int seed = static_cast<int>(Time::Now().ToInternalValue()); | |
190 srand(seed); | |
191 } | |
192 | |
193 for (size_t i = 0; i < len; i++) { | |
194 buffer[i] = static_cast<char>(rand()); | |
195 if (!buffer[i]) | |
196 buffer[i] = 'g'; | |
197 } | |
198 } | |
199 | |
200 #if !defined(OS_IOS) | |
201 void TestLoadTimingCacheHitNoNetwork( | |
202 const LoadTimingInfo& load_timing_info) { | |
203 EXPECT_FALSE(load_timing_info.socket_reused); | |
204 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); | |
205 | |
206 EXPECT_FALSE(load_timing_info.request_start_time.is_null()); | |
207 EXPECT_FALSE(load_timing_info.request_start.is_null()); | |
208 | |
209 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); | |
210 EXPECT_LE(load_timing_info.request_start, load_timing_info.send_start); | |
211 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end); | |
212 EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end); | |
213 | |
214 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); | |
215 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); | |
216 } | |
217 | |
218 // Tests load timing in the case that there is no HTTP response. This can be | |
219 // used to test in the case of errors or non-HTTP requests. | |
220 void TestLoadTimingNoHttpResponse( | |
221 const LoadTimingInfo& load_timing_info) { | |
222 EXPECT_FALSE(load_timing_info.socket_reused); | |
223 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); | |
224 | |
225 // Only the request times should be non-null. | |
226 EXPECT_FALSE(load_timing_info.request_start_time.is_null()); | |
227 EXPECT_FALSE(load_timing_info.request_start.is_null()); | |
228 | |
229 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); | |
230 | |
231 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null()); | |
232 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null()); | |
233 EXPECT_TRUE(load_timing_info.send_start.is_null()); | |
234 EXPECT_TRUE(load_timing_info.send_end.is_null()); | |
235 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); | |
236 } | |
237 | |
238 // Do a case-insensitive search through |haystack| for |needle|. | |
239 bool ContainsString(const std::string& haystack, const char* needle) { | |
240 std::string::const_iterator it = | |
241 std::search(haystack.begin(), | |
242 haystack.end(), | |
243 needle, | |
244 needle + strlen(needle), | |
245 base::CaseInsensitiveCompare<char>()); | |
246 return it != haystack.end(); | |
247 } | |
248 | |
249 scoped_ptr<UploadDataStream> CreateSimpleUploadData(const char* data) { | |
250 scoped_ptr<UploadElementReader> reader( | |
251 new UploadBytesElementReader(data, strlen(data))); | |
252 return ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0); | |
253 } | |
254 | |
255 // Verify that the SSLInfo of a successful SSL connection has valid values. | |
256 void CheckSSLInfo(const SSLInfo& ssl_info) { | |
257 // -1 means unknown. 0 means no encryption. | |
258 EXPECT_GT(ssl_info.security_bits, 0); | |
259 | |
260 // The cipher suite TLS_NULL_WITH_NULL_NULL (0) must not be negotiated. | |
261 uint16 cipher_suite = SSLConnectionStatusToCipherSuite( | |
262 ssl_info.connection_status); | |
263 EXPECT_NE(0U, cipher_suite); | |
264 } | |
265 | |
266 void CheckFullRequestHeaders(const HttpRequestHeaders& headers, | |
267 const GURL& host_url) { | |
268 std::string sent_value; | |
269 | |
270 EXPECT_TRUE(headers.GetHeader("Host", &sent_value)); | |
271 EXPECT_EQ(GetHostAndOptionalPort(host_url), sent_value); | |
272 | |
273 EXPECT_TRUE(headers.GetHeader("Connection", &sent_value)); | |
274 EXPECT_EQ("keep-alive", sent_value); | |
275 } | |
276 | |
277 bool FingerprintsEqual(const HashValueVector& a, const HashValueVector& b) { | |
278 size_t size = a.size(); | |
279 | |
280 if (size != b.size()) | |
281 return false; | |
282 | |
283 for (size_t i = 0; i < size; ++i) { | |
284 if (!a[i].Equals(b[i])) | |
285 return false; | |
286 } | |
287 | |
288 return true; | |
289 } | |
290 #endif // !defined(OS_IOS) | |
291 | |
292 // A network delegate that allows the user to choose a subset of request stages | |
293 // to block in. When blocking, the delegate can do one of the following: | |
294 // * synchronously return a pre-specified error code, or | |
295 // * asynchronously return that value via an automatically called callback, | |
296 // or | |
297 // * block and wait for the user to do a callback. | |
298 // Additionally, the user may also specify a redirect URL -- then each request | |
299 // with the current URL different from the redirect target will be redirected | |
300 // to that target, in the on-before-URL-request stage, independent of whether | |
301 // the delegate blocks in ON_BEFORE_URL_REQUEST or not. | |
302 class BlockingNetworkDelegate : public TestNetworkDelegate { | |
303 public: | |
304 // Stages in which the delegate can block. | |
305 enum Stage { | |
306 NOT_BLOCKED = 0, | |
307 ON_BEFORE_URL_REQUEST = 1 << 0, | |
308 ON_BEFORE_SEND_HEADERS = 1 << 1, | |
309 ON_HEADERS_RECEIVED = 1 << 2, | |
310 ON_AUTH_REQUIRED = 1 << 3 | |
311 }; | |
312 | |
313 // Behavior during blocked stages. During other stages, just | |
314 // returns OK or NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION. | |
315 enum BlockMode { | |
316 SYNCHRONOUS, // No callback, returns specified return values. | |
317 AUTO_CALLBACK, // |this| posts a task to run the callback using the | |
318 // specified return codes. | |
319 USER_CALLBACK, // User takes care of doing a callback. |retval_| and | |
320 // |auth_retval_| are ignored. In every blocking stage the | |
321 // message loop is quit. | |
322 }; | |
323 | |
324 // Creates a delegate which does not block at all. | |
325 explicit BlockingNetworkDelegate(BlockMode block_mode); | |
326 | |
327 // For users to trigger a callback returning |response|. | |
328 // Side-effects: resets |stage_blocked_for_callback_| and stored callbacks. | |
329 // Only call if |block_mode_| == USER_CALLBACK. | |
330 void DoCallback(int response); | |
331 void DoAuthCallback(NetworkDelegate::AuthRequiredResponse response); | |
332 | |
333 // Setters. | |
334 void set_retval(int retval) { | |
335 ASSERT_NE(USER_CALLBACK, block_mode_); | |
336 ASSERT_NE(ERR_IO_PENDING, retval); | |
337 ASSERT_NE(OK, retval); | |
338 retval_ = retval; | |
339 } | |
340 | |
341 // If |auth_retval| == AUTH_REQUIRED_RESPONSE_SET_AUTH, then | |
342 // |auth_credentials_| will be passed with the response. | |
343 void set_auth_retval(AuthRequiredResponse auth_retval) { | |
344 ASSERT_NE(USER_CALLBACK, block_mode_); | |
345 ASSERT_NE(AUTH_REQUIRED_RESPONSE_IO_PENDING, auth_retval); | |
346 auth_retval_ = auth_retval; | |
347 } | |
348 void set_auth_credentials(const AuthCredentials& auth_credentials) { | |
349 auth_credentials_ = auth_credentials; | |
350 } | |
351 | |
352 void set_redirect_url(const GURL& url) { | |
353 redirect_url_ = url; | |
354 } | |
355 | |
356 void set_block_on(int block_on) { | |
357 block_on_ = block_on; | |
358 } | |
359 | |
360 // Allows the user to check in which state did we block. | |
361 Stage stage_blocked_for_callback() const { | |
362 EXPECT_EQ(USER_CALLBACK, block_mode_); | |
363 return stage_blocked_for_callback_; | |
364 } | |
365 | |
366 private: | |
367 void RunCallback(int response, const CompletionCallback& callback); | |
368 void RunAuthCallback(AuthRequiredResponse response, | |
369 const AuthCallback& callback); | |
370 | |
371 // TestNetworkDelegate implementation. | |
372 int OnBeforeURLRequest(URLRequest* request, | |
373 const CompletionCallback& callback, | |
374 GURL* new_url) override; | |
375 | |
376 int OnBeforeSendHeaders(URLRequest* request, | |
377 const CompletionCallback& callback, | |
378 HttpRequestHeaders* headers) override; | |
379 | |
380 int OnHeadersReceived( | |
381 URLRequest* request, | |
382 const CompletionCallback& callback, | |
383 const HttpResponseHeaders* original_response_headers, | |
384 scoped_refptr<HttpResponseHeaders>* override_response_headers, | |
385 GURL* allowed_unsafe_redirect_url) override; | |
386 | |
387 NetworkDelegate::AuthRequiredResponse OnAuthRequired( | |
388 URLRequest* request, | |
389 const AuthChallengeInfo& auth_info, | |
390 const AuthCallback& callback, | |
391 AuthCredentials* credentials) override; | |
392 | |
393 // Resets the callbacks and |stage_blocked_for_callback_|. | |
394 void Reset(); | |
395 | |
396 // Checks whether we should block in |stage|. If yes, returns an error code | |
397 // and optionally sets up callback based on |block_mode_|. If no, returns OK. | |
398 int MaybeBlockStage(Stage stage, const CompletionCallback& callback); | |
399 | |
400 // Configuration parameters, can be adjusted by public methods: | |
401 const BlockMode block_mode_; | |
402 | |
403 // Values returned on blocking stages when mode is SYNCHRONOUS or | |
404 // AUTO_CALLBACK. For USER_CALLBACK these are set automatically to IO_PENDING. | |
405 int retval_; // To be returned in non-auth stages. | |
406 AuthRequiredResponse auth_retval_; | |
407 | |
408 GURL redirect_url_; // Used if non-empty during OnBeforeURLRequest. | |
409 int block_on_; // Bit mask: in which stages to block. | |
410 | |
411 // |auth_credentials_| will be copied to |*target_auth_credential_| on | |
412 // callback. | |
413 AuthCredentials auth_credentials_; | |
414 AuthCredentials* target_auth_credentials_; | |
415 | |
416 // Internal variables, not set by not the user: | |
417 // Last blocked stage waiting for user callback (unused if |block_mode_| != | |
418 // USER_CALLBACK). | |
419 Stage stage_blocked_for_callback_; | |
420 | |
421 // Callback objects stored during blocking stages. | |
422 CompletionCallback callback_; | |
423 AuthCallback auth_callback_; | |
424 | |
425 base::WeakPtrFactory<BlockingNetworkDelegate> weak_factory_; | |
426 | |
427 DISALLOW_COPY_AND_ASSIGN(BlockingNetworkDelegate); | |
428 }; | |
429 | |
430 BlockingNetworkDelegate::BlockingNetworkDelegate(BlockMode block_mode) | |
431 : block_mode_(block_mode), | |
432 retval_(OK), | |
433 auth_retval_(AUTH_REQUIRED_RESPONSE_NO_ACTION), | |
434 block_on_(0), | |
435 target_auth_credentials_(NULL), | |
436 stage_blocked_for_callback_(NOT_BLOCKED), | |
437 weak_factory_(this) { | |
438 } | |
439 | |
440 void BlockingNetworkDelegate::DoCallback(int response) { | |
441 ASSERT_EQ(USER_CALLBACK, block_mode_); | |
442 ASSERT_NE(NOT_BLOCKED, stage_blocked_for_callback_); | |
443 ASSERT_NE(ON_AUTH_REQUIRED, stage_blocked_for_callback_); | |
444 CompletionCallback callback = callback_; | |
445 Reset(); | |
446 RunCallback(response, callback); | |
447 } | |
448 | |
449 void BlockingNetworkDelegate::DoAuthCallback( | |
450 NetworkDelegate::AuthRequiredResponse response) { | |
451 ASSERT_EQ(USER_CALLBACK, block_mode_); | |
452 ASSERT_EQ(ON_AUTH_REQUIRED, stage_blocked_for_callback_); | |
453 AuthCallback auth_callback = auth_callback_; | |
454 Reset(); | |
455 RunAuthCallback(response, auth_callback); | |
456 } | |
457 | |
458 void BlockingNetworkDelegate::RunCallback(int response, | |
459 const CompletionCallback& callback) { | |
460 callback.Run(response); | |
461 } | |
462 | |
463 void BlockingNetworkDelegate::RunAuthCallback(AuthRequiredResponse response, | |
464 const AuthCallback& callback) { | |
465 if (auth_retval_ == AUTH_REQUIRED_RESPONSE_SET_AUTH) { | |
466 ASSERT_TRUE(target_auth_credentials_ != NULL); | |
467 *target_auth_credentials_ = auth_credentials_; | |
468 } | |
469 callback.Run(response); | |
470 } | |
471 | |
472 int BlockingNetworkDelegate::OnBeforeURLRequest( | |
473 URLRequest* request, | |
474 const CompletionCallback& callback, | |
475 GURL* new_url) { | |
476 if (redirect_url_ == request->url()) | |
477 return OK; // We've already seen this request and redirected elsewhere. | |
478 | |
479 TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url); | |
480 | |
481 if (!redirect_url_.is_empty()) | |
482 *new_url = redirect_url_; | |
483 | |
484 return MaybeBlockStage(ON_BEFORE_URL_REQUEST, callback); | |
485 } | |
486 | |
487 int BlockingNetworkDelegate::OnBeforeSendHeaders( | |
488 URLRequest* request, | |
489 const CompletionCallback& callback, | |
490 HttpRequestHeaders* headers) { | |
491 TestNetworkDelegate::OnBeforeSendHeaders(request, callback, headers); | |
492 | |
493 return MaybeBlockStage(ON_BEFORE_SEND_HEADERS, callback); | |
494 } | |
495 | |
496 int BlockingNetworkDelegate::OnHeadersReceived( | |
497 URLRequest* request, | |
498 const CompletionCallback& callback, | |
499 const HttpResponseHeaders* original_response_headers, | |
500 scoped_refptr<HttpResponseHeaders>* override_response_headers, | |
501 GURL* allowed_unsafe_redirect_url) { | |
502 TestNetworkDelegate::OnHeadersReceived(request, | |
503 callback, | |
504 original_response_headers, | |
505 override_response_headers, | |
506 allowed_unsafe_redirect_url); | |
507 | |
508 return MaybeBlockStage(ON_HEADERS_RECEIVED, callback); | |
509 } | |
510 | |
511 NetworkDelegate::AuthRequiredResponse BlockingNetworkDelegate::OnAuthRequired( | |
512 URLRequest* request, | |
513 const AuthChallengeInfo& auth_info, | |
514 const AuthCallback& callback, | |
515 AuthCredentials* credentials) { | |
516 TestNetworkDelegate::OnAuthRequired(request, auth_info, callback, | |
517 credentials); | |
518 // Check that the user has provided callback for the previous blocked stage. | |
519 EXPECT_EQ(NOT_BLOCKED, stage_blocked_for_callback_); | |
520 | |
521 if ((block_on_ & ON_AUTH_REQUIRED) == 0) { | |
522 return AUTH_REQUIRED_RESPONSE_NO_ACTION; | |
523 } | |
524 | |
525 target_auth_credentials_ = credentials; | |
526 | |
527 switch (block_mode_) { | |
528 case SYNCHRONOUS: | |
529 if (auth_retval_ == AUTH_REQUIRED_RESPONSE_SET_AUTH) | |
530 *target_auth_credentials_ = auth_credentials_; | |
531 return auth_retval_; | |
532 | |
533 case AUTO_CALLBACK: | |
534 base::MessageLoop::current()->PostTask( | |
535 FROM_HERE, | |
536 base::Bind(&BlockingNetworkDelegate::RunAuthCallback, | |
537 weak_factory_.GetWeakPtr(), auth_retval_, callback)); | |
538 return AUTH_REQUIRED_RESPONSE_IO_PENDING; | |
539 | |
540 case USER_CALLBACK: | |
541 auth_callback_ = callback; | |
542 stage_blocked_for_callback_ = ON_AUTH_REQUIRED; | |
543 base::MessageLoop::current()->PostTask(FROM_HERE, | |
544 base::MessageLoop::QuitClosure()); | |
545 return AUTH_REQUIRED_RESPONSE_IO_PENDING; | |
546 } | |
547 NOTREACHED(); | |
548 return AUTH_REQUIRED_RESPONSE_NO_ACTION; // Dummy value. | |
549 } | |
550 | |
551 void BlockingNetworkDelegate::Reset() { | |
552 EXPECT_NE(NOT_BLOCKED, stage_blocked_for_callback_); | |
553 stage_blocked_for_callback_ = NOT_BLOCKED; | |
554 callback_.Reset(); | |
555 auth_callback_.Reset(); | |
556 } | |
557 | |
558 int BlockingNetworkDelegate::MaybeBlockStage( | |
559 BlockingNetworkDelegate::Stage stage, | |
560 const CompletionCallback& callback) { | |
561 // Check that the user has provided callback for the previous blocked stage. | |
562 EXPECT_EQ(NOT_BLOCKED, stage_blocked_for_callback_); | |
563 | |
564 if ((block_on_ & stage) == 0) { | |
565 return OK; | |
566 } | |
567 | |
568 switch (block_mode_) { | |
569 case SYNCHRONOUS: | |
570 EXPECT_NE(OK, retval_); | |
571 return retval_; | |
572 | |
573 case AUTO_CALLBACK: | |
574 base::MessageLoop::current()->PostTask( | |
575 FROM_HERE, | |
576 base::Bind(&BlockingNetworkDelegate::RunCallback, | |
577 weak_factory_.GetWeakPtr(), retval_, callback)); | |
578 return ERR_IO_PENDING; | |
579 | |
580 case USER_CALLBACK: | |
581 callback_ = callback; | |
582 stage_blocked_for_callback_ = stage; | |
583 base::MessageLoop::current()->PostTask(FROM_HERE, | |
584 base::MessageLoop::QuitClosure()); | |
585 return ERR_IO_PENDING; | |
586 } | |
587 NOTREACHED(); | |
588 return 0; | |
589 } | |
590 | |
591 class TestURLRequestContextWithProxy : public TestURLRequestContext { | |
592 public: | |
593 // Does not own |delegate|. | |
594 TestURLRequestContextWithProxy(const std::string& proxy, | |
595 NetworkDelegate* delegate) | |
596 : TestURLRequestContext(true) { | |
597 context_storage_.set_proxy_service(ProxyService::CreateFixed(proxy)); | |
598 set_network_delegate(delegate); | |
599 Init(); | |
600 } | |
601 ~TestURLRequestContextWithProxy() override {} | |
602 }; | |
603 | |
604 } // namespace | |
605 | |
606 // Inherit PlatformTest since we require the autorelease pool on Mac OS X. | |
607 class URLRequestTest : public PlatformTest { | |
608 public: | |
609 URLRequestTest() : default_context_(true) { | |
610 default_context_.set_network_delegate(&default_network_delegate_); | |
611 default_context_.set_net_log(&net_log_); | |
612 job_factory_impl_ = new URLRequestJobFactoryImpl(); | |
613 job_factory_.reset(job_factory_impl_); | |
614 } | |
615 | |
616 ~URLRequestTest() override { | |
617 // URLRequestJobs may post clean-up tasks on destruction. | |
618 base::RunLoop().RunUntilIdle(); | |
619 } | |
620 | |
621 void SetUp() override { | |
622 SetUpFactory(); | |
623 default_context_.set_job_factory(job_factory_.get()); | |
624 default_context_.Init(); | |
625 PlatformTest::SetUp(); | |
626 } | |
627 | |
628 virtual void SetUpFactory() { | |
629 job_factory_impl_->SetProtocolHandler("data", new DataProtocolHandler); | |
630 #if !defined(DISABLE_FILE_SUPPORT) | |
631 job_factory_impl_->SetProtocolHandler( | |
632 "file", new FileProtocolHandler(base::MessageLoopProxy::current())); | |
633 #endif | |
634 } | |
635 | |
636 TestNetworkDelegate* default_network_delegate() { | |
637 return &default_network_delegate_; | |
638 } | |
639 | |
640 const TestURLRequestContext& default_context() const { | |
641 return default_context_; | |
642 } | |
643 | |
644 | |
645 // Adds the TestJobInterceptor to the default context. | |
646 TestJobInterceptor* AddTestInterceptor() { | |
647 TestJobInterceptor* protocol_handler_ = new TestJobInterceptor(); | |
648 job_factory_impl_->SetProtocolHandler("http", NULL); | |
649 job_factory_impl_->SetProtocolHandler("http", protocol_handler_); | |
650 return protocol_handler_; | |
651 } | |
652 | |
653 protected: | |
654 CapturingNetLog net_log_; | |
655 TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest. | |
656 URLRequestJobFactoryImpl* job_factory_impl_; | |
657 scoped_ptr<URLRequestJobFactory> job_factory_; | |
658 TestURLRequestContext default_context_; | |
659 }; | |
660 | |
661 TEST_F(URLRequestTest, AboutBlankTest) { | |
662 TestDelegate d; | |
663 { | |
664 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
665 GURL("about:blank"), DEFAULT_PRIORITY, &d, NULL)); | |
666 | |
667 r->Start(); | |
668 EXPECT_TRUE(r->is_pending()); | |
669 | |
670 base::RunLoop().Run(); | |
671 | |
672 EXPECT_TRUE(!r->is_pending()); | |
673 EXPECT_FALSE(d.received_data_before_response()); | |
674 EXPECT_EQ(d.bytes_received(), 0); | |
675 EXPECT_EQ("", r->GetSocketAddress().host()); | |
676 EXPECT_EQ(0, r->GetSocketAddress().port()); | |
677 | |
678 HttpRequestHeaders headers; | |
679 EXPECT_FALSE(r->GetFullRequestHeaders(&headers)); | |
680 } | |
681 } | |
682 | |
683 TEST_F(URLRequestTest, DataURLImageTest) { | |
684 TestDelegate d; | |
685 { | |
686 // Use our nice little Chrome logo. | |
687 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
688 GURL( | |
689 "data:image/png;base64," | |
690 "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADVklEQVQ4jX2TfUwUBBjG3" | |
691 "w1y+HGcd9dxhXR8T4awOccJGgOSWclHImznLkTlSw0DDQXkrmgYgbUYnlQTqQxIEVxitD" | |
692 "5UMCATRA1CEEg+Qjw3bWDxIauJv/5oumqs39/P827vnucRmYN0gyF01GI5MpCVdW0gO7t" | |
693 "vNC+vqSEtbZefk5NuLv1jdJ46p/zw0HeH4+PHr3h7c1mjoV2t5rKzMx1+fg9bAgK6zHq9" | |
694 "cU5z+LpA3xOtx34+vTeT21onRuzssC3zxbbSwC13d/pFuC7CkIMDxQpF7r/MWq12UctI1" | |
695 "dWWm99ypqSYmRUBdKem8MkrO/kgaTt1O7YzlpzE5GIVd0WYUqt57yWf2McHTObYPbVD+Z" | |
696 "wbtlLTVMZ3BW+TnLyXLaWtmEq6WJVbT3HBh3Svj2HQQcm43XwmtoYM6vVKleh0uoWvnzW" | |
697 "3v3MpidruPTQPf0bia7sJOtBM0ufTWNvus/nkDFHF9ZS+uYVjRUasMeHUmyLYtcklTvzW" | |
698 "GFZnNOXczThvpKIzjcahSqIzkvDLayDq6D3eOjtBbNUEIZYyqsvj4V4wY92eNJ4IoyhTb" | |
699 "xXX1T5xsV9tm9r4TQwHLiZw/pdDZJea8TKmsmR/K0uLh/GwnCHghTja6lPhphezPfO5/5" | |
700 "MrVvMzNaI3+ERHfrFzPKQukrQGI4d/3EFD/3E2mVNYvi4at7CXWREaxZGD+3hg28zD3gV" | |
701 "Md6q5c8GdosynKmSeRuGzpjyl1/9UDGtPR5HeaKT8Wjo17WXk579BXVUhN64ehF9fhRtq" | |
702 "/uxxZKzNiZFGD0wRC3NFROZ5mwIPL/96K/rKMMLrIzF9uhHr+/sYH7DAbwlgC4J+R2Z7F" | |
703 "Ux1qLnV7MGF40smVSoJ/jvHRfYhQeUJd/SnYtGWhPHR0Sz+GE2F2yth0B36Vcz2KpnufB" | |
704 "JbsysjjW4kblBUiIjiURUWqJY65zxbnTy57GQyH58zgy0QBtTQv5gH15XMdKkYu+TGaJM" | |
705 "nlm2O34uI4b9tflqp1+QEFGzoW/ulmcofcpkZCYJhDfSpme7QcrHa+Xfji8paEQkTkSfm" | |
706 "moRWRNZr/F1KfVMjW+IKEnv2FwZfKdzt0BQR6lClcZR0EfEXEfv/G6W9iLiIyCoReV5En" | |
707 "hORIBHx+ufPj/gLB/zGI/G4Bk0AAAAASUVORK5CYII="), | |
708 DEFAULT_PRIORITY, &d, NULL)); | |
709 | |
710 r->Start(); | |
711 EXPECT_TRUE(r->is_pending()); | |
712 | |
713 base::RunLoop().Run(); | |
714 | |
715 EXPECT_TRUE(!r->is_pending()); | |
716 EXPECT_FALSE(d.received_data_before_response()); | |
717 EXPECT_EQ(d.bytes_received(), 911); | |
718 EXPECT_EQ("", r->GetSocketAddress().host()); | |
719 EXPECT_EQ(0, r->GetSocketAddress().port()); | |
720 | |
721 HttpRequestHeaders headers; | |
722 EXPECT_FALSE(r->GetFullRequestHeaders(&headers)); | |
723 } | |
724 } | |
725 | |
726 #if !defined(DISABLE_FILE_SUPPORT) | |
727 TEST_F(URLRequestTest, FileTest) { | |
728 base::FilePath app_path; | |
729 PathService::Get(base::FILE_EXE, &app_path); | |
730 GURL app_url = FilePathToFileURL(app_path); | |
731 | |
732 TestDelegate d; | |
733 { | |
734 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
735 app_url, DEFAULT_PRIORITY, &d, NULL)); | |
736 | |
737 r->Start(); | |
738 EXPECT_TRUE(r->is_pending()); | |
739 | |
740 base::RunLoop().Run(); | |
741 | |
742 int64 file_size = -1; | |
743 EXPECT_TRUE(base::GetFileSize(app_path, &file_size)); | |
744 | |
745 EXPECT_TRUE(!r->is_pending()); | |
746 EXPECT_EQ(1, d.response_started_count()); | |
747 EXPECT_FALSE(d.received_data_before_response()); | |
748 EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); | |
749 EXPECT_EQ("", r->GetSocketAddress().host()); | |
750 EXPECT_EQ(0, r->GetSocketAddress().port()); | |
751 | |
752 HttpRequestHeaders headers; | |
753 EXPECT_FALSE(r->GetFullRequestHeaders(&headers)); | |
754 } | |
755 } | |
756 | |
757 TEST_F(URLRequestTest, FileTestCancel) { | |
758 base::FilePath app_path; | |
759 PathService::Get(base::FILE_EXE, &app_path); | |
760 GURL app_url = FilePathToFileURL(app_path); | |
761 | |
762 TestDelegate d; | |
763 { | |
764 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
765 app_url, DEFAULT_PRIORITY, &d, NULL)); | |
766 | |
767 r->Start(); | |
768 EXPECT_TRUE(r->is_pending()); | |
769 r->Cancel(); | |
770 } | |
771 // Async cancellation should be safe even when URLRequest has been already | |
772 // destroyed. | |
773 base::RunLoop().RunUntilIdle(); | |
774 } | |
775 | |
776 TEST_F(URLRequestTest, FileTestFullSpecifiedRange) { | |
777 const size_t buffer_size = 4000; | |
778 scoped_ptr<char[]> buffer(new char[buffer_size]); | |
779 FillBuffer(buffer.get(), buffer_size); | |
780 | |
781 base::FilePath temp_path; | |
782 EXPECT_TRUE(base::CreateTemporaryFile(&temp_path)); | |
783 GURL temp_url = FilePathToFileURL(temp_path); | |
784 EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size)); | |
785 | |
786 int64 file_size; | |
787 EXPECT_TRUE(base::GetFileSize(temp_path, &file_size)); | |
788 | |
789 const size_t first_byte_position = 500; | |
790 const size_t last_byte_position = buffer_size - first_byte_position; | |
791 const size_t content_length = last_byte_position - first_byte_position + 1; | |
792 std::string partial_buffer_string(buffer.get() + first_byte_position, | |
793 buffer.get() + last_byte_position + 1); | |
794 | |
795 TestDelegate d; | |
796 { | |
797 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
798 temp_url, DEFAULT_PRIORITY, &d, NULL)); | |
799 | |
800 HttpRequestHeaders headers; | |
801 headers.SetHeader( | |
802 HttpRequestHeaders::kRange, | |
803 HttpByteRange::Bounded( | |
804 first_byte_position, last_byte_position).GetHeaderValue()); | |
805 r->SetExtraRequestHeaders(headers); | |
806 r->Start(); | |
807 EXPECT_TRUE(r->is_pending()); | |
808 | |
809 base::RunLoop().Run(); | |
810 EXPECT_TRUE(!r->is_pending()); | |
811 EXPECT_EQ(1, d.response_started_count()); | |
812 EXPECT_FALSE(d.received_data_before_response()); | |
813 EXPECT_EQ(static_cast<int>(content_length), d.bytes_received()); | |
814 // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed. | |
815 EXPECT_TRUE(partial_buffer_string == d.data_received()); | |
816 } | |
817 | |
818 EXPECT_TRUE(base::DeleteFile(temp_path, false)); | |
819 } | |
820 | |
821 TEST_F(URLRequestTest, FileTestHalfSpecifiedRange) { | |
822 const size_t buffer_size = 4000; | |
823 scoped_ptr<char[]> buffer(new char[buffer_size]); | |
824 FillBuffer(buffer.get(), buffer_size); | |
825 | |
826 base::FilePath temp_path; | |
827 EXPECT_TRUE(base::CreateTemporaryFile(&temp_path)); | |
828 GURL temp_url = FilePathToFileURL(temp_path); | |
829 EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size)); | |
830 | |
831 int64 file_size; | |
832 EXPECT_TRUE(base::GetFileSize(temp_path, &file_size)); | |
833 | |
834 const size_t first_byte_position = 500; | |
835 const size_t last_byte_position = buffer_size - 1; | |
836 const size_t content_length = last_byte_position - first_byte_position + 1; | |
837 std::string partial_buffer_string(buffer.get() + first_byte_position, | |
838 buffer.get() + last_byte_position + 1); | |
839 | |
840 TestDelegate d; | |
841 { | |
842 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
843 temp_url, DEFAULT_PRIORITY, &d, NULL)); | |
844 | |
845 HttpRequestHeaders headers; | |
846 headers.SetHeader(HttpRequestHeaders::kRange, | |
847 HttpByteRange::RightUnbounded( | |
848 first_byte_position).GetHeaderValue()); | |
849 r->SetExtraRequestHeaders(headers); | |
850 r->Start(); | |
851 EXPECT_TRUE(r->is_pending()); | |
852 | |
853 base::RunLoop().Run(); | |
854 EXPECT_TRUE(!r->is_pending()); | |
855 EXPECT_EQ(1, d.response_started_count()); | |
856 EXPECT_FALSE(d.received_data_before_response()); | |
857 EXPECT_EQ(static_cast<int>(content_length), d.bytes_received()); | |
858 // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed. | |
859 EXPECT_TRUE(partial_buffer_string == d.data_received()); | |
860 } | |
861 | |
862 EXPECT_TRUE(base::DeleteFile(temp_path, false)); | |
863 } | |
864 | |
865 TEST_F(URLRequestTest, FileTestMultipleRanges) { | |
866 const size_t buffer_size = 400000; | |
867 scoped_ptr<char[]> buffer(new char[buffer_size]); | |
868 FillBuffer(buffer.get(), buffer_size); | |
869 | |
870 base::FilePath temp_path; | |
871 EXPECT_TRUE(base::CreateTemporaryFile(&temp_path)); | |
872 GURL temp_url = FilePathToFileURL(temp_path); | |
873 EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size)); | |
874 | |
875 int64 file_size; | |
876 EXPECT_TRUE(base::GetFileSize(temp_path, &file_size)); | |
877 | |
878 TestDelegate d; | |
879 { | |
880 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
881 temp_url, DEFAULT_PRIORITY, &d, NULL)); | |
882 | |
883 HttpRequestHeaders headers; | |
884 headers.SetHeader(HttpRequestHeaders::kRange, "bytes=0-0,10-200,200-300"); | |
885 r->SetExtraRequestHeaders(headers); | |
886 r->Start(); | |
887 EXPECT_TRUE(r->is_pending()); | |
888 | |
889 base::RunLoop().Run(); | |
890 EXPECT_TRUE(d.request_failed()); | |
891 } | |
892 | |
893 EXPECT_TRUE(base::DeleteFile(temp_path, false)); | |
894 } | |
895 | |
896 TEST_F(URLRequestTest, AllowFileURLs) { | |
897 base::ScopedTempDir temp_dir; | |
898 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
899 base::FilePath test_file; | |
900 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), &test_file)); | |
901 std::string test_data("monkey"); | |
902 base::WriteFile(test_file, test_data.data(), test_data.size()); | |
903 GURL test_file_url = FilePathToFileURL(test_file); | |
904 | |
905 { | |
906 TestDelegate d; | |
907 TestNetworkDelegate network_delegate; | |
908 network_delegate.set_can_access_files(true); | |
909 default_context_.set_network_delegate(&network_delegate); | |
910 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
911 test_file_url, DEFAULT_PRIORITY, &d, NULL)); | |
912 r->Start(); | |
913 base::RunLoop().Run(); | |
914 EXPECT_FALSE(d.request_failed()); | |
915 EXPECT_EQ(test_data, d.data_received()); | |
916 } | |
917 | |
918 { | |
919 TestDelegate d; | |
920 TestNetworkDelegate network_delegate; | |
921 network_delegate.set_can_access_files(false); | |
922 default_context_.set_network_delegate(&network_delegate); | |
923 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
924 test_file_url, DEFAULT_PRIORITY, &d, NULL)); | |
925 r->Start(); | |
926 base::RunLoop().Run(); | |
927 EXPECT_TRUE(d.request_failed()); | |
928 EXPECT_EQ("", d.data_received()); | |
929 } | |
930 } | |
931 | |
932 | |
933 TEST_F(URLRequestTest, FileDirCancelTest) { | |
934 // Put in mock resource provider. | |
935 NetModule::SetResourceProvider(TestNetResourceProvider); | |
936 | |
937 TestDelegate d; | |
938 { | |
939 base::FilePath file_path; | |
940 PathService::Get(base::DIR_SOURCE_ROOT, &file_path); | |
941 file_path = file_path.Append(FILE_PATH_LITERAL("net")); | |
942 file_path = file_path.Append(FILE_PATH_LITERAL("data")); | |
943 | |
944 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
945 FilePathToFileURL(file_path), DEFAULT_PRIORITY, &d, NULL)); | |
946 req->Start(); | |
947 EXPECT_TRUE(req->is_pending()); | |
948 | |
949 d.set_cancel_in_received_data_pending(true); | |
950 | |
951 base::RunLoop().Run(); | |
952 } | |
953 | |
954 // Take out mock resource provider. | |
955 NetModule::SetResourceProvider(NULL); | |
956 } | |
957 | |
958 TEST_F(URLRequestTest, FileDirOutputSanity) { | |
959 // Verify the general sanity of the the output of the file: | |
960 // directory lister by checking for the output of a known existing | |
961 // file. | |
962 const char sentinel_name[] = "filedir-sentinel"; | |
963 | |
964 base::FilePath path; | |
965 PathService::Get(base::DIR_SOURCE_ROOT, &path); | |
966 path = path.Append(FILE_PATH_LITERAL("net")); | |
967 path = path.Append(FILE_PATH_LITERAL("data")); | |
968 path = path.Append(FILE_PATH_LITERAL("url_request_unittest")); | |
969 | |
970 TestDelegate d; | |
971 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
972 FilePathToFileURL(path), DEFAULT_PRIORITY, &d, NULL)); | |
973 req->Start(); | |
974 base::RunLoop().Run(); | |
975 | |
976 // Generate entry for the sentinel file. | |
977 base::FilePath sentinel_path = path.AppendASCII(sentinel_name); | |
978 base::File::Info info; | |
979 EXPECT_TRUE(base::GetFileInfo(sentinel_path, &info)); | |
980 EXPECT_GT(info.size, 0); | |
981 std::string sentinel_output = GetDirectoryListingEntry( | |
982 base::string16(sentinel_name, sentinel_name + strlen(sentinel_name)), | |
983 std::string(sentinel_name), | |
984 false /* is_dir */, | |
985 info.size, | |
986 info.last_modified); | |
987 | |
988 ASSERT_LT(0, d.bytes_received()); | |
989 ASSERT_FALSE(d.request_failed()); | |
990 ASSERT_TRUE(req->status().is_success()); | |
991 // Check for the entry generated for the "sentinel" file. | |
992 const std::string& data = d.data_received(); | |
993 ASSERT_NE(data.find(sentinel_output), std::string::npos); | |
994 } | |
995 | |
996 TEST_F(URLRequestTest, FileDirRedirectNoCrash) { | |
997 // There is an implicit redirect when loading a file path that matches a | |
998 // directory and does not end with a slash. Ensure that following such | |
999 // redirects does not crash. See http://crbug.com/18686. | |
1000 | |
1001 base::FilePath path; | |
1002 PathService::Get(base::DIR_SOURCE_ROOT, &path); | |
1003 path = path.Append(FILE_PATH_LITERAL("net")); | |
1004 path = path.Append(FILE_PATH_LITERAL("data")); | |
1005 path = path.Append(FILE_PATH_LITERAL("url_request_unittest")); | |
1006 | |
1007 TestDelegate d; | |
1008 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
1009 FilePathToFileURL(path), DEFAULT_PRIORITY, &d, NULL)); | |
1010 req->Start(); | |
1011 base::RunLoop().Run(); | |
1012 | |
1013 ASSERT_EQ(1, d.received_redirect_count()); | |
1014 ASSERT_LT(0, d.bytes_received()); | |
1015 ASSERT_FALSE(d.request_failed()); | |
1016 ASSERT_TRUE(req->status().is_success()); | |
1017 } | |
1018 | |
1019 #if defined(OS_WIN) | |
1020 // Don't accept the url "file:///" on windows. See http://crbug.com/1474. | |
1021 TEST_F(URLRequestTest, FileDirRedirectSingleSlash) { | |
1022 TestDelegate d; | |
1023 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
1024 GURL("file:///"), DEFAULT_PRIORITY, &d, NULL)); | |
1025 req->Start(); | |
1026 base::RunLoop().Run(); | |
1027 | |
1028 ASSERT_EQ(1, d.received_redirect_count()); | |
1029 ASSERT_FALSE(req->status().is_success()); | |
1030 } | |
1031 #endif // defined(OS_WIN) | |
1032 | |
1033 #endif // !defined(DISABLE_FILE_SUPPORT) | |
1034 | |
1035 TEST_F(URLRequestTest, InvalidUrlTest) { | |
1036 TestDelegate d; | |
1037 { | |
1038 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
1039 GURL("invalid url"), DEFAULT_PRIORITY, &d, NULL)); | |
1040 | |
1041 r->Start(); | |
1042 EXPECT_TRUE(r->is_pending()); | |
1043 | |
1044 base::RunLoop().Run(); | |
1045 EXPECT_TRUE(d.request_failed()); | |
1046 } | |
1047 } | |
1048 | |
1049 TEST_F(URLRequestTest, InvalidReferrerTest) { | |
1050 TestURLRequestContext context; | |
1051 TestNetworkDelegate network_delegate; | |
1052 network_delegate.set_cancel_request_with_policy_violating_referrer(true); | |
1053 context.set_network_delegate(&network_delegate); | |
1054 TestDelegate d; | |
1055 scoped_ptr<URLRequest> req(context.CreateRequest( | |
1056 GURL("http://localhost/"), DEFAULT_PRIORITY, &d, NULL)); | |
1057 req->SetReferrer("https://somewhere.com/"); | |
1058 | |
1059 req->Start(); | |
1060 base::RunLoop().Run(); | |
1061 EXPECT_TRUE(d.request_failed()); | |
1062 } | |
1063 | |
1064 #if defined(OS_WIN) | |
1065 TEST_F(URLRequestTest, ResolveShortcutTest) { | |
1066 base::FilePath app_path; | |
1067 PathService::Get(base::DIR_SOURCE_ROOT, &app_path); | |
1068 app_path = app_path.AppendASCII("net"); | |
1069 app_path = app_path.AppendASCII("data"); | |
1070 app_path = app_path.AppendASCII("url_request_unittest"); | |
1071 app_path = app_path.AppendASCII("with-headers.html"); | |
1072 | |
1073 std::wstring lnk_path = app_path.value() + L".lnk"; | |
1074 | |
1075 base::win::ScopedCOMInitializer com_initializer; | |
1076 | |
1077 // Temporarily create a shortcut for test | |
1078 { | |
1079 base::win::ScopedComPtr<IShellLink> shell; | |
1080 ASSERT_TRUE(SUCCEEDED(shell.CreateInstance(CLSID_ShellLink, NULL, | |
1081 CLSCTX_INPROC_SERVER))); | |
1082 base::win::ScopedComPtr<IPersistFile> persist; | |
1083 ASSERT_TRUE(SUCCEEDED(shell.QueryInterface(persist.Receive()))); | |
1084 EXPECT_TRUE(SUCCEEDED(shell->SetPath(app_path.value().c_str()))); | |
1085 EXPECT_TRUE(SUCCEEDED(shell->SetDescription(L"ResolveShortcutTest"))); | |
1086 EXPECT_TRUE(SUCCEEDED(persist->Save(lnk_path.c_str(), TRUE))); | |
1087 } | |
1088 | |
1089 TestDelegate d; | |
1090 { | |
1091 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
1092 FilePathToFileURL(base::FilePath(lnk_path)), DEFAULT_PRIORITY, &d, | |
1093 NULL)); | |
1094 | |
1095 r->Start(); | |
1096 EXPECT_TRUE(r->is_pending()); | |
1097 | |
1098 base::RunLoop().Run(); | |
1099 | |
1100 WIN32_FILE_ATTRIBUTE_DATA data; | |
1101 GetFileAttributesEx(app_path.value().c_str(), | |
1102 GetFileExInfoStandard, &data); | |
1103 HANDLE file = CreateFile(app_path.value().c_str(), GENERIC_READ, | |
1104 FILE_SHARE_READ, NULL, OPEN_EXISTING, | |
1105 FILE_ATTRIBUTE_NORMAL, NULL); | |
1106 EXPECT_NE(INVALID_HANDLE_VALUE, file); | |
1107 scoped_ptr<char[]> buffer(new char[data.nFileSizeLow]); | |
1108 DWORD read_size; | |
1109 BOOL result; | |
1110 result = ReadFile(file, buffer.get(), data.nFileSizeLow, | |
1111 &read_size, NULL); | |
1112 std::string content(buffer.get(), read_size); | |
1113 CloseHandle(file); | |
1114 | |
1115 EXPECT_TRUE(!r->is_pending()); | |
1116 EXPECT_EQ(1, d.received_redirect_count()); | |
1117 EXPECT_EQ(content, d.data_received()); | |
1118 } | |
1119 | |
1120 // Clean the shortcut | |
1121 DeleteFile(lnk_path.c_str()); | |
1122 } | |
1123 #endif // defined(OS_WIN) | |
1124 | |
1125 // Custom URLRequestJobs for use with interceptor tests | |
1126 class RestartTestJob : public URLRequestTestJob { | |
1127 public: | |
1128 RestartTestJob(URLRequest* request, NetworkDelegate* network_delegate) | |
1129 : URLRequestTestJob(request, network_delegate, true) {} | |
1130 protected: | |
1131 void StartAsync() override { this->NotifyRestartRequired(); } | |
1132 private: | |
1133 ~RestartTestJob() override {} | |
1134 }; | |
1135 | |
1136 class CancelTestJob : public URLRequestTestJob { | |
1137 public: | |
1138 explicit CancelTestJob(URLRequest* request, NetworkDelegate* network_delegate) | |
1139 : URLRequestTestJob(request, network_delegate, true) {} | |
1140 protected: | |
1141 void StartAsync() override { request_->Cancel(); } | |
1142 private: | |
1143 ~CancelTestJob() override {} | |
1144 }; | |
1145 | |
1146 class CancelThenRestartTestJob : public URLRequestTestJob { | |
1147 public: | |
1148 explicit CancelThenRestartTestJob(URLRequest* request, | |
1149 NetworkDelegate* network_delegate) | |
1150 : URLRequestTestJob(request, network_delegate, true) { | |
1151 } | |
1152 protected: | |
1153 void StartAsync() override { | |
1154 request_->Cancel(); | |
1155 this->NotifyRestartRequired(); | |
1156 } | |
1157 private: | |
1158 ~CancelThenRestartTestJob() override {} | |
1159 }; | |
1160 | |
1161 // An Interceptor for use with interceptor tests. | |
1162 class MockURLRequestInterceptor : public URLRequestInterceptor { | |
1163 public: | |
1164 // Static getters for canned response header and data strings. | |
1165 static std::string ok_data() { | |
1166 return URLRequestTestJob::test_data_1(); | |
1167 } | |
1168 | |
1169 static std::string ok_headers() { | |
1170 return URLRequestTestJob::test_headers(); | |
1171 } | |
1172 | |
1173 static std::string redirect_data() { | |
1174 return std::string(); | |
1175 } | |
1176 | |
1177 static std::string redirect_headers() { | |
1178 return URLRequestTestJob::test_redirect_headers(); | |
1179 } | |
1180 | |
1181 static std::string error_data() { | |
1182 return std::string("ohhh nooooo mr. bill!"); | |
1183 } | |
1184 | |
1185 static std::string error_headers() { | |
1186 return URLRequestTestJob::test_error_headers(); | |
1187 } | |
1188 | |
1189 MockURLRequestInterceptor() | |
1190 : intercept_main_request_(false), restart_main_request_(false), | |
1191 cancel_main_request_(false), cancel_then_restart_main_request_(false), | |
1192 simulate_main_network_error_(false), | |
1193 intercept_redirect_(false), cancel_redirect_request_(false), | |
1194 intercept_final_response_(false), cancel_final_request_(false), | |
1195 use_url_request_http_job_(false), | |
1196 did_intercept_main_(false), did_restart_main_(false), | |
1197 did_cancel_main_(false), did_cancel_then_restart_main_(false), | |
1198 did_simulate_error_main_(false), | |
1199 did_intercept_redirect_(false), did_cancel_redirect_(false), | |
1200 did_intercept_final_(false), did_cancel_final_(false) { | |
1201 } | |
1202 | |
1203 ~MockURLRequestInterceptor() override { | |
1204 } | |
1205 | |
1206 // URLRequestInterceptor implementation: | |
1207 URLRequestJob* MaybeInterceptRequest( | |
1208 URLRequest* request, | |
1209 NetworkDelegate* network_delegate) const override { | |
1210 if (restart_main_request_) { | |
1211 restart_main_request_ = false; | |
1212 did_restart_main_ = true; | |
1213 return new RestartTestJob(request, network_delegate); | |
1214 } | |
1215 if (cancel_main_request_) { | |
1216 cancel_main_request_ = false; | |
1217 did_cancel_main_ = true; | |
1218 return new CancelTestJob(request, network_delegate); | |
1219 } | |
1220 if (cancel_then_restart_main_request_) { | |
1221 cancel_then_restart_main_request_ = false; | |
1222 did_cancel_then_restart_main_ = true; | |
1223 return new CancelThenRestartTestJob(request, network_delegate); | |
1224 } | |
1225 if (simulate_main_network_error_) { | |
1226 simulate_main_network_error_ = false; | |
1227 did_simulate_error_main_ = true; | |
1228 if (use_url_request_http_job_) { | |
1229 return URLRequestHttpJob::Factory(request, network_delegate, "http"); | |
1230 } | |
1231 // This job will result in error since the requested URL is not one of the | |
1232 // URLs supported by these tests. | |
1233 return new URLRequestTestJob(request, network_delegate, true); | |
1234 } | |
1235 if (!intercept_main_request_) | |
1236 return nullptr; | |
1237 intercept_main_request_ = false; | |
1238 did_intercept_main_ = true; | |
1239 URLRequestTestJob* job = new URLRequestTestJob(request, | |
1240 network_delegate, | |
1241 main_headers_, | |
1242 main_data_, | |
1243 true); | |
1244 job->set_load_timing_info(main_request_load_timing_info_); | |
1245 return job; | |
1246 } | |
1247 | |
1248 URLRequestJob* MaybeInterceptRedirect(URLRequest* request, | |
1249 NetworkDelegate* network_delegate, | |
1250 const GURL& location) const override { | |
1251 if (cancel_redirect_request_) { | |
1252 cancel_redirect_request_ = false; | |
1253 did_cancel_redirect_ = true; | |
1254 return new CancelTestJob(request, network_delegate); | |
1255 } | |
1256 if (!intercept_redirect_) | |
1257 return nullptr; | |
1258 intercept_redirect_ = false; | |
1259 did_intercept_redirect_ = true; | |
1260 if (use_url_request_http_job_) { | |
1261 return URLRequestHttpJob::Factory(request, network_delegate, "http"); | |
1262 } | |
1263 return new URLRequestTestJob(request, | |
1264 network_delegate, | |
1265 redirect_headers_, | |
1266 redirect_data_, | |
1267 true); | |
1268 } | |
1269 | |
1270 URLRequestJob* MaybeInterceptResponse( | |
1271 URLRequest* request, | |
1272 NetworkDelegate* network_delegate) const override { | |
1273 if (cancel_final_request_) { | |
1274 cancel_final_request_ = false; | |
1275 did_cancel_final_ = true; | |
1276 return new CancelTestJob(request, network_delegate); | |
1277 } | |
1278 if (!intercept_final_response_) | |
1279 return nullptr; | |
1280 intercept_final_response_ = false; | |
1281 did_intercept_final_ = true; | |
1282 if (use_url_request_http_job_) { | |
1283 return URLRequestHttpJob::Factory(request, network_delegate, "http"); | |
1284 } | |
1285 return new URLRequestTestJob(request, | |
1286 network_delegate, | |
1287 final_headers_, | |
1288 final_data_, | |
1289 true); | |
1290 } | |
1291 | |
1292 void set_intercept_main_request(bool intercept_main_request) { | |
1293 intercept_main_request_ = intercept_main_request; | |
1294 } | |
1295 | |
1296 void set_main_headers(const std::string& main_headers) { | |
1297 main_headers_ = main_headers; | |
1298 } | |
1299 | |
1300 void set_main_data(const std::string& main_data) { | |
1301 main_data_ = main_data; | |
1302 } | |
1303 | |
1304 void set_main_request_load_timing_info( | |
1305 const LoadTimingInfo& main_request_load_timing_info) { | |
1306 main_request_load_timing_info_ = main_request_load_timing_info; | |
1307 } | |
1308 | |
1309 void set_restart_main_request(bool restart_main_request) { | |
1310 restart_main_request_ = restart_main_request; | |
1311 } | |
1312 | |
1313 void set_cancel_main_request(bool cancel_main_request) { | |
1314 cancel_main_request_ = cancel_main_request; | |
1315 } | |
1316 | |
1317 void set_cancel_then_restart_main_request( | |
1318 bool cancel_then_restart_main_request) { | |
1319 cancel_then_restart_main_request_ = cancel_then_restart_main_request; | |
1320 } | |
1321 | |
1322 void set_simulate_main_network_error(bool simulate_main_network_error) { | |
1323 simulate_main_network_error_ = simulate_main_network_error; | |
1324 } | |
1325 | |
1326 void set_intercept_redirect(bool intercept_redirect) { | |
1327 intercept_redirect_ = intercept_redirect; | |
1328 } | |
1329 | |
1330 void set_redirect_headers(const std::string& redirect_headers) { | |
1331 redirect_headers_ = redirect_headers; | |
1332 } | |
1333 | |
1334 void set_redirect_data(const std::string& redirect_data) { | |
1335 redirect_data_ = redirect_data; | |
1336 } | |
1337 | |
1338 void set_cancel_redirect_request(bool cancel_redirect_request) { | |
1339 cancel_redirect_request_ = cancel_redirect_request; | |
1340 } | |
1341 | |
1342 void set_intercept_final_response(bool intercept_final_response) { | |
1343 intercept_final_response_ = intercept_final_response; | |
1344 } | |
1345 | |
1346 void set_final_headers(const std::string& final_headers) { | |
1347 final_headers_ = final_headers; | |
1348 } | |
1349 | |
1350 void set_final_data(const std::string& final_data) { | |
1351 final_data_ = final_data; | |
1352 } | |
1353 | |
1354 void set_cancel_final_request(bool cancel_final_request) { | |
1355 cancel_final_request_ = cancel_final_request; | |
1356 } | |
1357 | |
1358 void set_use_url_request_http_job(bool use_url_request_http_job) { | |
1359 use_url_request_http_job_ = use_url_request_http_job; | |
1360 } | |
1361 | |
1362 bool did_intercept_main() const { | |
1363 return did_intercept_main_; | |
1364 } | |
1365 | |
1366 bool did_restart_main() const { | |
1367 return did_restart_main_; | |
1368 } | |
1369 | |
1370 bool did_cancel_main() const { | |
1371 return did_cancel_main_; | |
1372 } | |
1373 | |
1374 bool did_cancel_then_restart_main() const { | |
1375 return did_cancel_then_restart_main_; | |
1376 } | |
1377 | |
1378 bool did_simulate_error_main() const { | |
1379 return did_simulate_error_main_; | |
1380 } | |
1381 | |
1382 bool did_intercept_redirect() const { | |
1383 return did_intercept_redirect_; | |
1384 } | |
1385 | |
1386 bool did_cancel_redirect() const { | |
1387 return did_cancel_redirect_; | |
1388 } | |
1389 | |
1390 bool did_intercept_final() const { | |
1391 return did_intercept_final_; | |
1392 } | |
1393 | |
1394 bool did_cancel_final() const { | |
1395 return did_cancel_final_; | |
1396 } | |
1397 | |
1398 private: | |
1399 // Indicate whether to intercept the main request, and if so specify the | |
1400 // response to return and the LoadTimingInfo to use. | |
1401 mutable bool intercept_main_request_; | |
1402 mutable std::string main_headers_; | |
1403 mutable std::string main_data_; | |
1404 mutable LoadTimingInfo main_request_load_timing_info_; | |
1405 | |
1406 // These indicate actions that can be taken within MaybeInterceptRequest. | |
1407 mutable bool restart_main_request_; | |
1408 mutable bool cancel_main_request_; | |
1409 mutable bool cancel_then_restart_main_request_; | |
1410 mutable bool simulate_main_network_error_; | |
1411 | |
1412 // Indicate whether to intercept redirects, and if so specify the response to | |
1413 // return. | |
1414 mutable bool intercept_redirect_; | |
1415 mutable std::string redirect_headers_; | |
1416 mutable std::string redirect_data_; | |
1417 | |
1418 // Cancel the request within MaybeInterceptRedirect. | |
1419 mutable bool cancel_redirect_request_; | |
1420 | |
1421 // Indicate whether to intercept the final response, and if so specify the | |
1422 // response to return. | |
1423 mutable bool intercept_final_response_; | |
1424 mutable std::string final_headers_; | |
1425 mutable std::string final_data_; | |
1426 | |
1427 // Cancel the final request within MaybeInterceptResponse. | |
1428 mutable bool cancel_final_request_; | |
1429 | |
1430 // Instruct the interceptor to use a real URLRequestHTTPJob. | |
1431 mutable bool use_url_request_http_job_; | |
1432 | |
1433 // These indicate if the interceptor did something or not. | |
1434 mutable bool did_intercept_main_; | |
1435 mutable bool did_restart_main_; | |
1436 mutable bool did_cancel_main_; | |
1437 mutable bool did_cancel_then_restart_main_; | |
1438 mutable bool did_simulate_error_main_; | |
1439 mutable bool did_intercept_redirect_; | |
1440 mutable bool did_cancel_redirect_; | |
1441 mutable bool did_intercept_final_; | |
1442 mutable bool did_cancel_final_; | |
1443 }; | |
1444 | |
1445 // Inherit PlatformTest since we require the autorelease pool on Mac OS X. | |
1446 class URLRequestInterceptorTest : public URLRequestTest { | |
1447 public: | |
1448 URLRequestInterceptorTest() : URLRequestTest(), interceptor_(NULL) { | |
1449 } | |
1450 | |
1451 ~URLRequestInterceptorTest() override { | |
1452 // URLRequestJobs may post clean-up tasks on destruction. | |
1453 base::RunLoop().RunUntilIdle(); | |
1454 } | |
1455 | |
1456 void SetUpFactory() override { | |
1457 interceptor_ = new MockURLRequestInterceptor(); | |
1458 job_factory_.reset(new URLRequestInterceptingJobFactory( | |
1459 job_factory_.Pass(), make_scoped_ptr(interceptor_))); | |
1460 } | |
1461 | |
1462 MockURLRequestInterceptor* interceptor() const { | |
1463 return interceptor_; | |
1464 } | |
1465 | |
1466 private: | |
1467 MockURLRequestInterceptor* interceptor_; | |
1468 }; | |
1469 | |
1470 TEST_F(URLRequestInterceptorTest, Intercept) { | |
1471 // Intercept the main request and respond with a simple response. | |
1472 interceptor()->set_intercept_main_request(true); | |
1473 interceptor()->set_main_headers(MockURLRequestInterceptor::ok_headers()); | |
1474 interceptor()->set_main_data(MockURLRequestInterceptor::ok_data()); | |
1475 TestDelegate d; | |
1476 scoped_ptr<URLRequest> req(default_context().CreateRequest( | |
1477 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); | |
1478 base::SupportsUserData::Data* user_data0 = new base::SupportsUserData::Data(); | |
1479 base::SupportsUserData::Data* user_data1 = new base::SupportsUserData::Data(); | |
1480 base::SupportsUserData::Data* user_data2 = new base::SupportsUserData::Data(); | |
1481 req->SetUserData(nullptr, user_data0); | |
1482 req->SetUserData(&user_data1, user_data1); | |
1483 req->SetUserData(&user_data2, user_data2); | |
1484 req->set_method("GET"); | |
1485 req->Start(); | |
1486 base::RunLoop().Run(); | |
1487 | |
1488 // Make sure we can retrieve our specific user data. | |
1489 EXPECT_EQ(user_data0, req->GetUserData(nullptr)); | |
1490 EXPECT_EQ(user_data1, req->GetUserData(&user_data1)); | |
1491 EXPECT_EQ(user_data2, req->GetUserData(&user_data2)); | |
1492 | |
1493 // Check that we got one good response. | |
1494 EXPECT_TRUE(req->status().is_success()); | |
1495 EXPECT_EQ(200, req->response_headers()->response_code()); | |
1496 EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); | |
1497 EXPECT_EQ(1, d.response_started_count()); | |
1498 EXPECT_EQ(0, d.received_redirect_count()); | |
1499 } | |
1500 | |
1501 TEST_F(URLRequestInterceptorTest, InterceptRedirect) { | |
1502 // Intercept the main request and respond with a redirect. | |
1503 interceptor()->set_intercept_main_request(true); | |
1504 interceptor()->set_main_headers( | |
1505 MockURLRequestInterceptor::redirect_headers()); | |
1506 interceptor()->set_main_data(MockURLRequestInterceptor::redirect_data()); | |
1507 | |
1508 // Intercept that redirect and respond with a final OK response. | |
1509 interceptor()->set_intercept_redirect(true); | |
1510 interceptor()->set_redirect_headers(MockURLRequestInterceptor::ok_headers()); | |
1511 interceptor()->set_redirect_data(MockURLRequestInterceptor::ok_data()); | |
1512 | |
1513 TestDelegate d; | |
1514 scoped_ptr<URLRequest> req(default_context().CreateRequest( | |
1515 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); | |
1516 req->set_method("GET"); | |
1517 req->Start(); | |
1518 base::RunLoop().Run(); | |
1519 | |
1520 // Check that the interceptor got called as expected. | |
1521 EXPECT_TRUE(interceptor()->did_intercept_main()); | |
1522 EXPECT_TRUE(interceptor()->did_intercept_redirect()); | |
1523 | |
1524 // Check that we got one good response. | |
1525 EXPECT_TRUE(req->status().is_success()); | |
1526 if (req->status().is_success()) | |
1527 EXPECT_EQ(200, req->response_headers()->response_code()); | |
1528 | |
1529 EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); | |
1530 EXPECT_EQ(1, d.response_started_count()); | |
1531 EXPECT_EQ(0, d.received_redirect_count()); | |
1532 } | |
1533 | |
1534 TEST_F(URLRequestInterceptorTest, InterceptServerError) { | |
1535 // Intercept the main request to generate a server error response. | |
1536 interceptor()->set_intercept_main_request(true); | |
1537 interceptor()->set_main_headers(MockURLRequestInterceptor::error_headers()); | |
1538 interceptor()->set_main_data(MockURLRequestInterceptor::error_data()); | |
1539 | |
1540 // Intercept that error and respond with an OK response. | |
1541 interceptor()->set_intercept_final_response(true); | |
1542 interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers()); | |
1543 interceptor()->set_final_data(MockURLRequestInterceptor::ok_data()); | |
1544 | |
1545 TestDelegate d; | |
1546 scoped_ptr<URLRequest> req(default_context().CreateRequest( | |
1547 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); | |
1548 req->set_method("GET"); | |
1549 req->Start(); | |
1550 base::RunLoop().Run(); | |
1551 | |
1552 // Check that the interceptor got called as expected. | |
1553 EXPECT_TRUE(interceptor()->did_intercept_main()); | |
1554 EXPECT_TRUE(interceptor()->did_intercept_final()); | |
1555 | |
1556 // Check that we got one good response. | |
1557 EXPECT_TRUE(req->status().is_success()); | |
1558 EXPECT_EQ(200, req->response_headers()->response_code()); | |
1559 EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); | |
1560 EXPECT_EQ(1, d.response_started_count()); | |
1561 EXPECT_EQ(0, d.received_redirect_count()); | |
1562 } | |
1563 | |
1564 TEST_F(URLRequestInterceptorTest, InterceptNetworkError) { | |
1565 // Intercept the main request to simulate a network error. | |
1566 interceptor()->set_simulate_main_network_error(true); | |
1567 | |
1568 // Intercept that error and respond with an OK response. | |
1569 interceptor()->set_intercept_final_response(true); | |
1570 interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers()); | |
1571 interceptor()->set_final_data(MockURLRequestInterceptor::ok_data()); | |
1572 | |
1573 TestDelegate d; | |
1574 scoped_ptr<URLRequest> req(default_context().CreateRequest( | |
1575 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); | |
1576 req->set_method("GET"); | |
1577 req->Start(); | |
1578 base::RunLoop().Run(); | |
1579 | |
1580 // Check that the interceptor got called as expected. | |
1581 EXPECT_TRUE(interceptor()->did_simulate_error_main()); | |
1582 EXPECT_TRUE(interceptor()->did_intercept_final()); | |
1583 | |
1584 // Check that we received one good response. | |
1585 EXPECT_TRUE(req->status().is_success()); | |
1586 EXPECT_EQ(200, req->response_headers()->response_code()); | |
1587 EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); | |
1588 EXPECT_EQ(1, d.response_started_count()); | |
1589 EXPECT_EQ(0, d.received_redirect_count()); | |
1590 } | |
1591 | |
1592 TEST_F(URLRequestInterceptorTest, InterceptRestartRequired) { | |
1593 // Restart the main request. | |
1594 interceptor()->set_restart_main_request(true); | |
1595 | |
1596 // then intercept the new main request and respond with an OK response | |
1597 interceptor()->set_intercept_main_request(true); | |
1598 interceptor()->set_main_headers(MockURLRequestInterceptor::ok_headers()); | |
1599 interceptor()->set_main_data(MockURLRequestInterceptor::ok_data()); | |
1600 | |
1601 TestDelegate d; | |
1602 scoped_ptr<URLRequest> req(default_context().CreateRequest( | |
1603 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); | |
1604 req->set_method("GET"); | |
1605 req->Start(); | |
1606 base::RunLoop().Run(); | |
1607 | |
1608 // Check that the interceptor got called as expected. | |
1609 EXPECT_TRUE(interceptor()->did_restart_main()); | |
1610 EXPECT_TRUE(interceptor()->did_intercept_main()); | |
1611 | |
1612 // Check that we received one good response. | |
1613 EXPECT_TRUE(req->status().is_success()); | |
1614 if (req->status().is_success()) | |
1615 EXPECT_EQ(200, req->response_headers()->response_code()); | |
1616 | |
1617 EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); | |
1618 EXPECT_EQ(1, d.response_started_count()); | |
1619 EXPECT_EQ(0, d.received_redirect_count()); | |
1620 } | |
1621 | |
1622 TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelMain) { | |
1623 // Intercept the main request and cancel from within the restarted job. | |
1624 interceptor()->set_cancel_main_request(true); | |
1625 | |
1626 // Set up to intercept the final response and override it with an OK response. | |
1627 interceptor()->set_intercept_final_response(true); | |
1628 interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers()); | |
1629 interceptor()->set_final_data(MockURLRequestInterceptor::ok_data()); | |
1630 | |
1631 TestDelegate d; | |
1632 scoped_ptr<URLRequest> req(default_context().CreateRequest( | |
1633 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); | |
1634 req->set_method("GET"); | |
1635 req->Start(); | |
1636 base::RunLoop().Run(); | |
1637 | |
1638 // Check that the interceptor got called as expected. | |
1639 EXPECT_TRUE(interceptor()->did_cancel_main()); | |
1640 EXPECT_FALSE(interceptor()->did_intercept_final()); | |
1641 | |
1642 // Check that we see a canceled request. | |
1643 EXPECT_FALSE(req->status().is_success()); | |
1644 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); | |
1645 } | |
1646 | |
1647 TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelRedirect) { | |
1648 // Intercept the main request and respond with a redirect. | |
1649 interceptor()->set_intercept_main_request(true); | |
1650 interceptor()->set_main_headers( | |
1651 MockURLRequestInterceptor::redirect_headers()); | |
1652 interceptor()->set_main_data(MockURLRequestInterceptor::redirect_data()); | |
1653 | |
1654 // Intercept the redirect and cancel from within that job. | |
1655 interceptor()->set_cancel_redirect_request(true); | |
1656 | |
1657 // Set up to intercept the final response and override it with an OK response. | |
1658 interceptor()->set_intercept_final_response(true); | |
1659 interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers()); | |
1660 interceptor()->set_final_data(MockURLRequestInterceptor::ok_data()); | |
1661 | |
1662 TestDelegate d; | |
1663 scoped_ptr<URLRequest> req(default_context().CreateRequest( | |
1664 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); | |
1665 req->set_method("GET"); | |
1666 req->Start(); | |
1667 base::RunLoop().Run(); | |
1668 | |
1669 // Check that the interceptor got called as expected. | |
1670 EXPECT_TRUE(interceptor()->did_intercept_main()); | |
1671 EXPECT_TRUE(interceptor()->did_cancel_redirect()); | |
1672 EXPECT_FALSE(interceptor()->did_intercept_final()); | |
1673 | |
1674 // Check that we see a canceled request. | |
1675 EXPECT_FALSE(req->status().is_success()); | |
1676 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); | |
1677 } | |
1678 | |
1679 TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelFinal) { | |
1680 // Intercept the main request to simulate a network error. | |
1681 interceptor()->set_simulate_main_network_error(true); | |
1682 | |
1683 // Set up to intercept final the response and cancel from within that job. | |
1684 interceptor()->set_cancel_final_request(true); | |
1685 | |
1686 TestDelegate d; | |
1687 scoped_ptr<URLRequest> req(default_context().CreateRequest( | |
1688 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); | |
1689 req->set_method("GET"); | |
1690 req->Start(); | |
1691 base::RunLoop().Run(); | |
1692 | |
1693 // Check that the interceptor got called as expected. | |
1694 EXPECT_TRUE(interceptor()->did_simulate_error_main()); | |
1695 EXPECT_TRUE(interceptor()->did_cancel_final()); | |
1696 | |
1697 // Check that we see a canceled request. | |
1698 EXPECT_FALSE(req->status().is_success()); | |
1699 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); | |
1700 } | |
1701 | |
1702 TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelInRestart) { | |
1703 // Intercept the main request and cancel then restart from within that job. | |
1704 interceptor()->set_cancel_then_restart_main_request(true); | |
1705 | |
1706 // Set up to intercept the final response and override it with an OK response. | |
1707 interceptor()->set_intercept_final_response(true); | |
1708 interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers()); | |
1709 interceptor()->set_final_data(MockURLRequestInterceptor::ok_data()); | |
1710 | |
1711 TestDelegate d; | |
1712 scoped_ptr<URLRequest> req(default_context().CreateRequest( | |
1713 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); | |
1714 req->set_method("GET"); | |
1715 req->Start(); | |
1716 base::RunLoop().Run(); | |
1717 | |
1718 // Check that the interceptor got called as expected. | |
1719 EXPECT_TRUE(interceptor()->did_cancel_then_restart_main()); | |
1720 EXPECT_FALSE(interceptor()->did_intercept_final()); | |
1721 | |
1722 // Check that we see a canceled request. | |
1723 EXPECT_FALSE(req->status().is_success()); | |
1724 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); | |
1725 } | |
1726 | |
1727 // "Normal" LoadTimingInfo as returned by a job. Everything is in order, not | |
1728 // reused. |connect_time_flags| is used to indicate if there should be dns | |
1729 // or SSL times, and |used_proxy| is used for proxy times. | |
1730 LoadTimingInfo NormalLoadTimingInfo(base::TimeTicks now, | |
1731 int connect_time_flags, | |
1732 bool used_proxy) { | |
1733 LoadTimingInfo load_timing; | |
1734 load_timing.socket_log_id = 1; | |
1735 | |
1736 if (used_proxy) { | |
1737 load_timing.proxy_resolve_start = now + base::TimeDelta::FromDays(1); | |
1738 load_timing.proxy_resolve_end = now + base::TimeDelta::FromDays(2); | |
1739 } | |
1740 | |
1741 LoadTimingInfo::ConnectTiming& connect_timing = load_timing.connect_timing; | |
1742 if (connect_time_flags & CONNECT_TIMING_HAS_DNS_TIMES) { | |
1743 connect_timing.dns_start = now + base::TimeDelta::FromDays(3); | |
1744 connect_timing.dns_end = now + base::TimeDelta::FromDays(4); | |
1745 } | |
1746 connect_timing.connect_start = now + base::TimeDelta::FromDays(5); | |
1747 if (connect_time_flags & CONNECT_TIMING_HAS_SSL_TIMES) { | |
1748 connect_timing.ssl_start = now + base::TimeDelta::FromDays(6); | |
1749 connect_timing.ssl_end = now + base::TimeDelta::FromDays(7); | |
1750 } | |
1751 connect_timing.connect_end = now + base::TimeDelta::FromDays(8); | |
1752 | |
1753 load_timing.send_start = now + base::TimeDelta::FromDays(9); | |
1754 load_timing.send_end = now + base::TimeDelta::FromDays(10); | |
1755 load_timing.receive_headers_end = now + base::TimeDelta::FromDays(11); | |
1756 return load_timing; | |
1757 } | |
1758 | |
1759 // Same as above, but in the case of a reused socket. | |
1760 LoadTimingInfo NormalLoadTimingInfoReused(base::TimeTicks now, | |
1761 bool used_proxy) { | |
1762 LoadTimingInfo load_timing; | |
1763 load_timing.socket_log_id = 1; | |
1764 load_timing.socket_reused = true; | |
1765 | |
1766 if (used_proxy) { | |
1767 load_timing.proxy_resolve_start = now + base::TimeDelta::FromDays(1); | |
1768 load_timing.proxy_resolve_end = now + base::TimeDelta::FromDays(2); | |
1769 } | |
1770 | |
1771 load_timing.send_start = now + base::TimeDelta::FromDays(9); | |
1772 load_timing.send_end = now + base::TimeDelta::FromDays(10); | |
1773 load_timing.receive_headers_end = now + base::TimeDelta::FromDays(11); | |
1774 return load_timing; | |
1775 } | |
1776 | |
1777 LoadTimingInfo RunURLRequestInterceptorLoadTimingTest( | |
1778 const LoadTimingInfo& job_load_timing, | |
1779 const URLRequestContext& context, | |
1780 MockURLRequestInterceptor* interceptor) { | |
1781 interceptor->set_intercept_main_request(true); | |
1782 interceptor->set_main_request_load_timing_info(job_load_timing); | |
1783 TestDelegate d; | |
1784 scoped_ptr<URLRequest> req(context.CreateRequest( | |
1785 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr)); | |
1786 req->Start(); | |
1787 base::RunLoop().Run(); | |
1788 | |
1789 LoadTimingInfo resulting_load_timing; | |
1790 req->GetLoadTimingInfo(&resulting_load_timing); | |
1791 | |
1792 // None of these should be modified by the URLRequest. | |
1793 EXPECT_EQ(job_load_timing.socket_reused, resulting_load_timing.socket_reused); | |
1794 EXPECT_EQ(job_load_timing.socket_log_id, resulting_load_timing.socket_log_id); | |
1795 EXPECT_EQ(job_load_timing.send_start, resulting_load_timing.send_start); | |
1796 EXPECT_EQ(job_load_timing.send_end, resulting_load_timing.send_end); | |
1797 EXPECT_EQ(job_load_timing.receive_headers_end, | |
1798 resulting_load_timing.receive_headers_end); | |
1799 | |
1800 return resulting_load_timing; | |
1801 } | |
1802 | |
1803 // Basic test that the intercept + load timing tests work. | |
1804 TEST_F(URLRequestInterceptorTest, InterceptLoadTiming) { | |
1805 base::TimeTicks now = base::TimeTicks::Now(); | |
1806 LoadTimingInfo job_load_timing = | |
1807 NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, false); | |
1808 | |
1809 LoadTimingInfo load_timing_result = | |
1810 RunURLRequestInterceptorLoadTimingTest( | |
1811 job_load_timing, default_context(), interceptor()); | |
1812 | |
1813 // Nothing should have been changed by the URLRequest. | |
1814 EXPECT_EQ(job_load_timing.proxy_resolve_start, | |
1815 load_timing_result.proxy_resolve_start); | |
1816 EXPECT_EQ(job_load_timing.proxy_resolve_end, | |
1817 load_timing_result.proxy_resolve_end); | |
1818 EXPECT_EQ(job_load_timing.connect_timing.dns_start, | |
1819 load_timing_result.connect_timing.dns_start); | |
1820 EXPECT_EQ(job_load_timing.connect_timing.dns_end, | |
1821 load_timing_result.connect_timing.dns_end); | |
1822 EXPECT_EQ(job_load_timing.connect_timing.connect_start, | |
1823 load_timing_result.connect_timing.connect_start); | |
1824 EXPECT_EQ(job_load_timing.connect_timing.connect_end, | |
1825 load_timing_result.connect_timing.connect_end); | |
1826 EXPECT_EQ(job_load_timing.connect_timing.ssl_start, | |
1827 load_timing_result.connect_timing.ssl_start); | |
1828 EXPECT_EQ(job_load_timing.connect_timing.ssl_end, | |
1829 load_timing_result.connect_timing.ssl_end); | |
1830 | |
1831 // Redundant sanity check. | |
1832 TestLoadTimingNotReused(load_timing_result, CONNECT_TIMING_HAS_DNS_TIMES); | |
1833 } | |
1834 | |
1835 // Another basic test, with proxy and SSL times, but no DNS times. | |
1836 TEST_F(URLRequestInterceptorTest, InterceptLoadTimingProxy) { | |
1837 base::TimeTicks now = base::TimeTicks::Now(); | |
1838 LoadTimingInfo job_load_timing = | |
1839 NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, true); | |
1840 | |
1841 LoadTimingInfo load_timing_result = | |
1842 RunURLRequestInterceptorLoadTimingTest( | |
1843 job_load_timing, default_context(), interceptor()); | |
1844 | |
1845 // Nothing should have been changed by the URLRequest. | |
1846 EXPECT_EQ(job_load_timing.proxy_resolve_start, | |
1847 load_timing_result.proxy_resolve_start); | |
1848 EXPECT_EQ(job_load_timing.proxy_resolve_end, | |
1849 load_timing_result.proxy_resolve_end); | |
1850 EXPECT_EQ(job_load_timing.connect_timing.dns_start, | |
1851 load_timing_result.connect_timing.dns_start); | |
1852 EXPECT_EQ(job_load_timing.connect_timing.dns_end, | |
1853 load_timing_result.connect_timing.dns_end); | |
1854 EXPECT_EQ(job_load_timing.connect_timing.connect_start, | |
1855 load_timing_result.connect_timing.connect_start); | |
1856 EXPECT_EQ(job_load_timing.connect_timing.connect_end, | |
1857 load_timing_result.connect_timing.connect_end); | |
1858 EXPECT_EQ(job_load_timing.connect_timing.ssl_start, | |
1859 load_timing_result.connect_timing.ssl_start); | |
1860 EXPECT_EQ(job_load_timing.connect_timing.ssl_end, | |
1861 load_timing_result.connect_timing.ssl_end); | |
1862 | |
1863 // Redundant sanity check. | |
1864 TestLoadTimingNotReusedWithProxy(load_timing_result, | |
1865 CONNECT_TIMING_HAS_SSL_TIMES); | |
1866 } | |
1867 | |
1868 // Make sure that URLRequest correctly adjusts proxy times when they're before | |
1869 // |request_start|, due to already having a connected socket. This happens in | |
1870 // the case of reusing a SPDY session. The connected socket is not considered | |
1871 // reused in this test (May be a preconnect). | |
1872 // | |
1873 // To mix things up from the test above, assumes DNS times but no SSL times. | |
1874 TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyProxyResolution) { | |
1875 base::TimeTicks now = base::TimeTicks::Now(); | |
1876 LoadTimingInfo job_load_timing = | |
1877 NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, true); | |
1878 job_load_timing.proxy_resolve_start = now - base::TimeDelta::FromDays(6); | |
1879 job_load_timing.proxy_resolve_end = now - base::TimeDelta::FromDays(5); | |
1880 job_load_timing.connect_timing.dns_start = now - base::TimeDelta::FromDays(4); | |
1881 job_load_timing.connect_timing.dns_end = now - base::TimeDelta::FromDays(3); | |
1882 job_load_timing.connect_timing.connect_start = | |
1883 now - base::TimeDelta::FromDays(2); | |
1884 job_load_timing.connect_timing.connect_end = | |
1885 now - base::TimeDelta::FromDays(1); | |
1886 | |
1887 LoadTimingInfo load_timing_result = | |
1888 RunURLRequestInterceptorLoadTimingTest( | |
1889 job_load_timing, default_context(), interceptor()); | |
1890 | |
1891 // Proxy times, connect times, and DNS times should all be replaced with | |
1892 // request_start. | |
1893 EXPECT_EQ(load_timing_result.request_start, | |
1894 load_timing_result.proxy_resolve_start); | |
1895 EXPECT_EQ(load_timing_result.request_start, | |
1896 load_timing_result.proxy_resolve_end); | |
1897 EXPECT_EQ(load_timing_result.request_start, | |
1898 load_timing_result.connect_timing.dns_start); | |
1899 EXPECT_EQ(load_timing_result.request_start, | |
1900 load_timing_result.connect_timing.dns_end); | |
1901 EXPECT_EQ(load_timing_result.request_start, | |
1902 load_timing_result.connect_timing.connect_start); | |
1903 EXPECT_EQ(load_timing_result.request_start, | |
1904 load_timing_result.connect_timing.connect_end); | |
1905 | |
1906 // Other times should have been left null. | |
1907 TestLoadTimingNotReusedWithProxy(load_timing_result, | |
1908 CONNECT_TIMING_HAS_DNS_TIMES); | |
1909 } | |
1910 | |
1911 // Same as above, but in the reused case. | |
1912 TEST_F(URLRequestInterceptorTest, | |
1913 InterceptLoadTimingEarlyProxyResolutionReused) { | |
1914 base::TimeTicks now = base::TimeTicks::Now(); | |
1915 LoadTimingInfo job_load_timing = NormalLoadTimingInfoReused(now, true); | |
1916 job_load_timing.proxy_resolve_start = now - base::TimeDelta::FromDays(4); | |
1917 job_load_timing.proxy_resolve_end = now - base::TimeDelta::FromDays(3); | |
1918 | |
1919 LoadTimingInfo load_timing_result = | |
1920 RunURLRequestInterceptorLoadTimingTest( | |
1921 job_load_timing, default_context(), interceptor()); | |
1922 | |
1923 // Proxy times and connect times should all be replaced with request_start. | |
1924 EXPECT_EQ(load_timing_result.request_start, | |
1925 load_timing_result.proxy_resolve_start); | |
1926 EXPECT_EQ(load_timing_result.request_start, | |
1927 load_timing_result.proxy_resolve_end); | |
1928 | |
1929 // Other times should have been left null. | |
1930 TestLoadTimingReusedWithProxy(load_timing_result); | |
1931 } | |
1932 | |
1933 // Make sure that URLRequest correctly adjusts connect times when they're before | |
1934 // |request_start|, due to reusing a connected socket. The connected socket is | |
1935 // not considered reused in this test (May be a preconnect). | |
1936 // | |
1937 // To mix things up, the request has SSL times, but no DNS times. | |
1938 TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyConnect) { | |
1939 base::TimeTicks now = base::TimeTicks::Now(); | |
1940 LoadTimingInfo job_load_timing = | |
1941 NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, false); | |
1942 job_load_timing.connect_timing.connect_start = | |
1943 now - base::TimeDelta::FromDays(1); | |
1944 job_load_timing.connect_timing.ssl_start = now - base::TimeDelta::FromDays(2); | |
1945 job_load_timing.connect_timing.ssl_end = now - base::TimeDelta::FromDays(3); | |
1946 job_load_timing.connect_timing.connect_end = | |
1947 now - base::TimeDelta::FromDays(4); | |
1948 | |
1949 LoadTimingInfo load_timing_result = | |
1950 RunURLRequestInterceptorLoadTimingTest( | |
1951 job_load_timing, default_context(), interceptor()); | |
1952 | |
1953 // Connect times, and SSL times should be replaced with request_start. | |
1954 EXPECT_EQ(load_timing_result.request_start, | |
1955 load_timing_result.connect_timing.connect_start); | |
1956 EXPECT_EQ(load_timing_result.request_start, | |
1957 load_timing_result.connect_timing.ssl_start); | |
1958 EXPECT_EQ(load_timing_result.request_start, | |
1959 load_timing_result.connect_timing.ssl_end); | |
1960 EXPECT_EQ(load_timing_result.request_start, | |
1961 load_timing_result.connect_timing.connect_end); | |
1962 | |
1963 // Other times should have been left null. | |
1964 TestLoadTimingNotReused(load_timing_result, CONNECT_TIMING_HAS_SSL_TIMES); | |
1965 } | |
1966 | |
1967 // Make sure that URLRequest correctly adjusts connect times when they're before | |
1968 // |request_start|, due to reusing a connected socket in the case that there | |
1969 // are also proxy times. The connected socket is not considered reused in this | |
1970 // test (May be a preconnect). | |
1971 // | |
1972 // In this test, there are no SSL or DNS times. | |
1973 TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyConnectWithProxy) { | |
1974 base::TimeTicks now = base::TimeTicks::Now(); | |
1975 LoadTimingInfo job_load_timing = | |
1976 NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY, true); | |
1977 job_load_timing.connect_timing.connect_start = | |
1978 now - base::TimeDelta::FromDays(1); | |
1979 job_load_timing.connect_timing.connect_end = | |
1980 now - base::TimeDelta::FromDays(2); | |
1981 | |
1982 LoadTimingInfo load_timing_result = | |
1983 RunURLRequestInterceptorLoadTimingTest( | |
1984 job_load_timing, default_context(), interceptor()); | |
1985 | |
1986 // Connect times should be replaced with proxy_resolve_end. | |
1987 EXPECT_EQ(load_timing_result.proxy_resolve_end, | |
1988 load_timing_result.connect_timing.connect_start); | |
1989 EXPECT_EQ(load_timing_result.proxy_resolve_end, | |
1990 load_timing_result.connect_timing.connect_end); | |
1991 | |
1992 // Other times should have been left null. | |
1993 TestLoadTimingNotReusedWithProxy(load_timing_result, | |
1994 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); | |
1995 } | |
1996 | |
1997 // Check that two different URL requests have different identifiers. | |
1998 TEST_F(URLRequestTest, Identifiers) { | |
1999 TestDelegate d; | |
2000 TestURLRequestContext context; | |
2001 scoped_ptr<URLRequest> req(context.CreateRequest( | |
2002 GURL("http://example.com"), DEFAULT_PRIORITY, &d, NULL)); | |
2003 scoped_ptr<URLRequest> other_req(context.CreateRequest( | |
2004 GURL("http://example.com"), DEFAULT_PRIORITY, &d, NULL)); | |
2005 | |
2006 ASSERT_NE(req->identifier(), other_req->identifier()); | |
2007 } | |
2008 | |
2009 // Check that a failure to connect to the proxy is reported to the network | |
2010 // delegate. | |
2011 TEST_F(URLRequestTest, NetworkDelegateProxyError) { | |
2012 MockHostResolver host_resolver; | |
2013 host_resolver.rules()->AddSimulatedFailure("*"); | |
2014 | |
2015 TestNetworkDelegate network_delegate; // Must outlive URLRequests. | |
2016 TestURLRequestContextWithProxy context("myproxy:70", &network_delegate); | |
2017 | |
2018 TestDelegate d; | |
2019 scoped_ptr<URLRequest> req(context.CreateRequest( | |
2020 GURL("http://example.com"), DEFAULT_PRIORITY, &d, NULL)); | |
2021 req->set_method("GET"); | |
2022 | |
2023 req->Start(); | |
2024 base::RunLoop().Run(); | |
2025 | |
2026 // Check we see a failed request. | |
2027 EXPECT_FALSE(req->status().is_success()); | |
2028 // The proxy server is not set before failure. | |
2029 EXPECT_TRUE(req->proxy_server().IsEmpty()); | |
2030 EXPECT_EQ(URLRequestStatus::FAILED, req->status().status()); | |
2031 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, req->status().error()); | |
2032 | |
2033 EXPECT_EQ(1, network_delegate.error_count()); | |
2034 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, network_delegate.last_error()); | |
2035 EXPECT_EQ(1, network_delegate.completed_requests()); | |
2036 } | |
2037 | |
2038 // Make sure that NetworkDelegate::NotifyCompleted is called if | |
2039 // content is empty. | |
2040 TEST_F(URLRequestTest, RequestCompletionForEmptyResponse) { | |
2041 TestDelegate d; | |
2042 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2043 GURL("data:,"), DEFAULT_PRIORITY, &d, NULL)); | |
2044 req->Start(); | |
2045 base::RunLoop().Run(); | |
2046 EXPECT_EQ("", d.data_received()); | |
2047 EXPECT_EQ(1, default_network_delegate_.completed_requests()); | |
2048 } | |
2049 | |
2050 // Make sure that SetPriority actually sets the URLRequest's priority | |
2051 // correctly, both before and after start. | |
2052 TEST_F(URLRequestTest, SetPriorityBasic) { | |
2053 TestDelegate d; | |
2054 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2055 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); | |
2056 EXPECT_EQ(DEFAULT_PRIORITY, req->priority()); | |
2057 | |
2058 req->SetPriority(LOW); | |
2059 EXPECT_EQ(LOW, req->priority()); | |
2060 | |
2061 req->Start(); | |
2062 EXPECT_EQ(LOW, req->priority()); | |
2063 | |
2064 req->SetPriority(MEDIUM); | |
2065 EXPECT_EQ(MEDIUM, req->priority()); | |
2066 } | |
2067 | |
2068 // Make sure that URLRequest calls SetPriority on a job before calling | |
2069 // Start on it. | |
2070 TEST_F(URLRequestTest, SetJobPriorityBeforeJobStart) { | |
2071 TestDelegate d; | |
2072 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2073 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); | |
2074 EXPECT_EQ(DEFAULT_PRIORITY, req->priority()); | |
2075 | |
2076 scoped_refptr<URLRequestTestJob> job = | |
2077 new URLRequestTestJob(req.get(), &default_network_delegate_); | |
2078 AddTestInterceptor()->set_main_intercept_job(job.get()); | |
2079 EXPECT_EQ(DEFAULT_PRIORITY, job->priority()); | |
2080 | |
2081 req->SetPriority(LOW); | |
2082 | |
2083 req->Start(); | |
2084 EXPECT_EQ(LOW, job->priority()); | |
2085 } | |
2086 | |
2087 // Make sure that URLRequest passes on its priority updates to its | |
2088 // job. | |
2089 TEST_F(URLRequestTest, SetJobPriority) { | |
2090 TestDelegate d; | |
2091 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2092 GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL)); | |
2093 | |
2094 scoped_refptr<URLRequestTestJob> job = | |
2095 new URLRequestTestJob(req.get(), &default_network_delegate_); | |
2096 AddTestInterceptor()->set_main_intercept_job(job.get()); | |
2097 | |
2098 req->SetPriority(LOW); | |
2099 req->Start(); | |
2100 EXPECT_EQ(LOW, job->priority()); | |
2101 | |
2102 req->SetPriority(MEDIUM); | |
2103 EXPECT_EQ(MEDIUM, req->priority()); | |
2104 EXPECT_EQ(MEDIUM, job->priority()); | |
2105 } | |
2106 | |
2107 // Setting the IGNORE_LIMITS load flag should be okay if the priority | |
2108 // is MAXIMUM_PRIORITY. | |
2109 TEST_F(URLRequestTest, PriorityIgnoreLimits) { | |
2110 TestDelegate d; | |
2111 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2112 GURL("http://test_intercept/foo"), MAXIMUM_PRIORITY, &d, NULL)); | |
2113 EXPECT_EQ(MAXIMUM_PRIORITY, req->priority()); | |
2114 | |
2115 scoped_refptr<URLRequestTestJob> job = | |
2116 new URLRequestTestJob(req.get(), &default_network_delegate_); | |
2117 AddTestInterceptor()->set_main_intercept_job(job.get()); | |
2118 | |
2119 req->SetLoadFlags(LOAD_IGNORE_LIMITS); | |
2120 EXPECT_EQ(MAXIMUM_PRIORITY, req->priority()); | |
2121 | |
2122 req->SetPriority(MAXIMUM_PRIORITY); | |
2123 EXPECT_EQ(MAXIMUM_PRIORITY, req->priority()); | |
2124 | |
2125 req->Start(); | |
2126 EXPECT_EQ(MAXIMUM_PRIORITY, req->priority()); | |
2127 EXPECT_EQ(MAXIMUM_PRIORITY, job->priority()); | |
2128 } | |
2129 | |
2130 // TODO(droger): Support SpawnedTestServer on iOS (see http://crbug.com/148666). | |
2131 #if !defined(OS_IOS) | |
2132 // A subclass of SpawnedTestServer that uses a statically-configured hostname. | |
2133 // This is to work around mysterious failures in chrome_frame_net_tests. See: | |
2134 // http://crbug.com/114369 | |
2135 // TODO(erikwright): remove or update as needed; see http://crbug.com/334634. | |
2136 class LocalHttpTestServer : public SpawnedTestServer { | |
2137 public: | |
2138 explicit LocalHttpTestServer(const base::FilePath& document_root) | |
2139 : SpawnedTestServer(SpawnedTestServer::TYPE_HTTP, | |
2140 ScopedCustomUrlRequestTestHttpHost::value(), | |
2141 document_root) {} | |
2142 LocalHttpTestServer() | |
2143 : SpawnedTestServer(SpawnedTestServer::TYPE_HTTP, | |
2144 ScopedCustomUrlRequestTestHttpHost::value(), | |
2145 base::FilePath()) {} | |
2146 }; | |
2147 | |
2148 TEST_F(URLRequestTest, DelayedCookieCallback) { | |
2149 LocalHttpTestServer test_server; | |
2150 ASSERT_TRUE(test_server.Start()); | |
2151 | |
2152 TestURLRequestContext context; | |
2153 scoped_refptr<DelayedCookieMonster> delayed_cm = | |
2154 new DelayedCookieMonster(); | |
2155 scoped_refptr<CookieStore> cookie_store = delayed_cm; | |
2156 context.set_cookie_store(delayed_cm.get()); | |
2157 | |
2158 // Set up a cookie. | |
2159 { | |
2160 TestNetworkDelegate network_delegate; | |
2161 context.set_network_delegate(&network_delegate); | |
2162 TestDelegate d; | |
2163 scoped_ptr<URLRequest> req(context.CreateRequest( | |
2164 test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY, | |
2165 &d, NULL)); | |
2166 req->Start(); | |
2167 base::RunLoop().Run(); | |
2168 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2169 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2170 EXPECT_EQ(1, network_delegate.set_cookie_count()); | |
2171 } | |
2172 | |
2173 // Verify that the cookie is set. | |
2174 { | |
2175 TestNetworkDelegate network_delegate; | |
2176 context.set_network_delegate(&network_delegate); | |
2177 TestDelegate d; | |
2178 scoped_ptr<URLRequest> req(context.CreateRequest( | |
2179 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); | |
2180 req->Start(); | |
2181 base::RunLoop().Run(); | |
2182 | |
2183 EXPECT_TRUE(d.data_received().find("CookieToNotSend=1") | |
2184 != std::string::npos); | |
2185 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2186 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2187 } | |
2188 } | |
2189 | |
2190 TEST_F(URLRequestTest, DoNotSendCookies) { | |
2191 LocalHttpTestServer test_server; | |
2192 ASSERT_TRUE(test_server.Start()); | |
2193 | |
2194 // Set up a cookie. | |
2195 { | |
2196 TestNetworkDelegate network_delegate; | |
2197 default_context_.set_network_delegate(&network_delegate); | |
2198 TestDelegate d; | |
2199 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2200 test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY, | |
2201 &d, NULL)); | |
2202 req->Start(); | |
2203 base::RunLoop().Run(); | |
2204 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2205 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2206 } | |
2207 | |
2208 // Verify that the cookie is set. | |
2209 { | |
2210 TestNetworkDelegate network_delegate; | |
2211 default_context_.set_network_delegate(&network_delegate); | |
2212 TestDelegate d; | |
2213 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2214 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); | |
2215 req->Start(); | |
2216 base::RunLoop().Run(); | |
2217 | |
2218 EXPECT_TRUE(d.data_received().find("CookieToNotSend=1") | |
2219 != std::string::npos); | |
2220 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2221 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2222 } | |
2223 | |
2224 // Verify that the cookie isn't sent when LOAD_DO_NOT_SEND_COOKIES is set. | |
2225 { | |
2226 TestNetworkDelegate network_delegate; | |
2227 default_context_.set_network_delegate(&network_delegate); | |
2228 TestDelegate d; | |
2229 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2230 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); | |
2231 req->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES); | |
2232 req->Start(); | |
2233 base::RunLoop().Run(); | |
2234 | |
2235 EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1") | |
2236 == std::string::npos); | |
2237 | |
2238 // LOAD_DO_NOT_SEND_COOKIES does not trigger OnGetCookies. | |
2239 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2240 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2241 } | |
2242 } | |
2243 | |
2244 TEST_F(URLRequestTest, DoNotSaveCookies) { | |
2245 LocalHttpTestServer test_server; | |
2246 ASSERT_TRUE(test_server.Start()); | |
2247 | |
2248 // Set up a cookie. | |
2249 { | |
2250 TestNetworkDelegate network_delegate; | |
2251 default_context_.set_network_delegate(&network_delegate); | |
2252 TestDelegate d; | |
2253 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2254 test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY, | |
2255 &d, NULL)); | |
2256 req->Start(); | |
2257 base::RunLoop().Run(); | |
2258 | |
2259 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2260 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2261 EXPECT_EQ(1, network_delegate.set_cookie_count()); | |
2262 } | |
2263 | |
2264 // Try to set-up another cookie and update the previous cookie. | |
2265 { | |
2266 TestNetworkDelegate network_delegate; | |
2267 default_context_.set_network_delegate(&network_delegate); | |
2268 TestDelegate d; | |
2269 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2270 test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"), | |
2271 DEFAULT_PRIORITY, &d, NULL)); | |
2272 req->SetLoadFlags(LOAD_DO_NOT_SAVE_COOKIES); | |
2273 req->Start(); | |
2274 | |
2275 base::RunLoop().Run(); | |
2276 | |
2277 // LOAD_DO_NOT_SAVE_COOKIES does not trigger OnSetCookie. | |
2278 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2279 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2280 EXPECT_EQ(0, network_delegate.set_cookie_count()); | |
2281 } | |
2282 | |
2283 // Verify the cookies weren't saved or updated. | |
2284 { | |
2285 TestNetworkDelegate network_delegate; | |
2286 default_context_.set_network_delegate(&network_delegate); | |
2287 TestDelegate d; | |
2288 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2289 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); | |
2290 req->Start(); | |
2291 base::RunLoop().Run(); | |
2292 | |
2293 EXPECT_TRUE(d.data_received().find("CookieToNotSave=1") | |
2294 == std::string::npos); | |
2295 EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2") | |
2296 != std::string::npos); | |
2297 | |
2298 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2299 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2300 EXPECT_EQ(0, network_delegate.set_cookie_count()); | |
2301 } | |
2302 } | |
2303 | |
2304 TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy) { | |
2305 LocalHttpTestServer test_server; | |
2306 ASSERT_TRUE(test_server.Start()); | |
2307 | |
2308 // Set up a cookie. | |
2309 { | |
2310 TestNetworkDelegate network_delegate; | |
2311 default_context_.set_network_delegate(&network_delegate); | |
2312 TestDelegate d; | |
2313 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2314 test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY, | |
2315 &d, NULL)); | |
2316 req->Start(); | |
2317 base::RunLoop().Run(); | |
2318 | |
2319 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2320 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2321 } | |
2322 | |
2323 // Verify that the cookie is set. | |
2324 { | |
2325 TestNetworkDelegate network_delegate; | |
2326 default_context_.set_network_delegate(&network_delegate); | |
2327 TestDelegate d; | |
2328 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2329 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); | |
2330 req->Start(); | |
2331 base::RunLoop().Run(); | |
2332 | |
2333 EXPECT_TRUE(d.data_received().find("CookieToNotSend=1") | |
2334 != std::string::npos); | |
2335 | |
2336 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2337 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2338 } | |
2339 | |
2340 // Verify that the cookie isn't sent. | |
2341 { | |
2342 TestNetworkDelegate network_delegate; | |
2343 default_context_.set_network_delegate(&network_delegate); | |
2344 TestDelegate d; | |
2345 network_delegate.set_cookie_options(TestNetworkDelegate::NO_GET_COOKIES); | |
2346 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2347 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); | |
2348 req->Start(); | |
2349 base::RunLoop().Run(); | |
2350 | |
2351 EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1") | |
2352 == std::string::npos); | |
2353 | |
2354 EXPECT_EQ(1, network_delegate.blocked_get_cookies_count()); | |
2355 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2356 } | |
2357 } | |
2358 | |
2359 TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy) { | |
2360 LocalHttpTestServer test_server; | |
2361 ASSERT_TRUE(test_server.Start()); | |
2362 | |
2363 // Set up a cookie. | |
2364 { | |
2365 TestNetworkDelegate network_delegate; | |
2366 default_context_.set_network_delegate(&network_delegate); | |
2367 TestDelegate d; | |
2368 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2369 test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY, | |
2370 &d, NULL)); | |
2371 req->Start(); | |
2372 base::RunLoop().Run(); | |
2373 | |
2374 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2375 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2376 } | |
2377 | |
2378 // Try to set-up another cookie and update the previous cookie. | |
2379 { | |
2380 TestNetworkDelegate network_delegate; | |
2381 default_context_.set_network_delegate(&network_delegate); | |
2382 TestDelegate d; | |
2383 network_delegate.set_cookie_options(TestNetworkDelegate::NO_SET_COOKIE); | |
2384 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2385 test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"), | |
2386 DEFAULT_PRIORITY, &d, NULL)); | |
2387 req->Start(); | |
2388 | |
2389 base::RunLoop().Run(); | |
2390 | |
2391 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2392 EXPECT_EQ(2, network_delegate.blocked_set_cookie_count()); | |
2393 } | |
2394 | |
2395 // Verify the cookies weren't saved or updated. | |
2396 { | |
2397 TestNetworkDelegate network_delegate; | |
2398 default_context_.set_network_delegate(&network_delegate); | |
2399 TestDelegate d; | |
2400 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2401 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); | |
2402 req->Start(); | |
2403 base::RunLoop().Run(); | |
2404 | |
2405 EXPECT_TRUE(d.data_received().find("CookieToNotSave=1") | |
2406 == std::string::npos); | |
2407 EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2") | |
2408 != std::string::npos); | |
2409 | |
2410 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2411 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2412 } | |
2413 } | |
2414 | |
2415 TEST_F(URLRequestTest, DoNotSaveEmptyCookies) { | |
2416 LocalHttpTestServer test_server; | |
2417 ASSERT_TRUE(test_server.Start()); | |
2418 | |
2419 // Set up an empty cookie. | |
2420 { | |
2421 TestNetworkDelegate network_delegate; | |
2422 default_context_.set_network_delegate(&network_delegate); | |
2423 TestDelegate d; | |
2424 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2425 test_server.GetURL("set-cookie"), DEFAULT_PRIORITY, &d, NULL)); | |
2426 req->Start(); | |
2427 base::RunLoop().Run(); | |
2428 | |
2429 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2430 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2431 EXPECT_EQ(0, network_delegate.set_cookie_count()); | |
2432 } | |
2433 } | |
2434 | |
2435 TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy_Async) { | |
2436 LocalHttpTestServer test_server; | |
2437 ASSERT_TRUE(test_server.Start()); | |
2438 | |
2439 // Set up a cookie. | |
2440 { | |
2441 TestNetworkDelegate network_delegate; | |
2442 default_context_.set_network_delegate(&network_delegate); | |
2443 TestDelegate d; | |
2444 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2445 test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY, | |
2446 &d, NULL)); | |
2447 req->Start(); | |
2448 base::RunLoop().Run(); | |
2449 | |
2450 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2451 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2452 } | |
2453 | |
2454 // Verify that the cookie is set. | |
2455 { | |
2456 TestNetworkDelegate network_delegate; | |
2457 default_context_.set_network_delegate(&network_delegate); | |
2458 TestDelegate d; | |
2459 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2460 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); | |
2461 req->Start(); | |
2462 base::RunLoop().Run(); | |
2463 | |
2464 EXPECT_TRUE(d.data_received().find("CookieToNotSend=1") | |
2465 != std::string::npos); | |
2466 | |
2467 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2468 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2469 } | |
2470 | |
2471 // Verify that the cookie isn't sent. | |
2472 { | |
2473 TestNetworkDelegate network_delegate; | |
2474 default_context_.set_network_delegate(&network_delegate); | |
2475 TestDelegate d; | |
2476 network_delegate.set_cookie_options(TestNetworkDelegate::NO_GET_COOKIES); | |
2477 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2478 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); | |
2479 req->Start(); | |
2480 base::RunLoop().Run(); | |
2481 | |
2482 EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1") | |
2483 == std::string::npos); | |
2484 | |
2485 EXPECT_EQ(1, network_delegate.blocked_get_cookies_count()); | |
2486 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2487 } | |
2488 } | |
2489 | |
2490 TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy_Async) { | |
2491 LocalHttpTestServer test_server; | |
2492 ASSERT_TRUE(test_server.Start()); | |
2493 | |
2494 // Set up a cookie. | |
2495 { | |
2496 TestNetworkDelegate network_delegate; | |
2497 default_context_.set_network_delegate(&network_delegate); | |
2498 TestDelegate d; | |
2499 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2500 test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY, | |
2501 &d, NULL)); | |
2502 req->Start(); | |
2503 base::RunLoop().Run(); | |
2504 | |
2505 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2506 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2507 } | |
2508 | |
2509 // Try to set-up another cookie and update the previous cookie. | |
2510 { | |
2511 TestNetworkDelegate network_delegate; | |
2512 default_context_.set_network_delegate(&network_delegate); | |
2513 TestDelegate d; | |
2514 network_delegate.set_cookie_options(TestNetworkDelegate::NO_SET_COOKIE); | |
2515 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2516 test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"), | |
2517 DEFAULT_PRIORITY, &d, NULL)); | |
2518 req->Start(); | |
2519 | |
2520 base::RunLoop().Run(); | |
2521 | |
2522 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2523 EXPECT_EQ(2, network_delegate.blocked_set_cookie_count()); | |
2524 } | |
2525 | |
2526 // Verify the cookies weren't saved or updated. | |
2527 { | |
2528 TestNetworkDelegate network_delegate; | |
2529 default_context_.set_network_delegate(&network_delegate); | |
2530 TestDelegate d; | |
2531 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2532 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); | |
2533 req->Start(); | |
2534 base::RunLoop().Run(); | |
2535 | |
2536 EXPECT_TRUE(d.data_received().find("CookieToNotSave=1") | |
2537 == std::string::npos); | |
2538 EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2") | |
2539 != std::string::npos); | |
2540 | |
2541 EXPECT_EQ(0, network_delegate.blocked_get_cookies_count()); | |
2542 EXPECT_EQ(0, network_delegate.blocked_set_cookie_count()); | |
2543 } | |
2544 } | |
2545 | |
2546 // FixedDateNetworkDelegate swaps out the server's HTTP Date response header | |
2547 // value for the |fixed_date| argument given to the constructor. | |
2548 class FixedDateNetworkDelegate : public TestNetworkDelegate { | |
2549 public: | |
2550 explicit FixedDateNetworkDelegate(const std::string& fixed_date) | |
2551 : fixed_date_(fixed_date) {} | |
2552 ~FixedDateNetworkDelegate() override {} | |
2553 | |
2554 // NetworkDelegate implementation | |
2555 int OnHeadersReceived( | |
2556 URLRequest* request, | |
2557 const CompletionCallback& callback, | |
2558 const HttpResponseHeaders* original_response_headers, | |
2559 scoped_refptr<HttpResponseHeaders>* override_response_headers, | |
2560 GURL* allowed_unsafe_redirect_url) override; | |
2561 | |
2562 private: | |
2563 std::string fixed_date_; | |
2564 | |
2565 DISALLOW_COPY_AND_ASSIGN(FixedDateNetworkDelegate); | |
2566 }; | |
2567 | |
2568 int FixedDateNetworkDelegate::OnHeadersReceived( | |
2569 URLRequest* request, | |
2570 const CompletionCallback& callback, | |
2571 const HttpResponseHeaders* original_response_headers, | |
2572 scoped_refptr<HttpResponseHeaders>* override_response_headers, | |
2573 GURL* allowed_unsafe_redirect_url) { | |
2574 HttpResponseHeaders* new_response_headers = | |
2575 new HttpResponseHeaders(original_response_headers->raw_headers()); | |
2576 | |
2577 new_response_headers->RemoveHeader("Date"); | |
2578 new_response_headers->AddHeader("Date: " + fixed_date_); | |
2579 | |
2580 *override_response_headers = new_response_headers; | |
2581 return TestNetworkDelegate::OnHeadersReceived(request, | |
2582 callback, | |
2583 original_response_headers, | |
2584 override_response_headers, | |
2585 allowed_unsafe_redirect_url); | |
2586 } | |
2587 | |
2588 // Test that cookie expiration times are adjusted for server/client clock | |
2589 // skew and that we handle incorrect timezone specifier "UTC" in HTTP Date | |
2590 // headers by defaulting to GMT. (crbug.com/135131) | |
2591 TEST_F(URLRequestTest, AcceptClockSkewCookieWithWrongDateTimezone) { | |
2592 LocalHttpTestServer test_server; | |
2593 ASSERT_TRUE(test_server.Start()); | |
2594 | |
2595 // Set up an expired cookie. | |
2596 { | |
2597 TestNetworkDelegate network_delegate; | |
2598 default_context_.set_network_delegate(&network_delegate); | |
2599 TestDelegate d; | |
2600 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2601 test_server.GetURL( | |
2602 "set-cookie?StillGood=1;expires=Mon,18-Apr-1977,22:50:13,GMT"), | |
2603 DEFAULT_PRIORITY, &d, NULL)); | |
2604 req->Start(); | |
2605 base::RunLoop().Run(); | |
2606 } | |
2607 // Verify that the cookie is not set. | |
2608 { | |
2609 TestNetworkDelegate network_delegate; | |
2610 default_context_.set_network_delegate(&network_delegate); | |
2611 TestDelegate d; | |
2612 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2613 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); | |
2614 req->Start(); | |
2615 base::RunLoop().Run(); | |
2616 | |
2617 EXPECT_TRUE(d.data_received().find("StillGood=1") == std::string::npos); | |
2618 } | |
2619 // Set up a cookie with clock skew and "UTC" HTTP Date timezone specifier. | |
2620 { | |
2621 FixedDateNetworkDelegate network_delegate("18-Apr-1977 22:49:13 UTC"); | |
2622 default_context_.set_network_delegate(&network_delegate); | |
2623 TestDelegate d; | |
2624 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2625 test_server.GetURL( | |
2626 "set-cookie?StillGood=1;expires=Mon,18-Apr-1977,22:50:13,GMT"), | |
2627 DEFAULT_PRIORITY, &d, NULL)); | |
2628 req->Start(); | |
2629 base::RunLoop().Run(); | |
2630 } | |
2631 // Verify that the cookie is set. | |
2632 { | |
2633 TestNetworkDelegate network_delegate; | |
2634 default_context_.set_network_delegate(&network_delegate); | |
2635 TestDelegate d; | |
2636 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2637 test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d, NULL)); | |
2638 req->Start(); | |
2639 base::RunLoop().Run(); | |
2640 | |
2641 EXPECT_TRUE(d.data_received().find("StillGood=1") != std::string::npos); | |
2642 } | |
2643 } | |
2644 | |
2645 | |
2646 // Check that it is impossible to change the referrer in the extra headers of | |
2647 // an URLRequest. | |
2648 TEST_F(URLRequestTest, DoNotOverrideReferrer) { | |
2649 LocalHttpTestServer test_server; | |
2650 ASSERT_TRUE(test_server.Start()); | |
2651 | |
2652 // If extra headers contain referer and the request contains a referer, | |
2653 // only the latter shall be respected. | |
2654 { | |
2655 TestDelegate d; | |
2656 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2657 test_server.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL)); | |
2658 req->SetReferrer("http://foo.com/"); | |
2659 | |
2660 HttpRequestHeaders headers; | |
2661 headers.SetHeader(HttpRequestHeaders::kReferer, "http://bar.com/"); | |
2662 req->SetExtraRequestHeaders(headers); | |
2663 | |
2664 req->Start(); | |
2665 base::RunLoop().Run(); | |
2666 | |
2667 EXPECT_EQ("http://foo.com/", d.data_received()); | |
2668 } | |
2669 | |
2670 // If extra headers contain a referer but the request does not, no referer | |
2671 // shall be sent in the header. | |
2672 { | |
2673 TestDelegate d; | |
2674 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2675 test_server.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL)); | |
2676 | |
2677 HttpRequestHeaders headers; | |
2678 headers.SetHeader(HttpRequestHeaders::kReferer, "http://bar.com/"); | |
2679 req->SetExtraRequestHeaders(headers); | |
2680 req->SetLoadFlags(LOAD_VALIDATE_CACHE); | |
2681 | |
2682 req->Start(); | |
2683 base::RunLoop().Run(); | |
2684 | |
2685 EXPECT_EQ("None", d.data_received()); | |
2686 } | |
2687 } | |
2688 | |
2689 class URLRequestTestHTTP : public URLRequestTest { | |
2690 public: | |
2691 URLRequestTestHTTP() | |
2692 : test_server_(base::FilePath(FILE_PATH_LITERAL( | |
2693 "net/data/url_request_unittest"))) { | |
2694 } | |
2695 | |
2696 protected: | |
2697 // Requests |redirect_url|, which must return a HTTP 3xx redirect. | |
2698 // |request_method| is the method to use for the initial request. | |
2699 // |redirect_method| is the method that is expected to be used for the second | |
2700 // request, after redirection. | |
2701 // If |include_data| is true, data is uploaded with the request. The | |
2702 // response body is expected to match it exactly, if and only if | |
2703 // |request_method| == |redirect_method|. | |
2704 void HTTPRedirectMethodTest(const GURL& redirect_url, | |
2705 const std::string& request_method, | |
2706 const std::string& redirect_method, | |
2707 bool include_data) { | |
2708 static const char kData[] = "hello world"; | |
2709 TestDelegate d; | |
2710 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
2711 redirect_url, DEFAULT_PRIORITY, &d, NULL)); | |
2712 req->set_method(request_method); | |
2713 if (include_data) { | |
2714 req->set_upload(CreateSimpleUploadData(kData)); | |
2715 HttpRequestHeaders headers; | |
2716 headers.SetHeader(HttpRequestHeaders::kContentLength, | |
2717 base::UintToString(arraysize(kData) - 1)); | |
2718 req->SetExtraRequestHeaders(headers); | |
2719 } | |
2720 req->Start(); | |
2721 base::RunLoop().Run(); | |
2722 EXPECT_EQ(redirect_method, req->method()); | |
2723 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); | |
2724 EXPECT_EQ(OK, req->status().error()); | |
2725 if (include_data) { | |
2726 if (request_method == redirect_method) { | |
2727 EXPECT_EQ(kData, d.data_received()); | |
2728 } else { | |
2729 EXPECT_NE(kData, d.data_received()); | |
2730 } | |
2731 } | |
2732 if (HasFailure()) | |
2733 LOG(WARNING) << "Request method was: " << request_method; | |
2734 } | |
2735 | |
2736 void HTTPUploadDataOperationTest(const std::string& method) { | |
2737 const int kMsgSize = 20000; // multiple of 10 | |
2738 const int kIterations = 50; | |
2739 char* uploadBytes = new char[kMsgSize+1]; | |
2740 char* ptr = uploadBytes; | |
2741 char marker = 'a'; | |
2742 for (int idx = 0; idx < kMsgSize/10; idx++) { | |
2743 memcpy(ptr, "----------", 10); | |
2744 ptr += 10; | |
2745 if (idx % 100 == 0) { | |
2746 ptr--; | |
2747 *ptr++ = marker; | |
2748 if (++marker > 'z') | |
2749 marker = 'a'; | |
2750 } | |
2751 } | |
2752 uploadBytes[kMsgSize] = '\0'; | |
2753 | |
2754 for (int i = 0; i < kIterations; ++i) { | |
2755 TestDelegate d; | |
2756 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
2757 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); | |
2758 r->set_method(method.c_str()); | |
2759 | |
2760 r->set_upload(CreateSimpleUploadData(uploadBytes)); | |
2761 | |
2762 r->Start(); | |
2763 EXPECT_TRUE(r->is_pending()); | |
2764 | |
2765 base::RunLoop().Run(); | |
2766 | |
2767 ASSERT_EQ(1, d.response_started_count()) | |
2768 << "request failed: " << r->status().status() | |
2769 << ", os error: " << r->status().error(); | |
2770 | |
2771 EXPECT_FALSE(d.received_data_before_response()); | |
2772 EXPECT_EQ(uploadBytes, d.data_received()); | |
2773 } | |
2774 delete[] uploadBytes; | |
2775 } | |
2776 | |
2777 void AddChunksToUpload(URLRequest* r) { | |
2778 r->AppendChunkToUpload("a", 1, false); | |
2779 r->AppendChunkToUpload("bcd", 3, false); | |
2780 r->AppendChunkToUpload("this is a longer chunk than before.", 35, false); | |
2781 r->AppendChunkToUpload("\r\n\r\n", 4, false); | |
2782 r->AppendChunkToUpload("0", 1, false); | |
2783 r->AppendChunkToUpload("2323", 4, true); | |
2784 } | |
2785 | |
2786 void VerifyReceivedDataMatchesChunks(URLRequest* r, TestDelegate* d) { | |
2787 // This should match the chunks sent by AddChunksToUpload(). | |
2788 const std::string expected_data = | |
2789 "abcdthis is a longer chunk than before.\r\n\r\n02323"; | |
2790 | |
2791 ASSERT_EQ(1, d->response_started_count()) | |
2792 << "request failed: " << r->status().status() | |
2793 << ", os error: " << r->status().error(); | |
2794 | |
2795 EXPECT_FALSE(d->received_data_before_response()); | |
2796 | |
2797 EXPECT_EQ(expected_data.size(), static_cast<size_t>(d->bytes_received())); | |
2798 EXPECT_EQ(expected_data, d->data_received()); | |
2799 } | |
2800 | |
2801 bool DoManyCookiesRequest(int num_cookies) { | |
2802 TestDelegate d; | |
2803 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
2804 test_server_.GetURL("set-many-cookies?" + | |
2805 base::IntToString(num_cookies)), | |
2806 DEFAULT_PRIORITY, &d, NULL)); | |
2807 | |
2808 r->Start(); | |
2809 EXPECT_TRUE(r->is_pending()); | |
2810 | |
2811 base::RunLoop().Run(); | |
2812 | |
2813 bool is_success = r->status().is_success(); | |
2814 | |
2815 if (!is_success) { | |
2816 EXPECT_TRUE(r->status().error() == ERR_RESPONSE_HEADERS_TOO_BIG); | |
2817 // The test server appears to be unable to handle subsequent requests | |
2818 // after this error is triggered. Force it to restart. | |
2819 EXPECT_TRUE(test_server_.Stop()); | |
2820 EXPECT_TRUE(test_server_.Start()); | |
2821 } | |
2822 | |
2823 return is_success; | |
2824 } | |
2825 | |
2826 LocalHttpTestServer* test_server() { | |
2827 return &test_server_; | |
2828 } | |
2829 | |
2830 protected: | |
2831 LocalHttpTestServer test_server_; | |
2832 }; | |
2833 | |
2834 // In this unit test, we're using the HTTPTestServer as a proxy server and | |
2835 // issuing a CONNECT request with the magic host name "www.redirect.com". | |
2836 // The HTTPTestServer will return a 302 response, which we should not | |
2837 // follow. | |
2838 TEST_F(URLRequestTestHTTP, ProxyTunnelRedirectTest) { | |
2839 ASSERT_TRUE(test_server_.Start()); | |
2840 | |
2841 TestNetworkDelegate network_delegate; // Must outlive URLRequest. | |
2842 TestURLRequestContextWithProxy context( | |
2843 test_server_.host_port_pair().ToString(), &network_delegate); | |
2844 | |
2845 TestDelegate d; | |
2846 { | |
2847 scoped_ptr<URLRequest> r(context.CreateRequest( | |
2848 GURL("https://www.redirect.com/"), DEFAULT_PRIORITY, &d, NULL)); | |
2849 r->Start(); | |
2850 EXPECT_TRUE(r->is_pending()); | |
2851 | |
2852 base::RunLoop().Run(); | |
2853 | |
2854 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); | |
2855 // The proxy server is not set before failure. | |
2856 EXPECT_TRUE(r->proxy_server().IsEmpty()); | |
2857 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r->status().error()); | |
2858 EXPECT_EQ(1, d.response_started_count()); | |
2859 // We should not have followed the redirect. | |
2860 EXPECT_EQ(0, d.received_redirect_count()); | |
2861 } | |
2862 } | |
2863 | |
2864 // This is the same as the previous test, but checks that the network delegate | |
2865 // registers the error. | |
2866 TEST_F(URLRequestTestHTTP, NetworkDelegateTunnelConnectionFailed) { | |
2867 ASSERT_TRUE(test_server_.Start()); | |
2868 | |
2869 TestNetworkDelegate network_delegate; // Must outlive URLRequest. | |
2870 TestURLRequestContextWithProxy context( | |
2871 test_server_.host_port_pair().ToString(), &network_delegate); | |
2872 | |
2873 TestDelegate d; | |
2874 { | |
2875 scoped_ptr<URLRequest> r(context.CreateRequest( | |
2876 GURL("https://www.redirect.com/"), DEFAULT_PRIORITY, &d, NULL)); | |
2877 r->Start(); | |
2878 EXPECT_TRUE(r->is_pending()); | |
2879 | |
2880 base::RunLoop().Run(); | |
2881 | |
2882 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); | |
2883 // The proxy server is not set before failure. | |
2884 EXPECT_TRUE(r->proxy_server().IsEmpty()); | |
2885 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r->status().error()); | |
2886 EXPECT_EQ(1, d.response_started_count()); | |
2887 // We should not have followed the redirect. | |
2888 EXPECT_EQ(0, d.received_redirect_count()); | |
2889 | |
2890 EXPECT_EQ(1, network_delegate.error_count()); | |
2891 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, network_delegate.last_error()); | |
2892 } | |
2893 } | |
2894 | |
2895 // Tests that we can block and asynchronously return OK in various stages. | |
2896 TEST_F(URLRequestTestHTTP, NetworkDelegateBlockAsynchronously) { | |
2897 static const BlockingNetworkDelegate::Stage blocking_stages[] = { | |
2898 BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST, | |
2899 BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS, | |
2900 BlockingNetworkDelegate::ON_HEADERS_RECEIVED | |
2901 }; | |
2902 static const size_t blocking_stages_length = arraysize(blocking_stages); | |
2903 | |
2904 ASSERT_TRUE(test_server_.Start()); | |
2905 | |
2906 TestDelegate d; | |
2907 BlockingNetworkDelegate network_delegate( | |
2908 BlockingNetworkDelegate::USER_CALLBACK); | |
2909 network_delegate.set_block_on( | |
2910 BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST | | |
2911 BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS | | |
2912 BlockingNetworkDelegate::ON_HEADERS_RECEIVED); | |
2913 | |
2914 TestURLRequestContext context(true); | |
2915 context.set_network_delegate(&network_delegate); | |
2916 context.Init(); | |
2917 | |
2918 { | |
2919 scoped_ptr<URLRequest> r(context.CreateRequest( | |
2920 test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d, NULL)); | |
2921 | |
2922 r->Start(); | |
2923 for (size_t i = 0; i < blocking_stages_length; ++i) { | |
2924 base::RunLoop().Run(); | |
2925 EXPECT_EQ(blocking_stages[i], | |
2926 network_delegate.stage_blocked_for_callback()); | |
2927 network_delegate.DoCallback(OK); | |
2928 } | |
2929 base::RunLoop().Run(); | |
2930 EXPECT_EQ(200, r->GetResponseCode()); | |
2931 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
2932 EXPECT_EQ(1, network_delegate.created_requests()); | |
2933 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
2934 } | |
2935 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
2936 } | |
2937 | |
2938 // Tests that the network delegate can block and cancel a request. | |
2939 TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequest) { | |
2940 ASSERT_TRUE(test_server_.Start()); | |
2941 | |
2942 TestDelegate d; | |
2943 BlockingNetworkDelegate network_delegate( | |
2944 BlockingNetworkDelegate::AUTO_CALLBACK); | |
2945 network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST); | |
2946 network_delegate.set_retval(ERR_EMPTY_RESPONSE); | |
2947 | |
2948 TestURLRequestContextWithProxy context( | |
2949 test_server_.host_port_pair().ToString(), &network_delegate); | |
2950 | |
2951 { | |
2952 scoped_ptr<URLRequest> r(context.CreateRequest( | |
2953 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
2954 | |
2955 r->Start(); | |
2956 base::RunLoop().Run(); | |
2957 | |
2958 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); | |
2959 // The proxy server is not set before cancellation. | |
2960 EXPECT_TRUE(r->proxy_server().IsEmpty()); | |
2961 EXPECT_EQ(ERR_EMPTY_RESPONSE, r->status().error()); | |
2962 EXPECT_EQ(1, network_delegate.created_requests()); | |
2963 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
2964 } | |
2965 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
2966 } | |
2967 | |
2968 // Helper function for NetworkDelegateCancelRequestAsynchronously and | |
2969 // NetworkDelegateCancelRequestSynchronously. Sets up a blocking network | |
2970 // delegate operating in |block_mode| and a request for |url|. It blocks the | |
2971 // request in |stage| and cancels it with ERR_BLOCKED_BY_CLIENT. | |
2972 void NetworkDelegateCancelRequest(BlockingNetworkDelegate::BlockMode block_mode, | |
2973 BlockingNetworkDelegate::Stage stage, | |
2974 const GURL& url) { | |
2975 TestDelegate d; | |
2976 BlockingNetworkDelegate network_delegate(block_mode); | |
2977 network_delegate.set_retval(ERR_BLOCKED_BY_CLIENT); | |
2978 network_delegate.set_block_on(stage); | |
2979 | |
2980 TestURLRequestContext context(true); | |
2981 context.set_network_delegate(&network_delegate); | |
2982 context.Init(); | |
2983 | |
2984 { | |
2985 scoped_ptr<URLRequest> r(context.CreateRequest( | |
2986 url, DEFAULT_PRIORITY, &d, NULL)); | |
2987 | |
2988 r->Start(); | |
2989 base::RunLoop().Run(); | |
2990 | |
2991 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); | |
2992 // The proxy server is not set before cancellation. | |
2993 EXPECT_TRUE(r->proxy_server().IsEmpty()); | |
2994 EXPECT_EQ(ERR_BLOCKED_BY_CLIENT, r->status().error()); | |
2995 EXPECT_EQ(1, network_delegate.created_requests()); | |
2996 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
2997 } | |
2998 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
2999 } | |
3000 | |
3001 // The following 3 tests check that the network delegate can cancel a request | |
3002 // synchronously in various stages of the request. | |
3003 TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously1) { | |
3004 ASSERT_TRUE(test_server_.Start()); | |
3005 NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS, | |
3006 BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST, | |
3007 test_server_.GetURL(std::string())); | |
3008 } | |
3009 | |
3010 TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously2) { | |
3011 ASSERT_TRUE(test_server_.Start()); | |
3012 NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS, | |
3013 BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS, | |
3014 test_server_.GetURL(std::string())); | |
3015 } | |
3016 | |
3017 TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously3) { | |
3018 ASSERT_TRUE(test_server_.Start()); | |
3019 NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS, | |
3020 BlockingNetworkDelegate::ON_HEADERS_RECEIVED, | |
3021 test_server_.GetURL(std::string())); | |
3022 } | |
3023 | |
3024 // The following 3 tests check that the network delegate can cancel a request | |
3025 // asynchronously in various stages of the request. | |
3026 TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously1) { | |
3027 ASSERT_TRUE(test_server_.Start()); | |
3028 NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK, | |
3029 BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST, | |
3030 test_server_.GetURL(std::string())); | |
3031 } | |
3032 | |
3033 TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously2) { | |
3034 ASSERT_TRUE(test_server_.Start()); | |
3035 NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK, | |
3036 BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS, | |
3037 test_server_.GetURL(std::string())); | |
3038 } | |
3039 | |
3040 TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously3) { | |
3041 ASSERT_TRUE(test_server_.Start()); | |
3042 NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK, | |
3043 BlockingNetworkDelegate::ON_HEADERS_RECEIVED, | |
3044 test_server_.GetURL(std::string())); | |
3045 } | |
3046 | |
3047 // Tests that the network delegate can block and redirect a request to a new | |
3048 // URL. | |
3049 TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequest) { | |
3050 ASSERT_TRUE(test_server_.Start()); | |
3051 | |
3052 TestDelegate d; | |
3053 BlockingNetworkDelegate network_delegate( | |
3054 BlockingNetworkDelegate::AUTO_CALLBACK); | |
3055 network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST); | |
3056 GURL redirect_url(test_server_.GetURL("simple.html")); | |
3057 network_delegate.set_redirect_url(redirect_url); | |
3058 | |
3059 TestURLRequestContextWithProxy context( | |
3060 test_server_.host_port_pair().ToString(), &network_delegate); | |
3061 | |
3062 { | |
3063 GURL original_url(test_server_.GetURL("empty.html")); | |
3064 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3065 original_url, DEFAULT_PRIORITY, &d, NULL)); | |
3066 | |
3067 // Quit after hitting the redirect, so can check the headers. | |
3068 d.set_quit_on_redirect(true); | |
3069 r->Start(); | |
3070 base::RunLoop().Run(); | |
3071 | |
3072 // Check headers from URLRequestJob. | |
3073 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3074 EXPECT_EQ(307, r->GetResponseCode()); | |
3075 EXPECT_EQ(307, r->response_headers()->response_code()); | |
3076 std::string location; | |
3077 ASSERT_TRUE(r->response_headers()->EnumerateHeader(NULL, "Location", | |
3078 &location)); | |
3079 EXPECT_EQ(redirect_url, GURL(location)); | |
3080 | |
3081 // Let the request finish. | |
3082 r->FollowDeferredRedirect(); | |
3083 base::RunLoop().Run(); | |
3084 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3085 EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair())); | |
3086 EXPECT_EQ( | |
3087 1, network_delegate.observed_before_proxy_headers_sent_callbacks()); | |
3088 EXPECT_TRUE( | |
3089 network_delegate.last_observed_proxy().Equals( | |
3090 test_server_.host_port_pair())); | |
3091 | |
3092 EXPECT_EQ(0, r->status().error()); | |
3093 EXPECT_EQ(redirect_url, r->url()); | |
3094 EXPECT_EQ(original_url, r->original_url()); | |
3095 EXPECT_EQ(2U, r->url_chain().size()); | |
3096 EXPECT_EQ(1, network_delegate.created_requests()); | |
3097 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3098 } | |
3099 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3100 } | |
3101 | |
3102 // Tests that the network delegate can block and redirect a request to a new | |
3103 // URL by setting a redirect_url and returning in OnBeforeURLRequest directly. | |
3104 TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestSynchronously) { | |
3105 ASSERT_TRUE(test_server_.Start()); | |
3106 | |
3107 TestDelegate d; | |
3108 BlockingNetworkDelegate network_delegate( | |
3109 BlockingNetworkDelegate::SYNCHRONOUS); | |
3110 GURL redirect_url(test_server_.GetURL("simple.html")); | |
3111 network_delegate.set_redirect_url(redirect_url); | |
3112 | |
3113 TestURLRequestContextWithProxy context( | |
3114 test_server_.host_port_pair().ToString(), &network_delegate); | |
3115 | |
3116 { | |
3117 GURL original_url(test_server_.GetURL("empty.html")); | |
3118 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3119 original_url, DEFAULT_PRIORITY, &d, NULL)); | |
3120 | |
3121 // Quit after hitting the redirect, so can check the headers. | |
3122 d.set_quit_on_redirect(true); | |
3123 r->Start(); | |
3124 base::RunLoop().Run(); | |
3125 | |
3126 // Check headers from URLRequestJob. | |
3127 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3128 EXPECT_EQ(307, r->GetResponseCode()); | |
3129 EXPECT_EQ(307, r->response_headers()->response_code()); | |
3130 std::string location; | |
3131 ASSERT_TRUE(r->response_headers()->EnumerateHeader(NULL, "Location", | |
3132 &location)); | |
3133 EXPECT_EQ(redirect_url, GURL(location)); | |
3134 | |
3135 // Let the request finish. | |
3136 r->FollowDeferredRedirect(); | |
3137 base::RunLoop().Run(); | |
3138 | |
3139 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3140 EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair())); | |
3141 EXPECT_EQ( | |
3142 1, network_delegate.observed_before_proxy_headers_sent_callbacks()); | |
3143 EXPECT_TRUE( | |
3144 network_delegate.last_observed_proxy().Equals( | |
3145 test_server_.host_port_pair())); | |
3146 EXPECT_EQ(0, r->status().error()); | |
3147 EXPECT_EQ(redirect_url, r->url()); | |
3148 EXPECT_EQ(original_url, r->original_url()); | |
3149 EXPECT_EQ(2U, r->url_chain().size()); | |
3150 EXPECT_EQ(1, network_delegate.created_requests()); | |
3151 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3152 } | |
3153 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3154 } | |
3155 | |
3156 // Tests that redirects caused by the network delegate preserve POST data. | |
3157 TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestPost) { | |
3158 ASSERT_TRUE(test_server_.Start()); | |
3159 | |
3160 const char kData[] = "hello world"; | |
3161 | |
3162 TestDelegate d; | |
3163 BlockingNetworkDelegate network_delegate( | |
3164 BlockingNetworkDelegate::AUTO_CALLBACK); | |
3165 network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST); | |
3166 GURL redirect_url(test_server_.GetURL("echo")); | |
3167 network_delegate.set_redirect_url(redirect_url); | |
3168 | |
3169 TestURLRequestContext context(true); | |
3170 context.set_network_delegate(&network_delegate); | |
3171 context.Init(); | |
3172 | |
3173 { | |
3174 GURL original_url(test_server_.GetURL("empty.html")); | |
3175 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3176 original_url, DEFAULT_PRIORITY, &d, NULL)); | |
3177 r->set_method("POST"); | |
3178 r->set_upload(CreateSimpleUploadData(kData)); | |
3179 HttpRequestHeaders headers; | |
3180 headers.SetHeader(HttpRequestHeaders::kContentLength, | |
3181 base::UintToString(arraysize(kData) - 1)); | |
3182 r->SetExtraRequestHeaders(headers); | |
3183 | |
3184 // Quit after hitting the redirect, so can check the headers. | |
3185 d.set_quit_on_redirect(true); | |
3186 r->Start(); | |
3187 base::RunLoop().Run(); | |
3188 | |
3189 // Check headers from URLRequestJob. | |
3190 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3191 EXPECT_EQ(307, r->GetResponseCode()); | |
3192 EXPECT_EQ(307, r->response_headers()->response_code()); | |
3193 std::string location; | |
3194 ASSERT_TRUE(r->response_headers()->EnumerateHeader(NULL, "Location", | |
3195 &location)); | |
3196 EXPECT_EQ(redirect_url, GURL(location)); | |
3197 | |
3198 // Let the request finish. | |
3199 r->FollowDeferredRedirect(); | |
3200 base::RunLoop().Run(); | |
3201 | |
3202 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3203 EXPECT_EQ(0, r->status().error()); | |
3204 EXPECT_EQ(redirect_url, r->url()); | |
3205 EXPECT_EQ(original_url, r->original_url()); | |
3206 EXPECT_EQ(2U, r->url_chain().size()); | |
3207 EXPECT_EQ(1, network_delegate.created_requests()); | |
3208 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3209 EXPECT_EQ("POST", r->method()); | |
3210 EXPECT_EQ(kData, d.data_received()); | |
3211 } | |
3212 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3213 } | |
3214 | |
3215 // Tests that the network delegate can block and redirect a request to a new | |
3216 // URL during OnHeadersReceived. | |
3217 TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestOnHeadersReceived) { | |
3218 ASSERT_TRUE(test_server_.Start()); | |
3219 | |
3220 TestDelegate d; | |
3221 BlockingNetworkDelegate network_delegate( | |
3222 BlockingNetworkDelegate::AUTO_CALLBACK); | |
3223 network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED); | |
3224 GURL redirect_url(test_server_.GetURL("simple.html")); | |
3225 network_delegate.set_redirect_on_headers_received_url(redirect_url); | |
3226 | |
3227 TestURLRequestContextWithProxy context( | |
3228 test_server_.host_port_pair().ToString(), &network_delegate); | |
3229 | |
3230 { | |
3231 GURL original_url(test_server_.GetURL("empty.html")); | |
3232 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3233 original_url, DEFAULT_PRIORITY, &d, NULL)); | |
3234 | |
3235 r->Start(); | |
3236 base::RunLoop().Run(); | |
3237 | |
3238 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3239 EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair())); | |
3240 EXPECT_EQ( | |
3241 2, network_delegate.observed_before_proxy_headers_sent_callbacks()); | |
3242 EXPECT_TRUE( | |
3243 network_delegate.last_observed_proxy().Equals( | |
3244 test_server_.host_port_pair())); | |
3245 | |
3246 EXPECT_EQ(OK, r->status().error()); | |
3247 EXPECT_EQ(redirect_url, r->url()); | |
3248 EXPECT_EQ(original_url, r->original_url()); | |
3249 EXPECT_EQ(2U, r->url_chain().size()); | |
3250 EXPECT_EQ(2, network_delegate.created_requests()); | |
3251 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3252 } | |
3253 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3254 } | |
3255 | |
3256 // Tests that the network delegate can synchronously complete OnAuthRequired | |
3257 // by taking no action. This indicates that the NetworkDelegate does not want to | |
3258 // handle the challenge, and is passing the buck along to the | |
3259 // URLRequest::Delegate. | |
3260 TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncNoAction) { | |
3261 ASSERT_TRUE(test_server_.Start()); | |
3262 | |
3263 TestDelegate d; | |
3264 BlockingNetworkDelegate network_delegate( | |
3265 BlockingNetworkDelegate::SYNCHRONOUS); | |
3266 | |
3267 TestURLRequestContext context(true); | |
3268 context.set_network_delegate(&network_delegate); | |
3269 context.Init(); | |
3270 | |
3271 d.set_credentials(AuthCredentials(kUser, kSecret)); | |
3272 | |
3273 { | |
3274 GURL url(test_server_.GetURL("auth-basic")); | |
3275 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3276 url, DEFAULT_PRIORITY, &d, NULL)); | |
3277 r->Start(); | |
3278 | |
3279 base::RunLoop().Run(); | |
3280 | |
3281 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3282 EXPECT_EQ(0, r->status().error()); | |
3283 EXPECT_EQ(200, r->GetResponseCode()); | |
3284 EXPECT_TRUE(d.auth_required_called()); | |
3285 EXPECT_EQ(1, network_delegate.created_requests()); | |
3286 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3287 } | |
3288 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3289 } | |
3290 | |
3291 TEST_F(URLRequestTestHTTP, | |
3292 NetworkDelegateOnAuthRequiredSyncNoAction_GetFullRequestHeaders) { | |
3293 ASSERT_TRUE(test_server_.Start()); | |
3294 | |
3295 TestDelegate d; | |
3296 BlockingNetworkDelegate network_delegate( | |
3297 BlockingNetworkDelegate::SYNCHRONOUS); | |
3298 | |
3299 TestURLRequestContext context(true); | |
3300 context.set_network_delegate(&network_delegate); | |
3301 context.Init(); | |
3302 | |
3303 d.set_credentials(AuthCredentials(kUser, kSecret)); | |
3304 | |
3305 { | |
3306 GURL url(test_server_.GetURL("auth-basic")); | |
3307 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3308 url, DEFAULT_PRIORITY, &d, NULL)); | |
3309 r->Start(); | |
3310 | |
3311 { | |
3312 HttpRequestHeaders headers; | |
3313 EXPECT_TRUE(r->GetFullRequestHeaders(&headers)); | |
3314 EXPECT_FALSE(headers.HasHeader("Authorization")); | |
3315 } | |
3316 | |
3317 base::RunLoop().Run(); | |
3318 | |
3319 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3320 EXPECT_EQ(0, r->status().error()); | |
3321 EXPECT_EQ(200, r->GetResponseCode()); | |
3322 EXPECT_TRUE(d.auth_required_called()); | |
3323 EXPECT_EQ(1, network_delegate.created_requests()); | |
3324 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3325 } | |
3326 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3327 } | |
3328 | |
3329 // Tests that the network delegate can synchronously complete OnAuthRequired | |
3330 // by setting credentials. | |
3331 TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncSetAuth) { | |
3332 ASSERT_TRUE(test_server_.Start()); | |
3333 | |
3334 TestDelegate d; | |
3335 BlockingNetworkDelegate network_delegate( | |
3336 BlockingNetworkDelegate::SYNCHRONOUS); | |
3337 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); | |
3338 network_delegate.set_auth_retval( | |
3339 NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH); | |
3340 | |
3341 network_delegate.set_auth_credentials(AuthCredentials(kUser, kSecret)); | |
3342 | |
3343 TestURLRequestContext context(true); | |
3344 context.set_network_delegate(&network_delegate); | |
3345 context.Init(); | |
3346 | |
3347 { | |
3348 GURL url(test_server_.GetURL("auth-basic")); | |
3349 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3350 url, DEFAULT_PRIORITY, &d, NULL)); | |
3351 r->Start(); | |
3352 base::RunLoop().Run(); | |
3353 | |
3354 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3355 EXPECT_EQ(0, r->status().error()); | |
3356 EXPECT_EQ(200, r->GetResponseCode()); | |
3357 EXPECT_FALSE(d.auth_required_called()); | |
3358 EXPECT_EQ(1, network_delegate.created_requests()); | |
3359 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3360 } | |
3361 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3362 } | |
3363 | |
3364 // Same as above, but also tests that GetFullRequestHeaders returns the proper | |
3365 // headers (for the first or second request) when called at the proper times. | |
3366 TEST_F(URLRequestTestHTTP, | |
3367 NetworkDelegateOnAuthRequiredSyncSetAuth_GetFullRequestHeaders) { | |
3368 ASSERT_TRUE(test_server_.Start()); | |
3369 | |
3370 TestDelegate d; | |
3371 BlockingNetworkDelegate network_delegate( | |
3372 BlockingNetworkDelegate::SYNCHRONOUS); | |
3373 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); | |
3374 network_delegate.set_auth_retval( | |
3375 NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH); | |
3376 | |
3377 network_delegate.set_auth_credentials(AuthCredentials(kUser, kSecret)); | |
3378 | |
3379 TestURLRequestContext context(true); | |
3380 context.set_network_delegate(&network_delegate); | |
3381 context.Init(); | |
3382 | |
3383 { | |
3384 GURL url(test_server_.GetURL("auth-basic")); | |
3385 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3386 url, DEFAULT_PRIORITY, &d, NULL)); | |
3387 r->Start(); | |
3388 base::RunLoop().Run(); | |
3389 | |
3390 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3391 EXPECT_EQ(0, r->status().error()); | |
3392 EXPECT_EQ(200, r->GetResponseCode()); | |
3393 EXPECT_FALSE(d.auth_required_called()); | |
3394 EXPECT_EQ(1, network_delegate.created_requests()); | |
3395 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3396 | |
3397 { | |
3398 HttpRequestHeaders headers; | |
3399 EXPECT_TRUE(r->GetFullRequestHeaders(&headers)); | |
3400 EXPECT_TRUE(headers.HasHeader("Authorization")); | |
3401 } | |
3402 } | |
3403 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3404 } | |
3405 | |
3406 // Tests that the network delegate can synchronously complete OnAuthRequired | |
3407 // by cancelling authentication. | |
3408 TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncCancel) { | |
3409 ASSERT_TRUE(test_server_.Start()); | |
3410 | |
3411 TestDelegate d; | |
3412 BlockingNetworkDelegate network_delegate( | |
3413 BlockingNetworkDelegate::SYNCHRONOUS); | |
3414 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); | |
3415 network_delegate.set_auth_retval( | |
3416 NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH); | |
3417 | |
3418 TestURLRequestContext context(true); | |
3419 context.set_network_delegate(&network_delegate); | |
3420 context.Init(); | |
3421 | |
3422 { | |
3423 GURL url(test_server_.GetURL("auth-basic")); | |
3424 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3425 url, DEFAULT_PRIORITY, &d, NULL)); | |
3426 r->Start(); | |
3427 base::RunLoop().Run(); | |
3428 | |
3429 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3430 EXPECT_EQ(OK, r->status().error()); | |
3431 EXPECT_EQ(401, r->GetResponseCode()); | |
3432 EXPECT_FALSE(d.auth_required_called()); | |
3433 EXPECT_EQ(1, network_delegate.created_requests()); | |
3434 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3435 } | |
3436 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3437 } | |
3438 | |
3439 // Tests that the network delegate can asynchronously complete OnAuthRequired | |
3440 // by taking no action. This indicates that the NetworkDelegate does not want | |
3441 // to handle the challenge, and is passing the buck along to the | |
3442 // URLRequest::Delegate. | |
3443 TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncNoAction) { | |
3444 ASSERT_TRUE(test_server_.Start()); | |
3445 | |
3446 TestDelegate d; | |
3447 BlockingNetworkDelegate network_delegate( | |
3448 BlockingNetworkDelegate::AUTO_CALLBACK); | |
3449 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); | |
3450 | |
3451 TestURLRequestContext context(true); | |
3452 context.set_network_delegate(&network_delegate); | |
3453 context.Init(); | |
3454 | |
3455 d.set_credentials(AuthCredentials(kUser, kSecret)); | |
3456 | |
3457 { | |
3458 GURL url(test_server_.GetURL("auth-basic")); | |
3459 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3460 url, DEFAULT_PRIORITY, &d, NULL)); | |
3461 r->Start(); | |
3462 base::RunLoop().Run(); | |
3463 | |
3464 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3465 EXPECT_EQ(0, r->status().error()); | |
3466 EXPECT_EQ(200, r->GetResponseCode()); | |
3467 EXPECT_TRUE(d.auth_required_called()); | |
3468 EXPECT_EQ(1, network_delegate.created_requests()); | |
3469 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3470 } | |
3471 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3472 } | |
3473 | |
3474 // Tests that the network delegate can asynchronously complete OnAuthRequired | |
3475 // by setting credentials. | |
3476 TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncSetAuth) { | |
3477 ASSERT_TRUE(test_server_.Start()); | |
3478 | |
3479 TestDelegate d; | |
3480 BlockingNetworkDelegate network_delegate( | |
3481 BlockingNetworkDelegate::AUTO_CALLBACK); | |
3482 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); | |
3483 network_delegate.set_auth_retval( | |
3484 NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH); | |
3485 | |
3486 AuthCredentials auth_credentials(kUser, kSecret); | |
3487 network_delegate.set_auth_credentials(auth_credentials); | |
3488 | |
3489 TestURLRequestContext context(true); | |
3490 context.set_network_delegate(&network_delegate); | |
3491 context.Init(); | |
3492 | |
3493 { | |
3494 GURL url(test_server_.GetURL("auth-basic")); | |
3495 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3496 url, DEFAULT_PRIORITY, &d, NULL)); | |
3497 r->Start(); | |
3498 base::RunLoop().Run(); | |
3499 | |
3500 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3501 EXPECT_EQ(0, r->status().error()); | |
3502 | |
3503 EXPECT_EQ(200, r->GetResponseCode()); | |
3504 EXPECT_FALSE(d.auth_required_called()); | |
3505 EXPECT_EQ(1, network_delegate.created_requests()); | |
3506 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3507 } | |
3508 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3509 } | |
3510 | |
3511 // Tests that the network delegate can asynchronously complete OnAuthRequired | |
3512 // by cancelling authentication. | |
3513 TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncCancel) { | |
3514 ASSERT_TRUE(test_server_.Start()); | |
3515 | |
3516 TestDelegate d; | |
3517 BlockingNetworkDelegate network_delegate( | |
3518 BlockingNetworkDelegate::AUTO_CALLBACK); | |
3519 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); | |
3520 network_delegate.set_auth_retval( | |
3521 NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH); | |
3522 | |
3523 TestURLRequestContext context(true); | |
3524 context.set_network_delegate(&network_delegate); | |
3525 context.Init(); | |
3526 | |
3527 { | |
3528 GURL url(test_server_.GetURL("auth-basic")); | |
3529 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3530 url, DEFAULT_PRIORITY, &d, NULL)); | |
3531 r->Start(); | |
3532 base::RunLoop().Run(); | |
3533 | |
3534 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
3535 EXPECT_EQ(OK, r->status().error()); | |
3536 EXPECT_EQ(401, r->GetResponseCode()); | |
3537 EXPECT_FALSE(d.auth_required_called()); | |
3538 EXPECT_EQ(1, network_delegate.created_requests()); | |
3539 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3540 } | |
3541 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3542 } | |
3543 | |
3544 // Tests that we can handle when a network request was canceled while we were | |
3545 // waiting for the network delegate. | |
3546 // Part 1: Request is cancelled while waiting for OnBeforeURLRequest callback. | |
3547 TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting1) { | |
3548 ASSERT_TRUE(test_server_.Start()); | |
3549 | |
3550 TestDelegate d; | |
3551 BlockingNetworkDelegate network_delegate( | |
3552 BlockingNetworkDelegate::USER_CALLBACK); | |
3553 network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST); | |
3554 | |
3555 TestURLRequestContext context(true); | |
3556 context.set_network_delegate(&network_delegate); | |
3557 context.Init(); | |
3558 | |
3559 { | |
3560 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3561 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
3562 | |
3563 r->Start(); | |
3564 base::RunLoop().Run(); | |
3565 EXPECT_EQ(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST, | |
3566 network_delegate.stage_blocked_for_callback()); | |
3567 EXPECT_EQ(0, network_delegate.completed_requests()); | |
3568 // Cancel before callback. | |
3569 r->Cancel(); | |
3570 // Ensure that network delegate is notified. | |
3571 EXPECT_EQ(1, network_delegate.completed_requests()); | |
3572 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); | |
3573 EXPECT_EQ(ERR_ABORTED, r->status().error()); | |
3574 EXPECT_EQ(1, network_delegate.created_requests()); | |
3575 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3576 } | |
3577 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3578 } | |
3579 | |
3580 // Tests that we can handle when a network request was canceled while we were | |
3581 // waiting for the network delegate. | |
3582 // Part 2: Request is cancelled while waiting for OnBeforeSendHeaders callback. | |
3583 TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting2) { | |
3584 ASSERT_TRUE(test_server_.Start()); | |
3585 | |
3586 TestDelegate d; | |
3587 BlockingNetworkDelegate network_delegate( | |
3588 BlockingNetworkDelegate::USER_CALLBACK); | |
3589 network_delegate.set_block_on( | |
3590 BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS); | |
3591 | |
3592 TestURLRequestContext context(true); | |
3593 context.set_network_delegate(&network_delegate); | |
3594 context.Init(); | |
3595 | |
3596 { | |
3597 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3598 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
3599 | |
3600 r->Start(); | |
3601 base::RunLoop().Run(); | |
3602 EXPECT_EQ(BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS, | |
3603 network_delegate.stage_blocked_for_callback()); | |
3604 EXPECT_EQ(0, network_delegate.completed_requests()); | |
3605 // Cancel before callback. | |
3606 r->Cancel(); | |
3607 // Ensure that network delegate is notified. | |
3608 EXPECT_EQ(1, network_delegate.completed_requests()); | |
3609 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); | |
3610 EXPECT_EQ(ERR_ABORTED, r->status().error()); | |
3611 EXPECT_EQ(1, network_delegate.created_requests()); | |
3612 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3613 } | |
3614 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3615 } | |
3616 | |
3617 // Tests that we can handle when a network request was canceled while we were | |
3618 // waiting for the network delegate. | |
3619 // Part 3: Request is cancelled while waiting for OnHeadersReceived callback. | |
3620 TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting3) { | |
3621 ASSERT_TRUE(test_server_.Start()); | |
3622 | |
3623 TestDelegate d; | |
3624 BlockingNetworkDelegate network_delegate( | |
3625 BlockingNetworkDelegate::USER_CALLBACK); | |
3626 network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED); | |
3627 | |
3628 TestURLRequestContext context(true); | |
3629 context.set_network_delegate(&network_delegate); | |
3630 context.Init(); | |
3631 | |
3632 { | |
3633 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3634 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
3635 | |
3636 r->Start(); | |
3637 base::RunLoop().Run(); | |
3638 EXPECT_EQ(BlockingNetworkDelegate::ON_HEADERS_RECEIVED, | |
3639 network_delegate.stage_blocked_for_callback()); | |
3640 EXPECT_EQ(0, network_delegate.completed_requests()); | |
3641 // Cancel before callback. | |
3642 r->Cancel(); | |
3643 // Ensure that network delegate is notified. | |
3644 EXPECT_EQ(1, network_delegate.completed_requests()); | |
3645 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); | |
3646 EXPECT_EQ(ERR_ABORTED, r->status().error()); | |
3647 EXPECT_EQ(1, network_delegate.created_requests()); | |
3648 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3649 } | |
3650 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3651 } | |
3652 | |
3653 // Tests that we can handle when a network request was canceled while we were | |
3654 // waiting for the network delegate. | |
3655 // Part 4: Request is cancelled while waiting for OnAuthRequired callback. | |
3656 TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting4) { | |
3657 ASSERT_TRUE(test_server_.Start()); | |
3658 | |
3659 TestDelegate d; | |
3660 BlockingNetworkDelegate network_delegate( | |
3661 BlockingNetworkDelegate::USER_CALLBACK); | |
3662 network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED); | |
3663 | |
3664 TestURLRequestContext context(true); | |
3665 context.set_network_delegate(&network_delegate); | |
3666 context.Init(); | |
3667 | |
3668 { | |
3669 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3670 test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL)); | |
3671 | |
3672 r->Start(); | |
3673 base::RunLoop().Run(); | |
3674 EXPECT_EQ(BlockingNetworkDelegate::ON_AUTH_REQUIRED, | |
3675 network_delegate.stage_blocked_for_callback()); | |
3676 EXPECT_EQ(0, network_delegate.completed_requests()); | |
3677 // Cancel before callback. | |
3678 r->Cancel(); | |
3679 // Ensure that network delegate is notified. | |
3680 EXPECT_EQ(1, network_delegate.completed_requests()); | |
3681 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); | |
3682 EXPECT_EQ(ERR_ABORTED, r->status().error()); | |
3683 EXPECT_EQ(1, network_delegate.created_requests()); | |
3684 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3685 } | |
3686 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3687 } | |
3688 | |
3689 // In this unit test, we're using the HTTPTestServer as a proxy server and | |
3690 // issuing a CONNECT request with the magic host name "www.server-auth.com". | |
3691 // The HTTPTestServer will return a 401 response, which we should balk at. | |
3692 TEST_F(URLRequestTestHTTP, UnexpectedServerAuthTest) { | |
3693 ASSERT_TRUE(test_server_.Start()); | |
3694 | |
3695 TestNetworkDelegate network_delegate; // Must outlive URLRequest. | |
3696 TestURLRequestContextWithProxy context( | |
3697 test_server_.host_port_pair().ToString(), &network_delegate); | |
3698 | |
3699 TestDelegate d; | |
3700 { | |
3701 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3702 GURL("https://www.server-auth.com/"), DEFAULT_PRIORITY, &d, NULL)); | |
3703 | |
3704 r->Start(); | |
3705 EXPECT_TRUE(r->is_pending()); | |
3706 | |
3707 base::RunLoop().Run(); | |
3708 | |
3709 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); | |
3710 // The proxy server is not set before failure. | |
3711 EXPECT_TRUE(r->proxy_server().IsEmpty()); | |
3712 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r->status().error()); | |
3713 } | |
3714 } | |
3715 | |
3716 TEST_F(URLRequestTestHTTP, GetTest_NoCache) { | |
3717 ASSERT_TRUE(test_server_.Start()); | |
3718 | |
3719 TestDelegate d; | |
3720 { | |
3721 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
3722 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
3723 | |
3724 r->Start(); | |
3725 EXPECT_TRUE(r->is_pending()); | |
3726 | |
3727 base::RunLoop().Run(); | |
3728 | |
3729 EXPECT_EQ(1, d.response_started_count()); | |
3730 EXPECT_FALSE(d.received_data_before_response()); | |
3731 EXPECT_NE(0, d.bytes_received()); | |
3732 EXPECT_EQ(test_server_.host_port_pair().host(), | |
3733 r->GetSocketAddress().host()); | |
3734 EXPECT_EQ(test_server_.host_port_pair().port(), | |
3735 r->GetSocketAddress().port()); | |
3736 | |
3737 // TODO(eroman): Add back the NetLog tests... | |
3738 } | |
3739 } | |
3740 | |
3741 // This test has the server send a large number of cookies to the client. | |
3742 // To ensure that no number of cookies causes a crash, a galloping binary | |
3743 // search is used to estimate that maximum number of cookies that are accepted | |
3744 // by the browser. Beyond the maximum number, the request will fail with | |
3745 // ERR_RESPONSE_HEADERS_TOO_BIG. | |
3746 #if defined(OS_WIN) | |
3747 // http://crbug.com/177916 | |
3748 #define MAYBE_GetTest_ManyCookies DISABLED_GetTest_ManyCookies | |
3749 #else | |
3750 #define MAYBE_GetTest_ManyCookies GetTest_ManyCookies | |
3751 #endif // defined(OS_WIN) | |
3752 TEST_F(URLRequestTestHTTP, MAYBE_GetTest_ManyCookies) { | |
3753 ASSERT_TRUE(test_server_.Start()); | |
3754 | |
3755 int lower_bound = 0; | |
3756 int upper_bound = 1; | |
3757 | |
3758 // Double the number of cookies until the response header limits are | |
3759 // exceeded. | |
3760 while (DoManyCookiesRequest(upper_bound)) { | |
3761 lower_bound = upper_bound; | |
3762 upper_bound *= 2; | |
3763 ASSERT_LT(upper_bound, 1000000); | |
3764 } | |
3765 | |
3766 int tolerance = static_cast<int>(upper_bound * 0.005); | |
3767 if (tolerance < 2) | |
3768 tolerance = 2; | |
3769 | |
3770 // Perform a binary search to find the highest possible number of cookies, | |
3771 // within the desired tolerance. | |
3772 while (upper_bound - lower_bound >= tolerance) { | |
3773 int num_cookies = (lower_bound + upper_bound) / 2; | |
3774 | |
3775 if (DoManyCookiesRequest(num_cookies)) | |
3776 lower_bound = num_cookies; | |
3777 else | |
3778 upper_bound = num_cookies; | |
3779 } | |
3780 // Success: the test did not crash. | |
3781 } | |
3782 | |
3783 TEST_F(URLRequestTestHTTP, GetTest) { | |
3784 ASSERT_TRUE(test_server_.Start()); | |
3785 | |
3786 TestDelegate d; | |
3787 { | |
3788 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
3789 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
3790 | |
3791 r->Start(); | |
3792 EXPECT_TRUE(r->is_pending()); | |
3793 | |
3794 base::RunLoop().Run(); | |
3795 | |
3796 EXPECT_EQ(1, d.response_started_count()); | |
3797 EXPECT_FALSE(d.received_data_before_response()); | |
3798 EXPECT_NE(0, d.bytes_received()); | |
3799 EXPECT_EQ(test_server_.host_port_pair().host(), | |
3800 r->GetSocketAddress().host()); | |
3801 EXPECT_EQ(test_server_.host_port_pair().port(), | |
3802 r->GetSocketAddress().port()); | |
3803 } | |
3804 } | |
3805 | |
3806 TEST_F(URLRequestTestHTTP, GetTest_GetFullRequestHeaders) { | |
3807 ASSERT_TRUE(test_server_.Start()); | |
3808 | |
3809 TestDelegate d; | |
3810 { | |
3811 GURL test_url(test_server_.GetURL(std::string())); | |
3812 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
3813 test_url, DEFAULT_PRIORITY, &d, NULL)); | |
3814 | |
3815 HttpRequestHeaders headers; | |
3816 EXPECT_FALSE(r->GetFullRequestHeaders(&headers)); | |
3817 | |
3818 r->Start(); | |
3819 EXPECT_TRUE(r->is_pending()); | |
3820 | |
3821 base::RunLoop().Run(); | |
3822 | |
3823 EXPECT_EQ(1, d.response_started_count()); | |
3824 EXPECT_FALSE(d.received_data_before_response()); | |
3825 EXPECT_NE(0, d.bytes_received()); | |
3826 EXPECT_EQ(test_server_.host_port_pair().host(), | |
3827 r->GetSocketAddress().host()); | |
3828 EXPECT_EQ(test_server_.host_port_pair().port(), | |
3829 r->GetSocketAddress().port()); | |
3830 | |
3831 EXPECT_TRUE(d.have_full_request_headers()); | |
3832 CheckFullRequestHeaders(d.full_request_headers(), test_url); | |
3833 } | |
3834 } | |
3835 | |
3836 TEST_F(URLRequestTestHTTP, GetTestLoadTiming) { | |
3837 ASSERT_TRUE(test_server_.Start()); | |
3838 | |
3839 TestDelegate d; | |
3840 { | |
3841 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
3842 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
3843 | |
3844 r->Start(); | |
3845 EXPECT_TRUE(r->is_pending()); | |
3846 | |
3847 base::RunLoop().Run(); | |
3848 | |
3849 LoadTimingInfo load_timing_info; | |
3850 r->GetLoadTimingInfo(&load_timing_info); | |
3851 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); | |
3852 | |
3853 EXPECT_EQ(1, d.response_started_count()); | |
3854 EXPECT_FALSE(d.received_data_before_response()); | |
3855 EXPECT_NE(0, d.bytes_received()); | |
3856 EXPECT_EQ(test_server_.host_port_pair().host(), | |
3857 r->GetSocketAddress().host()); | |
3858 EXPECT_EQ(test_server_.host_port_pair().port(), | |
3859 r->GetSocketAddress().port()); | |
3860 } | |
3861 } | |
3862 | |
3863 TEST_F(URLRequestTestHTTP, GetZippedTest) { | |
3864 ASSERT_TRUE(test_server_.Start()); | |
3865 | |
3866 // Parameter that specifies the Content-Length field in the response: | |
3867 // C - Compressed length. | |
3868 // U - Uncompressed length. | |
3869 // L - Large length (larger than both C & U). | |
3870 // M - Medium length (between C & U). | |
3871 // S - Small length (smaller than both C & U). | |
3872 const char test_parameters[] = "CULMS"; | |
3873 const int num_tests = arraysize(test_parameters)- 1; // Skip NULL. | |
3874 // C & U should be OK. | |
3875 // L & M are larger than the data sent, and show an error. | |
3876 // S has too little data, but we seem to accept it. | |
3877 const bool test_expect_success[num_tests] = | |
3878 { true, true, false, false, true }; | |
3879 | |
3880 for (int i = 0; i < num_tests ; i++) { | |
3881 TestDelegate d; | |
3882 { | |
3883 std::string test_file = | |
3884 base::StringPrintf("compressedfiles/BullRunSpeech.txt?%c", | |
3885 test_parameters[i]); | |
3886 | |
3887 TestNetworkDelegate network_delegate; // Must outlive URLRequest. | |
3888 TestURLRequestContext context(true); | |
3889 context.set_network_delegate(&network_delegate); | |
3890 context.Init(); | |
3891 | |
3892 scoped_ptr<URLRequest> r(context.CreateRequest( | |
3893 test_server_.GetURL(test_file), DEFAULT_PRIORITY, &d, NULL)); | |
3894 r->Start(); | |
3895 EXPECT_TRUE(r->is_pending()); | |
3896 | |
3897 base::RunLoop().Run(); | |
3898 | |
3899 EXPECT_EQ(1, d.response_started_count()); | |
3900 EXPECT_FALSE(d.received_data_before_response()); | |
3901 VLOG(1) << " Received " << d.bytes_received() << " bytes" | |
3902 << " status = " << r->status().status() | |
3903 << " error = " << r->status().error(); | |
3904 if (test_expect_success[i]) { | |
3905 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()) | |
3906 << " Parameter = \"" << test_file << "\""; | |
3907 } else { | |
3908 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); | |
3909 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, r->status().error()) | |
3910 << " Parameter = \"" << test_file << "\""; | |
3911 } | |
3912 } | |
3913 } | |
3914 } | |
3915 | |
3916 TEST_F(URLRequestTestHTTP, RedirectLoadTiming) { | |
3917 ASSERT_TRUE(test_server_.Start()); | |
3918 | |
3919 GURL destination_url = test_server_.GetURL(std::string()); | |
3920 GURL original_url = | |
3921 test_server_.GetURL("server-redirect?" + destination_url.spec()); | |
3922 TestDelegate d; | |
3923 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
3924 original_url, DEFAULT_PRIORITY, &d, NULL)); | |
3925 req->Start(); | |
3926 base::RunLoop().Run(); | |
3927 | |
3928 EXPECT_EQ(1, d.response_started_count()); | |
3929 EXPECT_EQ(1, d.received_redirect_count()); | |
3930 EXPECT_EQ(destination_url, req->url()); | |
3931 EXPECT_EQ(original_url, req->original_url()); | |
3932 ASSERT_EQ(2U, req->url_chain().size()); | |
3933 EXPECT_EQ(original_url, req->url_chain()[0]); | |
3934 EXPECT_EQ(destination_url, req->url_chain()[1]); | |
3935 | |
3936 LoadTimingInfo load_timing_info_before_redirect; | |
3937 EXPECT_TRUE(default_network_delegate_.GetLoadTimingInfoBeforeRedirect( | |
3938 &load_timing_info_before_redirect)); | |
3939 TestLoadTimingNotReused(load_timing_info_before_redirect, | |
3940 CONNECT_TIMING_HAS_DNS_TIMES); | |
3941 | |
3942 LoadTimingInfo load_timing_info; | |
3943 req->GetLoadTimingInfo(&load_timing_info); | |
3944 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); | |
3945 | |
3946 // Check that a new socket was used on redirect, since the server does not | |
3947 // supposed keep-alive sockets, and that the times before the redirect are | |
3948 // before the ones recorded for the second request. | |
3949 EXPECT_NE(load_timing_info_before_redirect.socket_log_id, | |
3950 load_timing_info.socket_log_id); | |
3951 EXPECT_LE(load_timing_info_before_redirect.receive_headers_end, | |
3952 load_timing_info.connect_timing.connect_start); | |
3953 } | |
3954 | |
3955 TEST_F(URLRequestTestHTTP, MultipleRedirectTest) { | |
3956 ASSERT_TRUE(test_server_.Start()); | |
3957 | |
3958 GURL destination_url = test_server_.GetURL(std::string()); | |
3959 GURL middle_redirect_url = | |
3960 test_server_.GetURL("server-redirect?" + destination_url.spec()); | |
3961 GURL original_url = test_server_.GetURL( | |
3962 "server-redirect?" + middle_redirect_url.spec()); | |
3963 TestDelegate d; | |
3964 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
3965 original_url, DEFAULT_PRIORITY, &d, NULL)); | |
3966 req->Start(); | |
3967 base::RunLoop().Run(); | |
3968 | |
3969 EXPECT_EQ(1, d.response_started_count()); | |
3970 EXPECT_EQ(2, d.received_redirect_count()); | |
3971 EXPECT_EQ(destination_url, req->url()); | |
3972 EXPECT_EQ(original_url, req->original_url()); | |
3973 ASSERT_EQ(3U, req->url_chain().size()); | |
3974 EXPECT_EQ(original_url, req->url_chain()[0]); | |
3975 EXPECT_EQ(middle_redirect_url, req->url_chain()[1]); | |
3976 EXPECT_EQ(destination_url, req->url_chain()[2]); | |
3977 } | |
3978 | |
3979 // First and second pieces of information logged by delegates to URLRequests. | |
3980 const char kFirstDelegateInfo[] = "Wonderful delegate"; | |
3981 const char kSecondDelegateInfo[] = "Exciting delegate"; | |
3982 | |
3983 // Logs delegate information to a URLRequest. The first string is logged | |
3984 // synchronously on Start(), using DELEGATE_INFO_DEBUG_ONLY. The second is | |
3985 // logged asynchronously, using DELEGATE_INFO_DISPLAY_TO_USER. Then | |
3986 // another asynchronous call is used to clear the delegate information | |
3987 // before calling a callback. The object then deletes itself. | |
3988 class AsyncDelegateLogger : public base::RefCounted<AsyncDelegateLogger> { | |
3989 public: | |
3990 typedef base::Callback<void()> Callback; | |
3991 | |
3992 // Each time delegate information is added to the URLRequest, the resulting | |
3993 // load state is checked. The expected load state after each request is | |
3994 // passed in as an argument. | |
3995 static void Run(URLRequest* url_request, | |
3996 LoadState expected_first_load_state, | |
3997 LoadState expected_second_load_state, | |
3998 LoadState expected_third_load_state, | |
3999 const Callback& callback) { | |
4000 AsyncDelegateLogger* logger = new AsyncDelegateLogger( | |
4001 url_request, | |
4002 expected_first_load_state, | |
4003 expected_second_load_state, | |
4004 expected_third_load_state, | |
4005 callback); | |
4006 logger->Start(); | |
4007 } | |
4008 | |
4009 // Checks that the log entries, starting with log_position, contain the | |
4010 // DELEGATE_INFO NetLog events that an AsyncDelegateLogger should have | |
4011 // recorded. Returns the index of entry after the expected number of | |
4012 // events this logged, or entries.size() if there aren't enough entries. | |
4013 static size_t CheckDelegateInfo( | |
4014 const CapturingNetLog::CapturedEntryList& entries, size_t log_position) { | |
4015 // There should be 4 DELEGATE_INFO events: Two begins and two ends. | |
4016 if (log_position + 3 >= entries.size()) { | |
4017 ADD_FAILURE() << "Not enough log entries"; | |
4018 return entries.size(); | |
4019 } | |
4020 std::string delegate_info; | |
4021 EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type); | |
4022 EXPECT_EQ(NetLog::PHASE_BEGIN, entries[log_position].phase); | |
4023 EXPECT_TRUE(entries[log_position].GetStringValue("delegate_info", | |
4024 &delegate_info)); | |
4025 EXPECT_EQ(kFirstDelegateInfo, delegate_info); | |
4026 | |
4027 ++log_position; | |
4028 EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type); | |
4029 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); | |
4030 | |
4031 ++log_position; | |
4032 EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type); | |
4033 EXPECT_EQ(NetLog::PHASE_BEGIN, entries[log_position].phase); | |
4034 EXPECT_TRUE(entries[log_position].GetStringValue("delegate_info", | |
4035 &delegate_info)); | |
4036 EXPECT_EQ(kSecondDelegateInfo, delegate_info); | |
4037 | |
4038 ++log_position; | |
4039 EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type); | |
4040 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); | |
4041 | |
4042 return log_position + 1; | |
4043 } | |
4044 | |
4045 // Find delegate request begin and end messages for OnBeforeNetworkStart. | |
4046 // Returns the position of the end message. | |
4047 static size_t ExpectBeforeNetworkEvents( | |
4048 const CapturingNetLog::CapturedEntryList& entries, | |
4049 size_t log_position) { | |
4050 log_position = | |
4051 ExpectLogContainsSomewhereAfter(entries, | |
4052 log_position, | |
4053 NetLog::TYPE_URL_REQUEST_DELEGATE, | |
4054 NetLog::PHASE_BEGIN); | |
4055 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, | |
4056 entries[log_position + 1].type); | |
4057 EXPECT_EQ(NetLog::PHASE_END, entries[log_position + 1].phase); | |
4058 return log_position + 1; | |
4059 } | |
4060 | |
4061 private: | |
4062 friend class base::RefCounted<AsyncDelegateLogger>; | |
4063 | |
4064 AsyncDelegateLogger(URLRequest* url_request, | |
4065 LoadState expected_first_load_state, | |
4066 LoadState expected_second_load_state, | |
4067 LoadState expected_third_load_state, | |
4068 const Callback& callback) | |
4069 : url_request_(url_request), | |
4070 expected_first_load_state_(expected_first_load_state), | |
4071 expected_second_load_state_(expected_second_load_state), | |
4072 expected_third_load_state_(expected_third_load_state), | |
4073 callback_(callback) { | |
4074 } | |
4075 | |
4076 ~AsyncDelegateLogger() {} | |
4077 | |
4078 void Start() { | |
4079 url_request_->LogBlockedBy(kFirstDelegateInfo); | |
4080 LoadStateWithParam load_state = url_request_->GetLoadState(); | |
4081 EXPECT_EQ(expected_first_load_state_, load_state.state); | |
4082 EXPECT_NE(ASCIIToUTF16(kFirstDelegateInfo), load_state.param); | |
4083 base::MessageLoop::current()->PostTask( | |
4084 FROM_HERE, | |
4085 base::Bind(&AsyncDelegateLogger::LogSecondDelegate, this)); | |
4086 } | |
4087 | |
4088 void LogSecondDelegate() { | |
4089 url_request_->LogAndReportBlockedBy(kSecondDelegateInfo); | |
4090 LoadStateWithParam load_state = url_request_->GetLoadState(); | |
4091 EXPECT_EQ(expected_second_load_state_, load_state.state); | |
4092 if (expected_second_load_state_ == LOAD_STATE_WAITING_FOR_DELEGATE) { | |
4093 EXPECT_EQ(ASCIIToUTF16(kSecondDelegateInfo), load_state.param); | |
4094 } else { | |
4095 EXPECT_NE(ASCIIToUTF16(kSecondDelegateInfo), load_state.param); | |
4096 } | |
4097 base::MessageLoop::current()->PostTask( | |
4098 FROM_HERE, | |
4099 base::Bind(&AsyncDelegateLogger::LogComplete, this)); | |
4100 } | |
4101 | |
4102 void LogComplete() { | |
4103 url_request_->LogUnblocked(); | |
4104 LoadStateWithParam load_state = url_request_->GetLoadState(); | |
4105 EXPECT_EQ(expected_third_load_state_, load_state.state); | |
4106 if (expected_second_load_state_ == LOAD_STATE_WAITING_FOR_DELEGATE) | |
4107 EXPECT_EQ(base::string16(), load_state.param); | |
4108 callback_.Run(); | |
4109 } | |
4110 | |
4111 URLRequest* url_request_; | |
4112 const int expected_first_load_state_; | |
4113 const int expected_second_load_state_; | |
4114 const int expected_third_load_state_; | |
4115 const Callback callback_; | |
4116 | |
4117 DISALLOW_COPY_AND_ASSIGN(AsyncDelegateLogger); | |
4118 }; | |
4119 | |
4120 // NetworkDelegate that logs delegate information before a request is started, | |
4121 // before headers are sent, when headers are read, and when auth information | |
4122 // is requested. Uses AsyncDelegateLogger. | |
4123 class AsyncLoggingNetworkDelegate : public TestNetworkDelegate { | |
4124 public: | |
4125 AsyncLoggingNetworkDelegate() {} | |
4126 ~AsyncLoggingNetworkDelegate() override {} | |
4127 | |
4128 // NetworkDelegate implementation. | |
4129 int OnBeforeURLRequest(URLRequest* request, | |
4130 const CompletionCallback& callback, | |
4131 GURL* new_url) override { | |
4132 TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url); | |
4133 return RunCallbackAsynchronously(request, callback); | |
4134 } | |
4135 | |
4136 int OnBeforeSendHeaders(URLRequest* request, | |
4137 const CompletionCallback& callback, | |
4138 HttpRequestHeaders* headers) override { | |
4139 TestNetworkDelegate::OnBeforeSendHeaders(request, callback, headers); | |
4140 return RunCallbackAsynchronously(request, callback); | |
4141 } | |
4142 | |
4143 int OnHeadersReceived( | |
4144 URLRequest* request, | |
4145 const CompletionCallback& callback, | |
4146 const HttpResponseHeaders* original_response_headers, | |
4147 scoped_refptr<HttpResponseHeaders>* override_response_headers, | |
4148 GURL* allowed_unsafe_redirect_url) override { | |
4149 TestNetworkDelegate::OnHeadersReceived(request, | |
4150 callback, | |
4151 original_response_headers, | |
4152 override_response_headers, | |
4153 allowed_unsafe_redirect_url); | |
4154 return RunCallbackAsynchronously(request, callback); | |
4155 } | |
4156 | |
4157 NetworkDelegate::AuthRequiredResponse OnAuthRequired( | |
4158 URLRequest* request, | |
4159 const AuthChallengeInfo& auth_info, | |
4160 const AuthCallback& callback, | |
4161 AuthCredentials* credentials) override { | |
4162 AsyncDelegateLogger::Run( | |
4163 request, | |
4164 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4165 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4166 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4167 base::Bind(&AsyncLoggingNetworkDelegate::SetAuthAndResume, | |
4168 callback, credentials)); | |
4169 return AUTH_REQUIRED_RESPONSE_IO_PENDING; | |
4170 } | |
4171 | |
4172 private: | |
4173 static int RunCallbackAsynchronously( | |
4174 URLRequest* request, | |
4175 const CompletionCallback& callback) { | |
4176 AsyncDelegateLogger::Run( | |
4177 request, | |
4178 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4179 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4180 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4181 base::Bind(callback, OK)); | |
4182 return ERR_IO_PENDING; | |
4183 } | |
4184 | |
4185 static void SetAuthAndResume(const AuthCallback& callback, | |
4186 AuthCredentials* credentials) { | |
4187 *credentials = AuthCredentials(kUser, kSecret); | |
4188 callback.Run(NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH); | |
4189 } | |
4190 | |
4191 DISALLOW_COPY_AND_ASSIGN(AsyncLoggingNetworkDelegate); | |
4192 }; | |
4193 | |
4194 // URLRequest::Delegate that logs delegate information when the headers | |
4195 // are received, when each read completes, and during redirects. Uses | |
4196 // AsyncDelegateLogger. Can optionally cancel a request in any phase. | |
4197 // | |
4198 // Inherits from TestDelegate to reuse the TestDelegate code to handle | |
4199 // advancing to the next step in most cases, as well as cancellation. | |
4200 class AsyncLoggingUrlRequestDelegate : public TestDelegate { | |
4201 public: | |
4202 enum CancelStage { | |
4203 NO_CANCEL = 0, | |
4204 CANCEL_ON_RECEIVED_REDIRECT, | |
4205 CANCEL_ON_RESPONSE_STARTED, | |
4206 CANCEL_ON_READ_COMPLETED | |
4207 }; | |
4208 | |
4209 explicit AsyncLoggingUrlRequestDelegate(CancelStage cancel_stage) | |
4210 : cancel_stage_(cancel_stage) { | |
4211 if (cancel_stage == CANCEL_ON_RECEIVED_REDIRECT) | |
4212 set_cancel_in_received_redirect(true); | |
4213 else if (cancel_stage == CANCEL_ON_RESPONSE_STARTED) | |
4214 set_cancel_in_response_started(true); | |
4215 else if (cancel_stage == CANCEL_ON_READ_COMPLETED) | |
4216 set_cancel_in_received_data(true); | |
4217 } | |
4218 ~AsyncLoggingUrlRequestDelegate() override {} | |
4219 | |
4220 // URLRequest::Delegate implementation: | |
4221 void OnReceivedRedirect(URLRequest* request, | |
4222 const RedirectInfo& redirect_info, | |
4223 bool* defer_redirect) override { | |
4224 *defer_redirect = true; | |
4225 AsyncDelegateLogger::Run( | |
4226 request, | |
4227 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4228 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4229 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4230 base::Bind( | |
4231 &AsyncLoggingUrlRequestDelegate::OnReceivedRedirectLoggingComplete, | |
4232 base::Unretained(this), request, redirect_info)); | |
4233 } | |
4234 | |
4235 void OnResponseStarted(URLRequest* request) override { | |
4236 AsyncDelegateLogger::Run( | |
4237 request, | |
4238 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4239 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4240 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4241 base::Bind( | |
4242 &AsyncLoggingUrlRequestDelegate::OnResponseStartedLoggingComplete, | |
4243 base::Unretained(this), request)); | |
4244 } | |
4245 | |
4246 void OnReadCompleted(URLRequest* request, int bytes_read) override { | |
4247 AsyncDelegateLogger::Run( | |
4248 request, | |
4249 LOAD_STATE_IDLE, | |
4250 LOAD_STATE_IDLE, | |
4251 LOAD_STATE_IDLE, | |
4252 base::Bind( | |
4253 &AsyncLoggingUrlRequestDelegate::AfterReadCompletedLoggingComplete, | |
4254 base::Unretained(this), request, bytes_read)); | |
4255 } | |
4256 | |
4257 private: | |
4258 void OnReceivedRedirectLoggingComplete(URLRequest* request, | |
4259 const RedirectInfo& redirect_info) { | |
4260 bool defer_redirect = false; | |
4261 TestDelegate::OnReceivedRedirect(request, redirect_info, &defer_redirect); | |
4262 // FollowDeferredRedirect should not be called after cancellation. | |
4263 if (cancel_stage_ == CANCEL_ON_RECEIVED_REDIRECT) | |
4264 return; | |
4265 if (!defer_redirect) | |
4266 request->FollowDeferredRedirect(); | |
4267 } | |
4268 | |
4269 void OnResponseStartedLoggingComplete(URLRequest* request) { | |
4270 // The parent class continues the request. | |
4271 TestDelegate::OnResponseStarted(request); | |
4272 } | |
4273 | |
4274 void AfterReadCompletedLoggingComplete(URLRequest* request, int bytes_read) { | |
4275 // The parent class continues the request. | |
4276 TestDelegate::OnReadCompleted(request, bytes_read); | |
4277 } | |
4278 | |
4279 const CancelStage cancel_stage_; | |
4280 | |
4281 DISALLOW_COPY_AND_ASSIGN(AsyncLoggingUrlRequestDelegate); | |
4282 }; | |
4283 | |
4284 // Tests handling of delegate info before a request starts. | |
4285 TEST_F(URLRequestTestHTTP, DelegateInfoBeforeStart) { | |
4286 ASSERT_TRUE(test_server_.Start()); | |
4287 | |
4288 TestDelegate request_delegate; | |
4289 TestURLRequestContext context(true); | |
4290 context.set_network_delegate(NULL); | |
4291 context.set_net_log(&net_log_); | |
4292 context.Init(); | |
4293 | |
4294 { | |
4295 scoped_ptr<URLRequest> r(context.CreateRequest( | |
4296 test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &request_delegate, | |
4297 NULL)); | |
4298 LoadStateWithParam load_state = r->GetLoadState(); | |
4299 EXPECT_EQ(LOAD_STATE_IDLE, load_state.state); | |
4300 EXPECT_EQ(base::string16(), load_state.param); | |
4301 | |
4302 AsyncDelegateLogger::Run( | |
4303 r.get(), | |
4304 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4305 LOAD_STATE_WAITING_FOR_DELEGATE, | |
4306 LOAD_STATE_IDLE, | |
4307 base::Bind(&URLRequest::Start, base::Unretained(r.get()))); | |
4308 | |
4309 base::RunLoop().Run(); | |
4310 | |
4311 EXPECT_EQ(200, r->GetResponseCode()); | |
4312 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
4313 } | |
4314 | |
4315 CapturingNetLog::CapturedEntryList entries; | |
4316 net_log_.GetEntries(&entries); | |
4317 size_t log_position = ExpectLogContainsSomewhereAfter( | |
4318 entries, | |
4319 0, | |
4320 NetLog::TYPE_DELEGATE_INFO, | |
4321 NetLog::PHASE_BEGIN); | |
4322 | |
4323 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, log_position); | |
4324 | |
4325 // Nothing else should add any delegate info to the request. | |
4326 EXPECT_FALSE(LogContainsEntryWithTypeAfter( | |
4327 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); | |
4328 } | |
4329 | |
4330 // Tests handling of delegate info from a network delegate. | |
4331 TEST_F(URLRequestTestHTTP, NetworkDelegateInfo) { | |
4332 ASSERT_TRUE(test_server_.Start()); | |
4333 | |
4334 TestDelegate request_delegate; | |
4335 AsyncLoggingNetworkDelegate network_delegate; | |
4336 TestURLRequestContext context(true); | |
4337 context.set_network_delegate(&network_delegate); | |
4338 context.set_net_log(&net_log_); | |
4339 context.Init(); | |
4340 | |
4341 { | |
4342 scoped_ptr<URLRequest> r(context.CreateRequest( | |
4343 test_server_.GetURL("simple.html"), DEFAULT_PRIORITY, &request_delegate, | |
4344 NULL)); | |
4345 LoadStateWithParam load_state = r->GetLoadState(); | |
4346 EXPECT_EQ(LOAD_STATE_IDLE, load_state.state); | |
4347 EXPECT_EQ(base::string16(), load_state.param); | |
4348 | |
4349 r->Start(); | |
4350 base::RunLoop().Run(); | |
4351 | |
4352 EXPECT_EQ(200, r->GetResponseCode()); | |
4353 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
4354 EXPECT_EQ(1, network_delegate.created_requests()); | |
4355 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
4356 } | |
4357 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
4358 | |
4359 size_t log_position = 0; | |
4360 CapturingNetLog::CapturedEntryList entries; | |
4361 net_log_.GetEntries(&entries); | |
4362 for (size_t i = 0; i < 3; ++i) { | |
4363 log_position = ExpectLogContainsSomewhereAfter( | |
4364 entries, | |
4365 log_position + 1, | |
4366 NetLog::TYPE_URL_REQUEST_DELEGATE, | |
4367 NetLog::PHASE_BEGIN); | |
4368 | |
4369 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, | |
4370 log_position + 1); | |
4371 | |
4372 ASSERT_LT(log_position, entries.size()); | |
4373 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); | |
4374 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); | |
4375 | |
4376 if (i == 1) { | |
4377 log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents( | |
4378 entries, log_position + 1); | |
4379 } | |
4380 } | |
4381 | |
4382 EXPECT_FALSE(LogContainsEntryWithTypeAfter( | |
4383 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); | |
4384 } | |
4385 | |
4386 // Tests handling of delegate info from a network delegate in the case of an | |
4387 // HTTP redirect. | |
4388 TEST_F(URLRequestTestHTTP, NetworkDelegateInfoRedirect) { | |
4389 ASSERT_TRUE(test_server_.Start()); | |
4390 | |
4391 TestDelegate request_delegate; | |
4392 AsyncLoggingNetworkDelegate network_delegate; | |
4393 TestURLRequestContext context(true); | |
4394 context.set_network_delegate(&network_delegate); | |
4395 context.set_net_log(&net_log_); | |
4396 context.Init(); | |
4397 | |
4398 { | |
4399 scoped_ptr<URLRequest> r(context.CreateRequest( | |
4400 test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY, | |
4401 &request_delegate, NULL)); | |
4402 LoadStateWithParam load_state = r->GetLoadState(); | |
4403 EXPECT_EQ(LOAD_STATE_IDLE, load_state.state); | |
4404 EXPECT_EQ(base::string16(), load_state.param); | |
4405 | |
4406 r->Start(); | |
4407 base::RunLoop().Run(); | |
4408 | |
4409 EXPECT_EQ(200, r->GetResponseCode()); | |
4410 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
4411 EXPECT_EQ(2, network_delegate.created_requests()); | |
4412 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
4413 } | |
4414 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
4415 | |
4416 size_t log_position = 0; | |
4417 CapturingNetLog::CapturedEntryList entries; | |
4418 net_log_.GetEntries(&entries); | |
4419 // The NetworkDelegate logged information in OnBeforeURLRequest, | |
4420 // OnBeforeSendHeaders, and OnHeadersReceived. | |
4421 for (size_t i = 0; i < 3; ++i) { | |
4422 log_position = ExpectLogContainsSomewhereAfter( | |
4423 entries, | |
4424 log_position + 1, | |
4425 NetLog::TYPE_URL_REQUEST_DELEGATE, | |
4426 NetLog::PHASE_BEGIN); | |
4427 | |
4428 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, | |
4429 log_position + 1); | |
4430 | |
4431 ASSERT_LT(log_position, entries.size()); | |
4432 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); | |
4433 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); | |
4434 | |
4435 if (i == 1) { | |
4436 log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents( | |
4437 entries, log_position + 1); | |
4438 } | |
4439 } | |
4440 | |
4441 // The URLRequest::Delegate then gets informed about the redirect. | |
4442 log_position = ExpectLogContainsSomewhereAfter( | |
4443 entries, | |
4444 log_position + 1, | |
4445 NetLog::TYPE_URL_REQUEST_DELEGATE, | |
4446 NetLog::PHASE_BEGIN); | |
4447 | |
4448 // The NetworkDelegate logged information in the same three events as before. | |
4449 for (size_t i = 0; i < 3; ++i) { | |
4450 log_position = ExpectLogContainsSomewhereAfter( | |
4451 entries, | |
4452 log_position + 1, | |
4453 NetLog::TYPE_URL_REQUEST_DELEGATE, | |
4454 NetLog::PHASE_BEGIN); | |
4455 | |
4456 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, | |
4457 log_position + 1); | |
4458 | |
4459 ASSERT_LT(log_position, entries.size()); | |
4460 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); | |
4461 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); | |
4462 } | |
4463 | |
4464 EXPECT_FALSE(LogContainsEntryWithTypeAfter( | |
4465 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); | |
4466 } | |
4467 | |
4468 // Tests handling of delegate info from a network delegate in the case of HTTP | |
4469 // AUTH. | |
4470 TEST_F(URLRequestTestHTTP, NetworkDelegateInfoAuth) { | |
4471 ASSERT_TRUE(test_server_.Start()); | |
4472 | |
4473 TestDelegate request_delegate; | |
4474 AsyncLoggingNetworkDelegate network_delegate; | |
4475 TestURLRequestContext context(true); | |
4476 context.set_network_delegate(&network_delegate); | |
4477 context.set_net_log(&net_log_); | |
4478 context.Init(); | |
4479 | |
4480 { | |
4481 scoped_ptr<URLRequest> r(context.CreateRequest( | |
4482 test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &request_delegate, | |
4483 NULL)); | |
4484 LoadStateWithParam load_state = r->GetLoadState(); | |
4485 EXPECT_EQ(LOAD_STATE_IDLE, load_state.state); | |
4486 EXPECT_EQ(base::string16(), load_state.param); | |
4487 | |
4488 r->Start(); | |
4489 base::RunLoop().Run(); | |
4490 | |
4491 EXPECT_EQ(200, r->GetResponseCode()); | |
4492 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
4493 EXPECT_EQ(1, network_delegate.created_requests()); | |
4494 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
4495 } | |
4496 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
4497 | |
4498 size_t log_position = 0; | |
4499 CapturingNetLog::CapturedEntryList entries; | |
4500 net_log_.GetEntries(&entries); | |
4501 // The NetworkDelegate should have logged information in OnBeforeURLRequest, | |
4502 // OnBeforeSendHeaders, OnHeadersReceived, OnAuthRequired, and then again in | |
4503 // OnBeforeURLRequest and OnBeforeSendHeaders. | |
4504 for (size_t i = 0; i < 6; ++i) { | |
4505 log_position = ExpectLogContainsSomewhereAfter( | |
4506 entries, | |
4507 log_position + 1, | |
4508 NetLog::TYPE_URL_REQUEST_DELEGATE, | |
4509 NetLog::PHASE_BEGIN); | |
4510 | |
4511 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, | |
4512 log_position + 1); | |
4513 | |
4514 ASSERT_LT(log_position, entries.size()); | |
4515 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); | |
4516 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); | |
4517 | |
4518 if (i == 1) { | |
4519 log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents( | |
4520 entries, log_position + 1); | |
4521 } | |
4522 } | |
4523 | |
4524 EXPECT_FALSE(LogContainsEntryWithTypeAfter( | |
4525 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); | |
4526 } | |
4527 | |
4528 // Tests handling of delegate info from a URLRequest::Delegate. | |
4529 TEST_F(URLRequestTestHTTP, URLRequestDelegateInfo) { | |
4530 ASSERT_TRUE(test_server_.Start()); | |
4531 | |
4532 AsyncLoggingUrlRequestDelegate request_delegate( | |
4533 AsyncLoggingUrlRequestDelegate::NO_CANCEL); | |
4534 TestURLRequestContext context(true); | |
4535 context.set_network_delegate(NULL); | |
4536 context.set_net_log(&net_log_); | |
4537 context.Init(); | |
4538 | |
4539 { | |
4540 // A chunked response with delays between chunks is used to make sure that | |
4541 // attempts by the URLRequest delegate to log information while reading the | |
4542 // body are ignored. Since they are ignored, this test is robust against | |
4543 // the possibility of multiple reads being combined in the unlikely event | |
4544 // that it occurs. | |
4545 scoped_ptr<URLRequest> r(context.CreateRequest( | |
4546 test_server_.GetURL("chunked?waitBetweenChunks=20"), DEFAULT_PRIORITY, | |
4547 &request_delegate, NULL)); | |
4548 LoadStateWithParam load_state = r->GetLoadState(); | |
4549 r->Start(); | |
4550 base::RunLoop().Run(); | |
4551 | |
4552 EXPECT_EQ(200, r->GetResponseCode()); | |
4553 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
4554 } | |
4555 | |
4556 CapturingNetLog::CapturedEntryList entries; | |
4557 net_log_.GetEntries(&entries); | |
4558 | |
4559 size_t log_position = 0; | |
4560 | |
4561 log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents( | |
4562 entries, log_position); | |
4563 | |
4564 // The delegate info should only have been logged on header complete. Other | |
4565 // times it should silently be ignored. | |
4566 log_position = | |
4567 ExpectLogContainsSomewhereAfter(entries, | |
4568 log_position + 1, | |
4569 NetLog::TYPE_URL_REQUEST_DELEGATE, | |
4570 NetLog::PHASE_BEGIN); | |
4571 | |
4572 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, | |
4573 log_position + 1); | |
4574 | |
4575 ASSERT_LT(log_position, entries.size()); | |
4576 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); | |
4577 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); | |
4578 | |
4579 EXPECT_FALSE(LogContainsEntryWithTypeAfter( | |
4580 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); | |
4581 EXPECT_FALSE(LogContainsEntryWithTypeAfter( | |
4582 entries, log_position + 1, NetLog::TYPE_URL_REQUEST_DELEGATE)); | |
4583 } | |
4584 | |
4585 // Tests handling of delegate info from a URLRequest::Delegate in the case of | |
4586 // an HTTP redirect. | |
4587 TEST_F(URLRequestTestHTTP, URLRequestDelegateInfoOnRedirect) { | |
4588 ASSERT_TRUE(test_server_.Start()); | |
4589 | |
4590 AsyncLoggingUrlRequestDelegate request_delegate( | |
4591 AsyncLoggingUrlRequestDelegate::NO_CANCEL); | |
4592 TestURLRequestContext context(true); | |
4593 context.set_network_delegate(NULL); | |
4594 context.set_net_log(&net_log_); | |
4595 context.Init(); | |
4596 | |
4597 { | |
4598 scoped_ptr<URLRequest> r(context.CreateRequest( | |
4599 test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY, | |
4600 &request_delegate, NULL)); | |
4601 LoadStateWithParam load_state = r->GetLoadState(); | |
4602 r->Start(); | |
4603 base::RunLoop().Run(); | |
4604 | |
4605 EXPECT_EQ(200, r->GetResponseCode()); | |
4606 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
4607 } | |
4608 | |
4609 CapturingNetLog::CapturedEntryList entries; | |
4610 net_log_.GetEntries(&entries); | |
4611 | |
4612 // Delegate info should only have been logged in OnReceivedRedirect and | |
4613 // OnResponseStarted. | |
4614 size_t log_position = 0; | |
4615 for (int i = 0; i < 2; ++i) { | |
4616 if (i == 0) { | |
4617 log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents( | |
4618 entries, log_position) + 1; | |
4619 } | |
4620 | |
4621 log_position = ExpectLogContainsSomewhereAfter( | |
4622 entries, | |
4623 log_position, | |
4624 NetLog::TYPE_URL_REQUEST_DELEGATE, | |
4625 NetLog::PHASE_BEGIN); | |
4626 | |
4627 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, | |
4628 log_position + 1); | |
4629 | |
4630 ASSERT_LT(log_position, entries.size()); | |
4631 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); | |
4632 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); | |
4633 } | |
4634 | |
4635 EXPECT_FALSE(LogContainsEntryWithTypeAfter( | |
4636 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); | |
4637 EXPECT_FALSE(LogContainsEntryWithTypeAfter( | |
4638 entries, log_position + 1, NetLog::TYPE_URL_REQUEST_DELEGATE)); | |
4639 } | |
4640 | |
4641 // Tests handling of delegate info from a URLRequest::Delegate in the case of | |
4642 // an HTTP redirect, with cancellation at various points. | |
4643 TEST_F(URLRequestTestHTTP, URLRequestDelegateOnRedirectCancelled) { | |
4644 ASSERT_TRUE(test_server_.Start()); | |
4645 | |
4646 const AsyncLoggingUrlRequestDelegate::CancelStage kCancelStages[] = { | |
4647 AsyncLoggingUrlRequestDelegate::CANCEL_ON_RECEIVED_REDIRECT, | |
4648 AsyncLoggingUrlRequestDelegate::CANCEL_ON_RESPONSE_STARTED, | |
4649 AsyncLoggingUrlRequestDelegate::CANCEL_ON_READ_COMPLETED, | |
4650 }; | |
4651 | |
4652 for (size_t test_case = 0; test_case < arraysize(kCancelStages); | |
4653 ++test_case) { | |
4654 AsyncLoggingUrlRequestDelegate request_delegate(kCancelStages[test_case]); | |
4655 TestURLRequestContext context(true); | |
4656 CapturingNetLog net_log; | |
4657 context.set_network_delegate(NULL); | |
4658 context.set_net_log(&net_log); | |
4659 context.Init(); | |
4660 | |
4661 { | |
4662 scoped_ptr<URLRequest> r(context.CreateRequest( | |
4663 test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY, | |
4664 &request_delegate, NULL)); | |
4665 LoadStateWithParam load_state = r->GetLoadState(); | |
4666 r->Start(); | |
4667 base::RunLoop().Run(); | |
4668 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); | |
4669 } | |
4670 | |
4671 CapturingNetLog::CapturedEntryList entries; | |
4672 net_log.GetEntries(&entries); | |
4673 | |
4674 // Delegate info is always logged in both OnReceivedRedirect and | |
4675 // OnResponseStarted. In the CANCEL_ON_RECEIVED_REDIRECT, the | |
4676 // OnResponseStarted delegate call is after cancellation, but logging is | |
4677 // still currently supported in that call. | |
4678 size_t log_position = 0; | |
4679 for (int i = 0; i < 2; ++i) { | |
4680 if (i == 0) { | |
4681 log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents( | |
4682 entries, log_position) + 1; | |
4683 } | |
4684 | |
4685 log_position = ExpectLogContainsSomewhereAfter( | |
4686 entries, | |
4687 log_position, | |
4688 NetLog::TYPE_URL_REQUEST_DELEGATE, | |
4689 NetLog::PHASE_BEGIN); | |
4690 | |
4691 log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, | |
4692 log_position + 1); | |
4693 | |
4694 ASSERT_LT(log_position, entries.size()); | |
4695 EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type); | |
4696 EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase); | |
4697 } | |
4698 | |
4699 EXPECT_FALSE(LogContainsEntryWithTypeAfter( | |
4700 entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO)); | |
4701 EXPECT_FALSE(LogContainsEntryWithTypeAfter( | |
4702 entries, log_position + 1, NetLog::TYPE_URL_REQUEST_DELEGATE)); | |
4703 } | |
4704 } | |
4705 | |
4706 namespace { | |
4707 | |
4708 const char kExtraHeader[] = "Allow-Snafu"; | |
4709 const char kExtraValue[] = "fubar"; | |
4710 | |
4711 class RedirectWithAdditionalHeadersDelegate : public TestDelegate { | |
4712 void OnReceivedRedirect(URLRequest* request, | |
4713 const RedirectInfo& redirect_info, | |
4714 bool* defer_redirect) override { | |
4715 TestDelegate::OnReceivedRedirect(request, redirect_info, defer_redirect); | |
4716 request->SetExtraRequestHeaderByName(kExtraHeader, kExtraValue, false); | |
4717 } | |
4718 }; | |
4719 | |
4720 } // namespace | |
4721 | |
4722 TEST_F(URLRequestTestHTTP, RedirectWithAdditionalHeadersTest) { | |
4723 ASSERT_TRUE(test_server_.Start()); | |
4724 | |
4725 GURL destination_url = test_server_.GetURL( | |
4726 "echoheader?" + std::string(kExtraHeader)); | |
4727 GURL original_url = test_server_.GetURL( | |
4728 "server-redirect?" + destination_url.spec()); | |
4729 RedirectWithAdditionalHeadersDelegate d; | |
4730 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
4731 original_url, DEFAULT_PRIORITY, &d, NULL)); | |
4732 req->Start(); | |
4733 base::RunLoop().Run(); | |
4734 | |
4735 std::string value; | |
4736 const HttpRequestHeaders& headers = req->extra_request_headers(); | |
4737 EXPECT_TRUE(headers.GetHeader(kExtraHeader, &value)); | |
4738 EXPECT_EQ(kExtraValue, value); | |
4739 EXPECT_FALSE(req->is_pending()); | |
4740 EXPECT_FALSE(req->is_redirecting()); | |
4741 EXPECT_EQ(kExtraValue, d.data_received()); | |
4742 } | |
4743 | |
4744 namespace { | |
4745 | |
4746 const char kExtraHeaderToRemove[] = "To-Be-Removed"; | |
4747 | |
4748 class RedirectWithHeaderRemovalDelegate : public TestDelegate { | |
4749 void OnReceivedRedirect(URLRequest* request, | |
4750 const RedirectInfo& redirect_info, | |
4751 bool* defer_redirect) override { | |
4752 TestDelegate::OnReceivedRedirect(request, redirect_info, defer_redirect); | |
4753 request->RemoveRequestHeaderByName(kExtraHeaderToRemove); | |
4754 } | |
4755 }; | |
4756 | |
4757 } // namespace | |
4758 | |
4759 TEST_F(URLRequestTestHTTP, RedirectWithHeaderRemovalTest) { | |
4760 ASSERT_TRUE(test_server_.Start()); | |
4761 | |
4762 GURL destination_url = test_server_.GetURL( | |
4763 "echoheader?" + std::string(kExtraHeaderToRemove)); | |
4764 GURL original_url = test_server_.GetURL( | |
4765 "server-redirect?" + destination_url.spec()); | |
4766 RedirectWithHeaderRemovalDelegate d; | |
4767 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
4768 original_url, DEFAULT_PRIORITY, &d, NULL)); | |
4769 req->SetExtraRequestHeaderByName(kExtraHeaderToRemove, "dummy", false); | |
4770 req->Start(); | |
4771 base::RunLoop().Run(); | |
4772 | |
4773 std::string value; | |
4774 const HttpRequestHeaders& headers = req->extra_request_headers(); | |
4775 EXPECT_FALSE(headers.GetHeader(kExtraHeaderToRemove, &value)); | |
4776 EXPECT_FALSE(req->is_pending()); | |
4777 EXPECT_FALSE(req->is_redirecting()); | |
4778 EXPECT_EQ("None", d.data_received()); | |
4779 } | |
4780 | |
4781 TEST_F(URLRequestTestHTTP, CancelTest) { | |
4782 TestDelegate d; | |
4783 { | |
4784 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
4785 GURL("http://www.google.com/"), DEFAULT_PRIORITY, &d, NULL)); | |
4786 | |
4787 r->Start(); | |
4788 EXPECT_TRUE(r->is_pending()); | |
4789 | |
4790 r->Cancel(); | |
4791 | |
4792 base::RunLoop().Run(); | |
4793 | |
4794 // We expect to receive OnResponseStarted even though the request has been | |
4795 // cancelled. | |
4796 EXPECT_EQ(1, d.response_started_count()); | |
4797 EXPECT_EQ(0, d.bytes_received()); | |
4798 EXPECT_FALSE(d.received_data_before_response()); | |
4799 } | |
4800 } | |
4801 | |
4802 TEST_F(URLRequestTestHTTP, CancelTest2) { | |
4803 ASSERT_TRUE(test_server_.Start()); | |
4804 | |
4805 TestDelegate d; | |
4806 { | |
4807 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
4808 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
4809 | |
4810 d.set_cancel_in_response_started(true); | |
4811 | |
4812 r->Start(); | |
4813 EXPECT_TRUE(r->is_pending()); | |
4814 | |
4815 base::RunLoop().Run(); | |
4816 | |
4817 EXPECT_EQ(1, d.response_started_count()); | |
4818 EXPECT_EQ(0, d.bytes_received()); | |
4819 EXPECT_FALSE(d.received_data_before_response()); | |
4820 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); | |
4821 } | |
4822 } | |
4823 | |
4824 TEST_F(URLRequestTestHTTP, CancelTest3) { | |
4825 ASSERT_TRUE(test_server_.Start()); | |
4826 | |
4827 TestDelegate d; | |
4828 { | |
4829 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
4830 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
4831 | |
4832 d.set_cancel_in_received_data(true); | |
4833 | |
4834 r->Start(); | |
4835 EXPECT_TRUE(r->is_pending()); | |
4836 | |
4837 base::RunLoop().Run(); | |
4838 | |
4839 EXPECT_EQ(1, d.response_started_count()); | |
4840 // There is no guarantee about how much data was received | |
4841 // before the cancel was issued. It could have been 0 bytes, | |
4842 // or it could have been all the bytes. | |
4843 // EXPECT_EQ(0, d.bytes_received()); | |
4844 EXPECT_FALSE(d.received_data_before_response()); | |
4845 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); | |
4846 } | |
4847 } | |
4848 | |
4849 TEST_F(URLRequestTestHTTP, CancelTest4) { | |
4850 ASSERT_TRUE(test_server_.Start()); | |
4851 | |
4852 TestDelegate d; | |
4853 { | |
4854 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
4855 test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
4856 | |
4857 r->Start(); | |
4858 EXPECT_TRUE(r->is_pending()); | |
4859 | |
4860 // The request will be implicitly canceled when it is destroyed. The | |
4861 // test delegate must not post a quit message when this happens because | |
4862 // this test doesn't actually have a message loop. The quit message would | |
4863 // get put on this thread's message queue and the next test would exit | |
4864 // early, causing problems. | |
4865 d.set_quit_on_complete(false); | |
4866 } | |
4867 // expect things to just cleanup properly. | |
4868 | |
4869 // we won't actually get a received reponse here because we've never run the | |
4870 // message loop | |
4871 EXPECT_FALSE(d.received_data_before_response()); | |
4872 EXPECT_EQ(0, d.bytes_received()); | |
4873 } | |
4874 | |
4875 TEST_F(URLRequestTestHTTP, CancelTest5) { | |
4876 ASSERT_TRUE(test_server_.Start()); | |
4877 | |
4878 // populate cache | |
4879 { | |
4880 TestDelegate d; | |
4881 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
4882 test_server_.GetURL("cachetime"), DEFAULT_PRIORITY, &d, NULL)); | |
4883 r->Start(); | |
4884 base::RunLoop().Run(); | |
4885 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
4886 } | |
4887 | |
4888 // cancel read from cache (see bug 990242) | |
4889 { | |
4890 TestDelegate d; | |
4891 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
4892 test_server_.GetURL("cachetime"), DEFAULT_PRIORITY, &d, NULL)); | |
4893 r->Start(); | |
4894 r->Cancel(); | |
4895 base::RunLoop().Run(); | |
4896 | |
4897 EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status()); | |
4898 EXPECT_EQ(1, d.response_started_count()); | |
4899 EXPECT_EQ(0, d.bytes_received()); | |
4900 EXPECT_FALSE(d.received_data_before_response()); | |
4901 } | |
4902 } | |
4903 | |
4904 TEST_F(URLRequestTestHTTP, PostTest) { | |
4905 ASSERT_TRUE(test_server_.Start()); | |
4906 HTTPUploadDataOperationTest("POST"); | |
4907 } | |
4908 | |
4909 TEST_F(URLRequestTestHTTP, PutTest) { | |
4910 ASSERT_TRUE(test_server_.Start()); | |
4911 HTTPUploadDataOperationTest("PUT"); | |
4912 } | |
4913 | |
4914 TEST_F(URLRequestTestHTTP, PostEmptyTest) { | |
4915 ASSERT_TRUE(test_server_.Start()); | |
4916 | |
4917 TestDelegate d; | |
4918 { | |
4919 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
4920 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); | |
4921 r->set_method("POST"); | |
4922 | |
4923 r->Start(); | |
4924 EXPECT_TRUE(r->is_pending()); | |
4925 | |
4926 base::RunLoop().Run(); | |
4927 | |
4928 ASSERT_EQ(1, d.response_started_count()) | |
4929 << "request failed: " << r->status().status() | |
4930 << ", error: " << r->status().error(); | |
4931 | |
4932 EXPECT_FALSE(d.received_data_before_response()); | |
4933 EXPECT_TRUE(d.data_received().empty()); | |
4934 } | |
4935 } | |
4936 | |
4937 TEST_F(URLRequestTestHTTP, PostFileTest) { | |
4938 ASSERT_TRUE(test_server_.Start()); | |
4939 | |
4940 TestDelegate d; | |
4941 { | |
4942 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
4943 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); | |
4944 r->set_method("POST"); | |
4945 | |
4946 base::FilePath dir; | |
4947 PathService::Get(base::DIR_EXE, &dir); | |
4948 base::SetCurrentDirectory(dir); | |
4949 | |
4950 ScopedVector<UploadElementReader> element_readers; | |
4951 | |
4952 base::FilePath path; | |
4953 PathService::Get(base::DIR_SOURCE_ROOT, &path); | |
4954 path = path.Append(FILE_PATH_LITERAL("net")); | |
4955 path = path.Append(FILE_PATH_LITERAL("data")); | |
4956 path = path.Append(FILE_PATH_LITERAL("url_request_unittest")); | |
4957 path = path.Append(FILE_PATH_LITERAL("with-headers.html")); | |
4958 element_readers.push_back( | |
4959 new UploadFileElementReader(base::MessageLoopProxy::current().get(), | |
4960 path, | |
4961 0, | |
4962 kuint64max, | |
4963 base::Time())); | |
4964 r->set_upload(make_scoped_ptr<UploadDataStream>( | |
4965 new ElementsUploadDataStream(element_readers.Pass(), 0))); | |
4966 | |
4967 r->Start(); | |
4968 EXPECT_TRUE(r->is_pending()); | |
4969 | |
4970 base::RunLoop().Run(); | |
4971 | |
4972 int64 size64 = 0; | |
4973 ASSERT_EQ(true, base::GetFileSize(path, &size64)); | |
4974 ASSERT_LE(size64, std::numeric_limits<int>::max()); | |
4975 int size = static_cast<int>(size64); | |
4976 scoped_ptr<char[]> buf(new char[size]); | |
4977 | |
4978 ASSERT_EQ(size, base::ReadFile(path, buf.get(), size)); | |
4979 | |
4980 ASSERT_EQ(1, d.response_started_count()) | |
4981 << "request failed: " << r->status().status() | |
4982 << ", error: " << r->status().error(); | |
4983 | |
4984 EXPECT_FALSE(d.received_data_before_response()); | |
4985 | |
4986 EXPECT_EQ(size, d.bytes_received()); | |
4987 EXPECT_EQ(std::string(&buf[0], size), d.data_received()); | |
4988 } | |
4989 } | |
4990 | |
4991 TEST_F(URLRequestTestHTTP, PostUnreadableFileTest) { | |
4992 ASSERT_TRUE(test_server_.Start()); | |
4993 | |
4994 TestDelegate d; | |
4995 { | |
4996 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
4997 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); | |
4998 r->set_method("POST"); | |
4999 | |
5000 ScopedVector<UploadElementReader> element_readers; | |
5001 | |
5002 element_readers.push_back(new UploadFileElementReader( | |
5003 base::MessageLoopProxy::current().get(), | |
5004 base::FilePath(FILE_PATH_LITERAL( | |
5005 "c:\\path\\to\\non\\existant\\file.randomness.12345")), | |
5006 0, | |
5007 kuint64max, | |
5008 base::Time())); | |
5009 r->set_upload(make_scoped_ptr<UploadDataStream>( | |
5010 new ElementsUploadDataStream(element_readers.Pass(), 0))); | |
5011 | |
5012 r->Start(); | |
5013 EXPECT_TRUE(r->is_pending()); | |
5014 | |
5015 base::RunLoop().Run(); | |
5016 | |
5017 EXPECT_TRUE(d.request_failed()); | |
5018 EXPECT_FALSE(d.received_data_before_response()); | |
5019 EXPECT_EQ(0, d.bytes_received()); | |
5020 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); | |
5021 EXPECT_EQ(ERR_FILE_NOT_FOUND, r->status().error()); | |
5022 } | |
5023 } | |
5024 | |
5025 TEST_F(URLRequestTestHTTP, TestPostChunkedDataBeforeStart) { | |
5026 ASSERT_TRUE(test_server_.Start()); | |
5027 | |
5028 TestDelegate d; | |
5029 { | |
5030 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
5031 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); | |
5032 r->EnableChunkedUpload(); | |
5033 r->set_method("POST"); | |
5034 AddChunksToUpload(r.get()); | |
5035 r->Start(); | |
5036 EXPECT_TRUE(r->is_pending()); | |
5037 | |
5038 base::RunLoop().Run(); | |
5039 | |
5040 VerifyReceivedDataMatchesChunks(r.get(), &d); | |
5041 } | |
5042 } | |
5043 | |
5044 TEST_F(URLRequestTestHTTP, TestPostChunkedDataJustAfterStart) { | |
5045 ASSERT_TRUE(test_server_.Start()); | |
5046 | |
5047 TestDelegate d; | |
5048 { | |
5049 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
5050 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); | |
5051 r->EnableChunkedUpload(); | |
5052 r->set_method("POST"); | |
5053 r->Start(); | |
5054 EXPECT_TRUE(r->is_pending()); | |
5055 AddChunksToUpload(r.get()); | |
5056 base::RunLoop().Run(); | |
5057 | |
5058 VerifyReceivedDataMatchesChunks(r.get(), &d); | |
5059 } | |
5060 } | |
5061 | |
5062 TEST_F(URLRequestTestHTTP, TestPostChunkedDataAfterStart) { | |
5063 ASSERT_TRUE(test_server_.Start()); | |
5064 | |
5065 TestDelegate d; | |
5066 { | |
5067 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
5068 test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d, NULL)); | |
5069 r->EnableChunkedUpload(); | |
5070 r->set_method("POST"); | |
5071 r->Start(); | |
5072 EXPECT_TRUE(r->is_pending()); | |
5073 | |
5074 base::RunLoop().RunUntilIdle(); | |
5075 AddChunksToUpload(r.get()); | |
5076 base::RunLoop().Run(); | |
5077 | |
5078 VerifyReceivedDataMatchesChunks(r.get(), &d); | |
5079 } | |
5080 } | |
5081 | |
5082 TEST_F(URLRequestTestHTTP, ResponseHeadersTest) { | |
5083 ASSERT_TRUE(test_server_.Start()); | |
5084 | |
5085 TestDelegate d; | |
5086 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5087 test_server_.GetURL("files/with-headers.html"), DEFAULT_PRIORITY, &d, | |
5088 NULL)); | |
5089 req->Start(); | |
5090 base::RunLoop().Run(); | |
5091 | |
5092 const HttpResponseHeaders* headers = req->response_headers(); | |
5093 | |
5094 // Simple sanity check that response_info() accesses the same data. | |
5095 EXPECT_EQ(headers, req->response_info().headers.get()); | |
5096 | |
5097 std::string header; | |
5098 EXPECT_TRUE(headers->GetNormalizedHeader("cache-control", &header)); | |
5099 EXPECT_EQ("private", header); | |
5100 | |
5101 header.clear(); | |
5102 EXPECT_TRUE(headers->GetNormalizedHeader("content-type", &header)); | |
5103 EXPECT_EQ("text/html; charset=ISO-8859-1", header); | |
5104 | |
5105 // The response has two "X-Multiple-Entries" headers. | |
5106 // This verfies our output has them concatenated together. | |
5107 header.clear(); | |
5108 EXPECT_TRUE(headers->GetNormalizedHeader("x-multiple-entries", &header)); | |
5109 EXPECT_EQ("a, b", header); | |
5110 } | |
5111 | |
5112 TEST_F(URLRequestTestHTTP, ProcessSTS) { | |
5113 SpawnedTestServer::SSLOptions ssl_options; | |
5114 SpawnedTestServer https_test_server( | |
5115 SpawnedTestServer::TYPE_HTTPS, | |
5116 ssl_options, | |
5117 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | |
5118 ASSERT_TRUE(https_test_server.Start()); | |
5119 | |
5120 TestDelegate d; | |
5121 scoped_ptr<URLRequest> request(default_context_.CreateRequest( | |
5122 https_test_server.GetURL("files/hsts-headers.html"), DEFAULT_PRIORITY, &d, | |
5123 NULL)); | |
5124 request->Start(); | |
5125 base::RunLoop().Run(); | |
5126 | |
5127 TransportSecurityState* security_state = | |
5128 default_context_.transport_security_state(); | |
5129 TransportSecurityState::DomainState domain_state; | |
5130 EXPECT_TRUE(security_state->GetDynamicDomainState( | |
5131 SpawnedTestServer::kLocalhost, &domain_state)); | |
5132 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, | |
5133 domain_state.sts.upgrade_mode); | |
5134 EXPECT_TRUE(domain_state.sts.include_subdomains); | |
5135 EXPECT_FALSE(domain_state.pkp.include_subdomains); | |
5136 #if defined(OS_ANDROID) | |
5137 // Android's CertVerifyProc does not (yet) handle pins. | |
5138 #else | |
5139 EXPECT_FALSE(domain_state.HasPublicKeyPins()); | |
5140 #endif | |
5141 } | |
5142 | |
5143 // Android's CertVerifyProc does not (yet) handle pins. Therefore, it will | |
5144 // reject HPKP headers, and a test setting only HPKP headers will fail (no | |
5145 // DomainState present because header rejected). | |
5146 #if defined(OS_ANDROID) | |
5147 #define MAYBE_ProcessPKP DISABLED_ProcessPKP | |
5148 #else | |
5149 #define MAYBE_ProcessPKP ProcessPKP | |
5150 #endif | |
5151 | |
5152 // Tests that enabling HPKP on a domain does not affect the HSTS | |
5153 // validity/expiration. | |
5154 TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKP) { | |
5155 SpawnedTestServer::SSLOptions ssl_options; | |
5156 SpawnedTestServer https_test_server( | |
5157 SpawnedTestServer::TYPE_HTTPS, | |
5158 ssl_options, | |
5159 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | |
5160 ASSERT_TRUE(https_test_server.Start()); | |
5161 | |
5162 TestDelegate d; | |
5163 scoped_ptr<URLRequest> request(default_context_.CreateRequest( | |
5164 https_test_server.GetURL("files/hpkp-headers.html"), DEFAULT_PRIORITY, &d, | |
5165 NULL)); | |
5166 request->Start(); | |
5167 base::RunLoop().Run(); | |
5168 | |
5169 TransportSecurityState* security_state = | |
5170 default_context_.transport_security_state(); | |
5171 TransportSecurityState::DomainState domain_state; | |
5172 EXPECT_TRUE(security_state->GetDynamicDomainState( | |
5173 SpawnedTestServer::kLocalhost, &domain_state)); | |
5174 EXPECT_EQ(TransportSecurityState::DomainState::MODE_DEFAULT, | |
5175 domain_state.sts.upgrade_mode); | |
5176 EXPECT_FALSE(domain_state.sts.include_subdomains); | |
5177 EXPECT_FALSE(domain_state.pkp.include_subdomains); | |
5178 EXPECT_TRUE(domain_state.HasPublicKeyPins()); | |
5179 EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry); | |
5180 } | |
5181 | |
5182 TEST_F(URLRequestTestHTTP, ProcessSTSOnce) { | |
5183 SpawnedTestServer::SSLOptions ssl_options; | |
5184 SpawnedTestServer https_test_server( | |
5185 SpawnedTestServer::TYPE_HTTPS, | |
5186 ssl_options, | |
5187 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | |
5188 ASSERT_TRUE(https_test_server.Start()); | |
5189 | |
5190 TestDelegate d; | |
5191 scoped_ptr<URLRequest> request(default_context_.CreateRequest( | |
5192 https_test_server.GetURL("files/hsts-multiple-headers.html"), | |
5193 DEFAULT_PRIORITY, &d, NULL)); | |
5194 request->Start(); | |
5195 base::RunLoop().Run(); | |
5196 | |
5197 // We should have set parameters from the first header, not the second. | |
5198 TransportSecurityState* security_state = | |
5199 default_context_.transport_security_state(); | |
5200 TransportSecurityState::DomainState domain_state; | |
5201 EXPECT_TRUE(security_state->GetDynamicDomainState( | |
5202 SpawnedTestServer::kLocalhost, &domain_state)); | |
5203 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, | |
5204 domain_state.sts.upgrade_mode); | |
5205 EXPECT_FALSE(domain_state.sts.include_subdomains); | |
5206 EXPECT_FALSE(domain_state.pkp.include_subdomains); | |
5207 } | |
5208 | |
5209 TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP) { | |
5210 SpawnedTestServer::SSLOptions ssl_options; | |
5211 SpawnedTestServer https_test_server( | |
5212 SpawnedTestServer::TYPE_HTTPS, | |
5213 ssl_options, | |
5214 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | |
5215 ASSERT_TRUE(https_test_server.Start()); | |
5216 | |
5217 TestDelegate d; | |
5218 scoped_ptr<URLRequest> request(default_context_.CreateRequest( | |
5219 https_test_server.GetURL("files/hsts-and-hpkp-headers.html"), | |
5220 DEFAULT_PRIORITY, &d, NULL)); | |
5221 request->Start(); | |
5222 base::RunLoop().Run(); | |
5223 | |
5224 // We should have set parameters from the first header, not the second. | |
5225 TransportSecurityState* security_state = | |
5226 default_context_.transport_security_state(); | |
5227 TransportSecurityState::DomainState domain_state; | |
5228 EXPECT_TRUE(security_state->GetDynamicDomainState( | |
5229 SpawnedTestServer::kLocalhost, &domain_state)); | |
5230 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, | |
5231 domain_state.sts.upgrade_mode); | |
5232 #if defined(OS_ANDROID) | |
5233 // Android's CertVerifyProc does not (yet) handle pins. | |
5234 #else | |
5235 EXPECT_TRUE(domain_state.HasPublicKeyPins()); | |
5236 #endif | |
5237 EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry); | |
5238 | |
5239 // Even though there is an HSTS header asserting includeSubdomains, it is | |
5240 // the *second* such header, and we MUST process only the first. | |
5241 EXPECT_FALSE(domain_state.sts.include_subdomains); | |
5242 // includeSubdomains does not occur in the test HPKP header. | |
5243 EXPECT_FALSE(domain_state.pkp.include_subdomains); | |
5244 } | |
5245 | |
5246 // Tests that when multiple HPKP headers are present, asserting different | |
5247 // policies, that only the first such policy is processed. | |
5248 TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP2) { | |
5249 SpawnedTestServer::SSLOptions ssl_options; | |
5250 SpawnedTestServer https_test_server( | |
5251 SpawnedTestServer::TYPE_HTTPS, | |
5252 ssl_options, | |
5253 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | |
5254 ASSERT_TRUE(https_test_server.Start()); | |
5255 | |
5256 TestDelegate d; | |
5257 scoped_ptr<URLRequest> request(default_context_.CreateRequest( | |
5258 https_test_server.GetURL("files/hsts-and-hpkp-headers2.html"), | |
5259 DEFAULT_PRIORITY, &d, NULL)); | |
5260 request->Start(); | |
5261 base::RunLoop().Run(); | |
5262 | |
5263 TransportSecurityState* security_state = | |
5264 default_context_.transport_security_state(); | |
5265 TransportSecurityState::DomainState domain_state; | |
5266 EXPECT_TRUE(security_state->GetDynamicDomainState( | |
5267 SpawnedTestServer::kLocalhost, &domain_state)); | |
5268 EXPECT_EQ(TransportSecurityState::DomainState::MODE_FORCE_HTTPS, | |
5269 domain_state.sts.upgrade_mode); | |
5270 #if defined(OS_ANDROID) | |
5271 // Android's CertVerifyProc does not (yet) handle pins. | |
5272 #else | |
5273 EXPECT_TRUE(domain_state.HasPublicKeyPins()); | |
5274 #endif | |
5275 EXPECT_NE(domain_state.sts.expiry, domain_state.pkp.expiry); | |
5276 | |
5277 EXPECT_TRUE(domain_state.sts.include_subdomains); | |
5278 EXPECT_FALSE(domain_state.pkp.include_subdomains); | |
5279 } | |
5280 | |
5281 TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) { | |
5282 ASSERT_TRUE(test_server_.Start()); | |
5283 | |
5284 TestDelegate d; | |
5285 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5286 test_server_.GetURL("files/content-type-normalization.html"), | |
5287 DEFAULT_PRIORITY, &d, NULL)); | |
5288 req->Start(); | |
5289 base::RunLoop().Run(); | |
5290 | |
5291 std::string mime_type; | |
5292 req->GetMimeType(&mime_type); | |
5293 EXPECT_EQ("text/html", mime_type); | |
5294 | |
5295 std::string charset; | |
5296 req->GetCharset(&charset); | |
5297 EXPECT_EQ("utf-8", charset); | |
5298 req->Cancel(); | |
5299 } | |
5300 | |
5301 TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictDataRedirects) { | |
5302 // Test URLRequestJobFactory::ProtocolHandler::IsSafeRedirectTarget(). | |
5303 GURL data_url("data:,foo"); | |
5304 DataProtocolHandler data_protocol_handler; | |
5305 EXPECT_FALSE(data_protocol_handler.IsSafeRedirectTarget(data_url)); | |
5306 | |
5307 // Test URLRequestJobFactoryImpl::IsSafeRedirectTarget(). | |
5308 EXPECT_FALSE(job_factory_->IsSafeRedirectTarget(data_url)); | |
5309 } | |
5310 | |
5311 #if !defined(DISABLE_FILE_SUPPORT) | |
5312 TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictFileRedirects) { | |
5313 // Test URLRequestJobFactory::ProtocolHandler::IsSafeRedirectTarget(). | |
5314 GURL file_url("file:///foo.txt"); | |
5315 FileProtocolHandler file_protocol_handler(base::MessageLoopProxy::current()); | |
5316 EXPECT_FALSE(file_protocol_handler.IsSafeRedirectTarget(file_url)); | |
5317 | |
5318 // Test URLRequestJobFactoryImpl::IsSafeRedirectTarget(). | |
5319 EXPECT_FALSE(job_factory_->IsSafeRedirectTarget(file_url)); | |
5320 } | |
5321 | |
5322 TEST_F(URLRequestTestHTTP, RestrictFileRedirects) { | |
5323 ASSERT_TRUE(test_server_.Start()); | |
5324 | |
5325 TestDelegate d; | |
5326 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5327 test_server_.GetURL("files/redirect-to-file.html"), DEFAULT_PRIORITY, &d, | |
5328 NULL)); | |
5329 req->Start(); | |
5330 base::RunLoop().Run(); | |
5331 | |
5332 EXPECT_EQ(URLRequestStatus::FAILED, req->status().status()); | |
5333 EXPECT_EQ(ERR_UNSAFE_REDIRECT, req->status().error()); | |
5334 } | |
5335 #endif // !defined(DISABLE_FILE_SUPPORT) | |
5336 | |
5337 TEST_F(URLRequestTestHTTP, RestrictDataRedirects) { | |
5338 ASSERT_TRUE(test_server_.Start()); | |
5339 | |
5340 TestDelegate d; | |
5341 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5342 test_server_.GetURL("files/redirect-to-data.html"), DEFAULT_PRIORITY, &d, | |
5343 NULL)); | |
5344 req->Start(); | |
5345 base::MessageLoop::current()->Run(); | |
5346 | |
5347 EXPECT_EQ(URLRequestStatus::FAILED, req->status().status()); | |
5348 EXPECT_EQ(ERR_UNSAFE_REDIRECT, req->status().error()); | |
5349 } | |
5350 | |
5351 TEST_F(URLRequestTestHTTP, RedirectToInvalidURL) { | |
5352 ASSERT_TRUE(test_server_.Start()); | |
5353 | |
5354 TestDelegate d; | |
5355 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5356 test_server_.GetURL("files/redirect-to-invalid-url.html"), | |
5357 DEFAULT_PRIORITY, &d, NULL)); | |
5358 req->Start(); | |
5359 base::RunLoop().Run(); | |
5360 | |
5361 EXPECT_EQ(URLRequestStatus::FAILED, req->status().status()); | |
5362 EXPECT_EQ(ERR_INVALID_URL, req->status().error()); | |
5363 } | |
5364 | |
5365 // Make sure redirects are cached, despite not reading their bodies. | |
5366 TEST_F(URLRequestTestHTTP, CacheRedirect) { | |
5367 ASSERT_TRUE(test_server_.Start()); | |
5368 GURL redirect_url = | |
5369 test_server_.GetURL("files/redirect302-to-echo-cacheable"); | |
5370 | |
5371 { | |
5372 TestDelegate d; | |
5373 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5374 redirect_url, DEFAULT_PRIORITY, &d, NULL)); | |
5375 req->Start(); | |
5376 base::RunLoop().Run(); | |
5377 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); | |
5378 EXPECT_EQ(1, d.received_redirect_count()); | |
5379 EXPECT_EQ(test_server_.GetURL("echo"), req->url()); | |
5380 } | |
5381 | |
5382 { | |
5383 TestDelegate d; | |
5384 d.set_quit_on_redirect(true); | |
5385 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5386 redirect_url, DEFAULT_PRIORITY, &d, NULL)); | |
5387 req->Start(); | |
5388 base::RunLoop().Run(); | |
5389 | |
5390 EXPECT_EQ(1, d.received_redirect_count()); | |
5391 EXPECT_EQ(0, d.response_started_count()); | |
5392 EXPECT_TRUE(req->was_cached()); | |
5393 | |
5394 req->FollowDeferredRedirect(); | |
5395 base::RunLoop().Run(); | |
5396 EXPECT_EQ(1, d.received_redirect_count()); | |
5397 EXPECT_EQ(1, d.response_started_count()); | |
5398 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); | |
5399 EXPECT_EQ(test_server_.GetURL("echo"), req->url()); | |
5400 } | |
5401 } | |
5402 | |
5403 // Make sure a request isn't cached when a NetworkDelegate forces a redirect | |
5404 // when the headers are read, since the body won't have been read. | |
5405 TEST_F(URLRequestTestHTTP, NoCacheOnNetworkDelegateRedirect) { | |
5406 ASSERT_TRUE(test_server_.Start()); | |
5407 // URL that is normally cached. | |
5408 GURL initial_url = test_server_.GetURL("cachetime"); | |
5409 | |
5410 { | |
5411 // Set up the TestNetworkDelegate tp force a redirect. | |
5412 GURL redirect_to_url = test_server_.GetURL("echo"); | |
5413 default_network_delegate_.set_redirect_on_headers_received_url( | |
5414 redirect_to_url); | |
5415 | |
5416 TestDelegate d; | |
5417 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5418 initial_url, DEFAULT_PRIORITY, &d, NULL)); | |
5419 req->Start(); | |
5420 base::RunLoop().Run(); | |
5421 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); | |
5422 EXPECT_EQ(1, d.received_redirect_count()); | |
5423 EXPECT_EQ(redirect_to_url, req->url()); | |
5424 } | |
5425 | |
5426 { | |
5427 TestDelegate d; | |
5428 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5429 initial_url, DEFAULT_PRIORITY, &d, NULL)); | |
5430 req->Start(); | |
5431 base::RunLoop().Run(); | |
5432 | |
5433 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); | |
5434 EXPECT_FALSE(req->was_cached()); | |
5435 EXPECT_EQ(0, d.received_redirect_count()); | |
5436 EXPECT_EQ(initial_url, req->url()); | |
5437 } | |
5438 } | |
5439 | |
5440 // Tests that redirection to an unsafe URL is allowed when it has been marked as | |
5441 // safe. | |
5442 TEST_F(URLRequestTestHTTP, UnsafeRedirectToWhitelistedUnsafeURL) { | |
5443 ASSERT_TRUE(test_server_.Start()); | |
5444 | |
5445 GURL unsafe_url("data:text/html,this-is-considered-an-unsafe-url"); | |
5446 default_network_delegate_.set_redirect_on_headers_received_url(unsafe_url); | |
5447 default_network_delegate_.set_allowed_unsafe_redirect_url(unsafe_url); | |
5448 | |
5449 TestDelegate d; | |
5450 { | |
5451 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
5452 test_server_.GetURL("whatever"), DEFAULT_PRIORITY, &d, NULL)); | |
5453 | |
5454 r->Start(); | |
5455 base::RunLoop().Run(); | |
5456 | |
5457 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
5458 | |
5459 EXPECT_EQ(2U, r->url_chain().size()); | |
5460 EXPECT_EQ(OK, r->status().error()); | |
5461 EXPECT_EQ(unsafe_url, r->url()); | |
5462 EXPECT_EQ("this-is-considered-an-unsafe-url", d.data_received()); | |
5463 } | |
5464 } | |
5465 | |
5466 // Tests that a redirect to a different unsafe URL is blocked, even after adding | |
5467 // some other URL to the whitelist. | |
5468 TEST_F(URLRequestTestHTTP, UnsafeRedirectToDifferentUnsafeURL) { | |
5469 ASSERT_TRUE(test_server_.Start()); | |
5470 | |
5471 GURL unsafe_url("data:text/html,something"); | |
5472 GURL different_unsafe_url("data:text/html,something-else"); | |
5473 default_network_delegate_.set_redirect_on_headers_received_url(unsafe_url); | |
5474 default_network_delegate_.set_allowed_unsafe_redirect_url( | |
5475 different_unsafe_url); | |
5476 | |
5477 TestDelegate d; | |
5478 { | |
5479 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
5480 test_server_.GetURL("whatever"), DEFAULT_PRIORITY, &d, NULL)); | |
5481 | |
5482 r->Start(); | |
5483 base::RunLoop().Run(); | |
5484 | |
5485 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); | |
5486 EXPECT_EQ(ERR_UNSAFE_REDIRECT, r->status().error()); | |
5487 } | |
5488 } | |
5489 | |
5490 // Redirects from an URL with fragment to an unsafe URL with fragment should | |
5491 // be allowed, and the reference fragment of the target URL should be preserved. | |
5492 TEST_F(URLRequestTestHTTP, UnsafeRedirectWithDifferentReferenceFragment) { | |
5493 ASSERT_TRUE(test_server_.Start()); | |
5494 | |
5495 GURL original_url(test_server_.GetURL("original#fragment1")); | |
5496 GURL unsafe_url("data:,url-marked-safe-and-used-in-redirect#fragment2"); | |
5497 GURL expected_url("data:,url-marked-safe-and-used-in-redirect#fragment2"); | |
5498 | |
5499 default_network_delegate_.set_redirect_on_headers_received_url(unsafe_url); | |
5500 default_network_delegate_.set_allowed_unsafe_redirect_url(unsafe_url); | |
5501 | |
5502 TestDelegate d; | |
5503 { | |
5504 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
5505 original_url, DEFAULT_PRIORITY, &d, NULL)); | |
5506 | |
5507 r->Start(); | |
5508 base::RunLoop().Run(); | |
5509 | |
5510 EXPECT_EQ(2U, r->url_chain().size()); | |
5511 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
5512 EXPECT_EQ(OK, r->status().error()); | |
5513 EXPECT_EQ(original_url, r->original_url()); | |
5514 EXPECT_EQ(expected_url, r->url()); | |
5515 } | |
5516 } | |
5517 | |
5518 // When a delegate has specified a safe redirect URL, but it does not match the | |
5519 // redirect target, then do not prevent the reference fragment from being added. | |
5520 TEST_F(URLRequestTestHTTP, RedirectWithReferenceFragmentAndUnrelatedUnsafeUrl) { | |
5521 ASSERT_TRUE(test_server_.Start()); | |
5522 | |
5523 GURL original_url(test_server_.GetURL("original#expected-fragment")); | |
5524 GURL unsafe_url("data:text/html,this-url-does-not-match-redirect-url"); | |
5525 GURL redirect_url(test_server_.GetURL("target")); | |
5526 GURL expected_redirect_url(test_server_.GetURL("target#expected-fragment")); | |
5527 | |
5528 default_network_delegate_.set_redirect_on_headers_received_url(redirect_url); | |
5529 default_network_delegate_.set_allowed_unsafe_redirect_url(unsafe_url); | |
5530 | |
5531 TestDelegate d; | |
5532 { | |
5533 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
5534 original_url, DEFAULT_PRIORITY, &d, NULL)); | |
5535 | |
5536 r->Start(); | |
5537 base::RunLoop().Run(); | |
5538 | |
5539 EXPECT_EQ(2U, r->url_chain().size()); | |
5540 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
5541 EXPECT_EQ(OK, r->status().error()); | |
5542 EXPECT_EQ(original_url, r->original_url()); | |
5543 EXPECT_EQ(expected_redirect_url, r->url()); | |
5544 } | |
5545 } | |
5546 | |
5547 // When a delegate has specified a safe redirect URL, assume that the redirect | |
5548 // URL should not be changed. In particular, the reference fragment should not | |
5549 // be modified. | |
5550 TEST_F(URLRequestTestHTTP, RedirectWithReferenceFragment) { | |
5551 ASSERT_TRUE(test_server_.Start()); | |
5552 | |
5553 GURL original_url(test_server_.GetURL("original#should-not-be-appended")); | |
5554 GURL redirect_url("data:text/html,expect-no-reference-fragment"); | |
5555 | |
5556 default_network_delegate_.set_redirect_on_headers_received_url(redirect_url); | |
5557 default_network_delegate_.set_allowed_unsafe_redirect_url(redirect_url); | |
5558 | |
5559 TestDelegate d; | |
5560 { | |
5561 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
5562 original_url, DEFAULT_PRIORITY, &d, NULL)); | |
5563 | |
5564 r->Start(); | |
5565 base::RunLoop().Run(); | |
5566 | |
5567 EXPECT_EQ(2U, r->url_chain().size()); | |
5568 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
5569 EXPECT_EQ(OK, r->status().error()); | |
5570 EXPECT_EQ(original_url, r->original_url()); | |
5571 EXPECT_EQ(redirect_url, r->url()); | |
5572 } | |
5573 } | |
5574 | |
5575 // When a URLRequestRedirectJob is created, the redirection must be followed and | |
5576 // the reference fragment of the target URL must not be modified. | |
5577 TEST_F(URLRequestTestHTTP, RedirectJobWithReferenceFragment) { | |
5578 ASSERT_TRUE(test_server_.Start()); | |
5579 | |
5580 GURL original_url(test_server_.GetURL("original#should-not-be-appended")); | |
5581 GURL redirect_url(test_server_.GetURL("echo")); | |
5582 | |
5583 TestDelegate d; | |
5584 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
5585 original_url, DEFAULT_PRIORITY, &d, NULL)); | |
5586 | |
5587 URLRequestRedirectJob* job = new URLRequestRedirectJob( | |
5588 r.get(), &default_network_delegate_, redirect_url, | |
5589 URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason"); | |
5590 AddTestInterceptor()->set_main_intercept_job(job); | |
5591 | |
5592 r->Start(); | |
5593 base::RunLoop().Run(); | |
5594 | |
5595 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
5596 EXPECT_EQ(OK, r->status().error()); | |
5597 EXPECT_EQ(original_url, r->original_url()); | |
5598 EXPECT_EQ(redirect_url, r->url()); | |
5599 } | |
5600 | |
5601 TEST_F(URLRequestTestHTTP, NoUserPassInReferrer) { | |
5602 ASSERT_TRUE(test_server_.Start()); | |
5603 | |
5604 TestDelegate d; | |
5605 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5606 test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL)); | |
5607 req->SetReferrer("http://user:pass@foo.com/"); | |
5608 req->Start(); | |
5609 base::RunLoop().Run(); | |
5610 | |
5611 EXPECT_EQ(std::string("http://foo.com/"), d.data_received()); | |
5612 } | |
5613 | |
5614 TEST_F(URLRequestTestHTTP, NoFragmentInReferrer) { | |
5615 ASSERT_TRUE(test_server_.Start()); | |
5616 | |
5617 TestDelegate d; | |
5618 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5619 test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL)); | |
5620 req->SetReferrer("http://foo.com/test#fragment"); | |
5621 req->Start(); | |
5622 base::RunLoop().Run(); | |
5623 | |
5624 EXPECT_EQ(std::string("http://foo.com/test"), d.data_received()); | |
5625 } | |
5626 | |
5627 TEST_F(URLRequestTestHTTP, EmptyReferrerAfterValidReferrer) { | |
5628 ASSERT_TRUE(test_server_.Start()); | |
5629 | |
5630 TestDelegate d; | |
5631 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5632 test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d, NULL)); | |
5633 req->SetReferrer("http://foo.com/test#fragment"); | |
5634 req->SetReferrer(""); | |
5635 req->Start(); | |
5636 base::RunLoop().Run(); | |
5637 | |
5638 EXPECT_EQ(std::string("None"), d.data_received()); | |
5639 } | |
5640 | |
5641 // Defer network start and then resume, checking that the request was a success | |
5642 // and bytes were received. | |
5643 TEST_F(URLRequestTestHTTP, DeferredBeforeNetworkStart) { | |
5644 ASSERT_TRUE(test_server_.Start()); | |
5645 | |
5646 TestDelegate d; | |
5647 { | |
5648 d.set_quit_on_network_start(true); | |
5649 GURL test_url(test_server_.GetURL("echo")); | |
5650 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5651 test_url, DEFAULT_PRIORITY, &d, NULL)); | |
5652 | |
5653 req->Start(); | |
5654 base::RunLoop().Run(); | |
5655 | |
5656 EXPECT_EQ(1, d.received_before_network_start_count()); | |
5657 EXPECT_EQ(0, d.response_started_count()); | |
5658 | |
5659 req->ResumeNetworkStart(); | |
5660 base::RunLoop().Run(); | |
5661 | |
5662 EXPECT_EQ(1, d.response_started_count()); | |
5663 EXPECT_NE(0, d.bytes_received()); | |
5664 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); | |
5665 } | |
5666 } | |
5667 | |
5668 // Check that OnBeforeNetworkStart is only called once even if there is a | |
5669 // redirect. | |
5670 TEST_F(URLRequestTestHTTP, BeforeNetworkStartCalledOnce) { | |
5671 ASSERT_TRUE(test_server_.Start()); | |
5672 | |
5673 TestDelegate d; | |
5674 { | |
5675 d.set_quit_on_redirect(true); | |
5676 d.set_quit_on_network_start(true); | |
5677 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5678 test_server_.GetURL("server-redirect?echo"), DEFAULT_PRIORITY, &d, | |
5679 NULL)); | |
5680 | |
5681 req->Start(); | |
5682 base::RunLoop().Run(); | |
5683 | |
5684 EXPECT_EQ(1, d.received_before_network_start_count()); | |
5685 EXPECT_EQ(0, d.response_started_count()); | |
5686 EXPECT_EQ(0, d.received_redirect_count()); | |
5687 | |
5688 req->ResumeNetworkStart(); | |
5689 base::RunLoop().Run(); | |
5690 | |
5691 EXPECT_EQ(1, d.received_redirect_count()); | |
5692 req->FollowDeferredRedirect(); | |
5693 base::RunLoop().Run(); | |
5694 | |
5695 // Check that the redirect's new network transaction does not get propagated | |
5696 // to a second OnBeforeNetworkStart() notification. | |
5697 EXPECT_EQ(1, d.received_before_network_start_count()); | |
5698 | |
5699 EXPECT_EQ(1, d.response_started_count()); | |
5700 EXPECT_NE(0, d.bytes_received()); | |
5701 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); | |
5702 } | |
5703 } | |
5704 | |
5705 // Cancel the request after learning that the request would use the network. | |
5706 TEST_F(URLRequestTestHTTP, CancelOnBeforeNetworkStart) { | |
5707 ASSERT_TRUE(test_server_.Start()); | |
5708 | |
5709 TestDelegate d; | |
5710 { | |
5711 d.set_quit_on_network_start(true); | |
5712 GURL test_url(test_server_.GetURL("echo")); | |
5713 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5714 test_url, DEFAULT_PRIORITY, &d, NULL)); | |
5715 | |
5716 req->Start(); | |
5717 base::RunLoop().Run(); | |
5718 | |
5719 EXPECT_EQ(1, d.received_before_network_start_count()); | |
5720 EXPECT_EQ(0, d.response_started_count()); | |
5721 | |
5722 req->Cancel(); | |
5723 base::RunLoop().Run(); | |
5724 | |
5725 EXPECT_EQ(1, d.response_started_count()); | |
5726 EXPECT_EQ(0, d.bytes_received()); | |
5727 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); | |
5728 } | |
5729 } | |
5730 | |
5731 TEST_F(URLRequestTestHTTP, CancelRedirect) { | |
5732 ASSERT_TRUE(test_server_.Start()); | |
5733 | |
5734 TestDelegate d; | |
5735 { | |
5736 d.set_cancel_in_received_redirect(true); | |
5737 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5738 test_server_.GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, &d, | |
5739 NULL)); | |
5740 req->Start(); | |
5741 base::RunLoop().Run(); | |
5742 | |
5743 EXPECT_EQ(1, d.response_started_count()); | |
5744 EXPECT_EQ(0, d.bytes_received()); | |
5745 EXPECT_FALSE(d.received_data_before_response()); | |
5746 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); | |
5747 } | |
5748 } | |
5749 | |
5750 TEST_F(URLRequestTestHTTP, DeferredRedirect) { | |
5751 ASSERT_TRUE(test_server_.Start()); | |
5752 | |
5753 TestDelegate d; | |
5754 { | |
5755 d.set_quit_on_redirect(true); | |
5756 GURL test_url(test_server_.GetURL("files/redirect-test.html")); | |
5757 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5758 test_url, DEFAULT_PRIORITY, &d, NULL)); | |
5759 | |
5760 req->Start(); | |
5761 base::RunLoop().Run(); | |
5762 | |
5763 EXPECT_EQ(1, d.received_redirect_count()); | |
5764 | |
5765 req->FollowDeferredRedirect(); | |
5766 base::RunLoop().Run(); | |
5767 | |
5768 EXPECT_EQ(1, d.response_started_count()); | |
5769 EXPECT_FALSE(d.received_data_before_response()); | |
5770 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); | |
5771 | |
5772 base::FilePath path; | |
5773 PathService::Get(base::DIR_SOURCE_ROOT, &path); | |
5774 path = path.Append(FILE_PATH_LITERAL("net")); | |
5775 path = path.Append(FILE_PATH_LITERAL("data")); | |
5776 path = path.Append(FILE_PATH_LITERAL("url_request_unittest")); | |
5777 path = path.Append(FILE_PATH_LITERAL("with-headers.html")); | |
5778 | |
5779 std::string contents; | |
5780 EXPECT_TRUE(base::ReadFileToString(path, &contents)); | |
5781 EXPECT_EQ(contents, d.data_received()); | |
5782 } | |
5783 } | |
5784 | |
5785 TEST_F(URLRequestTestHTTP, DeferredRedirect_GetFullRequestHeaders) { | |
5786 ASSERT_TRUE(test_server_.Start()); | |
5787 | |
5788 TestDelegate d; | |
5789 { | |
5790 d.set_quit_on_redirect(true); | |
5791 GURL test_url(test_server_.GetURL("files/redirect-test.html")); | |
5792 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5793 test_url, DEFAULT_PRIORITY, &d, NULL)); | |
5794 | |
5795 EXPECT_FALSE(d.have_full_request_headers()); | |
5796 | |
5797 req->Start(); | |
5798 base::RunLoop().Run(); | |
5799 | |
5800 EXPECT_EQ(1, d.received_redirect_count()); | |
5801 EXPECT_TRUE(d.have_full_request_headers()); | |
5802 CheckFullRequestHeaders(d.full_request_headers(), test_url); | |
5803 d.ClearFullRequestHeaders(); | |
5804 | |
5805 req->FollowDeferredRedirect(); | |
5806 base::RunLoop().Run(); | |
5807 | |
5808 GURL target_url(test_server_.GetURL("files/with-headers.html")); | |
5809 EXPECT_EQ(1, d.response_started_count()); | |
5810 EXPECT_TRUE(d.have_full_request_headers()); | |
5811 CheckFullRequestHeaders(d.full_request_headers(), target_url); | |
5812 EXPECT_FALSE(d.received_data_before_response()); | |
5813 EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status()); | |
5814 | |
5815 base::FilePath path; | |
5816 PathService::Get(base::DIR_SOURCE_ROOT, &path); | |
5817 path = path.Append(FILE_PATH_LITERAL("net")); | |
5818 path = path.Append(FILE_PATH_LITERAL("data")); | |
5819 path = path.Append(FILE_PATH_LITERAL("url_request_unittest")); | |
5820 path = path.Append(FILE_PATH_LITERAL("with-headers.html")); | |
5821 | |
5822 std::string contents; | |
5823 EXPECT_TRUE(base::ReadFileToString(path, &contents)); | |
5824 EXPECT_EQ(contents, d.data_received()); | |
5825 } | |
5826 } | |
5827 | |
5828 TEST_F(URLRequestTestHTTP, CancelDeferredRedirect) { | |
5829 ASSERT_TRUE(test_server_.Start()); | |
5830 | |
5831 TestDelegate d; | |
5832 { | |
5833 d.set_quit_on_redirect(true); | |
5834 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5835 test_server_.GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, &d, | |
5836 NULL)); | |
5837 req->Start(); | |
5838 base::RunLoop().Run(); | |
5839 | |
5840 EXPECT_EQ(1, d.received_redirect_count()); | |
5841 | |
5842 req->Cancel(); | |
5843 base::RunLoop().Run(); | |
5844 | |
5845 EXPECT_EQ(1, d.response_started_count()); | |
5846 EXPECT_EQ(0, d.bytes_received()); | |
5847 EXPECT_FALSE(d.received_data_before_response()); | |
5848 EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status()); | |
5849 } | |
5850 } | |
5851 | |
5852 TEST_F(URLRequestTestHTTP, VaryHeader) { | |
5853 ASSERT_TRUE(test_server_.Start()); | |
5854 | |
5855 // Populate the cache. | |
5856 { | |
5857 TestDelegate d; | |
5858 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5859 test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d, | |
5860 NULL)); | |
5861 HttpRequestHeaders headers; | |
5862 headers.SetHeader("foo", "1"); | |
5863 req->SetExtraRequestHeaders(headers); | |
5864 req->Start(); | |
5865 base::RunLoop().Run(); | |
5866 | |
5867 LoadTimingInfo load_timing_info; | |
5868 req->GetLoadTimingInfo(&load_timing_info); | |
5869 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); | |
5870 } | |
5871 | |
5872 // Expect a cache hit. | |
5873 { | |
5874 TestDelegate d; | |
5875 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5876 test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d, | |
5877 NULL)); | |
5878 HttpRequestHeaders headers; | |
5879 headers.SetHeader("foo", "1"); | |
5880 req->SetExtraRequestHeaders(headers); | |
5881 req->Start(); | |
5882 base::RunLoop().Run(); | |
5883 | |
5884 EXPECT_TRUE(req->was_cached()); | |
5885 | |
5886 LoadTimingInfo load_timing_info; | |
5887 req->GetLoadTimingInfo(&load_timing_info); | |
5888 TestLoadTimingCacheHitNoNetwork(load_timing_info); | |
5889 } | |
5890 | |
5891 // Expect a cache miss. | |
5892 { | |
5893 TestDelegate d; | |
5894 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
5895 test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d, | |
5896 NULL)); | |
5897 HttpRequestHeaders headers; | |
5898 headers.SetHeader("foo", "2"); | |
5899 req->SetExtraRequestHeaders(headers); | |
5900 req->Start(); | |
5901 base::RunLoop().Run(); | |
5902 | |
5903 EXPECT_FALSE(req->was_cached()); | |
5904 | |
5905 LoadTimingInfo load_timing_info; | |
5906 req->GetLoadTimingInfo(&load_timing_info); | |
5907 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); | |
5908 } | |
5909 } | |
5910 | |
5911 TEST_F(URLRequestTestHTTP, BasicAuth) { | |
5912 ASSERT_TRUE(test_server_.Start()); | |
5913 | |
5914 // populate the cache | |
5915 { | |
5916 TestDelegate d; | |
5917 d.set_credentials(AuthCredentials(kUser, kSecret)); | |
5918 | |
5919 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
5920 test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL)); | |
5921 r->Start(); | |
5922 | |
5923 base::RunLoop().Run(); | |
5924 | |
5925 EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos); | |
5926 } | |
5927 | |
5928 // repeat request with end-to-end validation. since auth-basic results in a | |
5929 // cachable page, we expect this test to result in a 304. in which case, the | |
5930 // response should be fetched from the cache. | |
5931 { | |
5932 TestDelegate d; | |
5933 d.set_credentials(AuthCredentials(kUser, kSecret)); | |
5934 | |
5935 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
5936 test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL)); | |
5937 r->SetLoadFlags(LOAD_VALIDATE_CACHE); | |
5938 r->Start(); | |
5939 | |
5940 base::RunLoop().Run(); | |
5941 | |
5942 EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos); | |
5943 | |
5944 // Should be the same cached document. | |
5945 EXPECT_TRUE(r->was_cached()); | |
5946 } | |
5947 } | |
5948 | |
5949 // Check that Set-Cookie headers in 401 responses are respected. | |
5950 // http://crbug.com/6450 | |
5951 TEST_F(URLRequestTestHTTP, BasicAuthWithCookies) { | |
5952 ASSERT_TRUE(test_server_.Start()); | |
5953 | |
5954 GURL url_requiring_auth = | |
5955 test_server_.GetURL("auth-basic?set-cookie-if-challenged"); | |
5956 | |
5957 // Request a page that will give a 401 containing a Set-Cookie header. | |
5958 // Verify that when the transaction is restarted, it includes the new cookie. | |
5959 { | |
5960 TestNetworkDelegate network_delegate; // Must outlive URLRequest. | |
5961 TestURLRequestContext context(true); | |
5962 context.set_network_delegate(&network_delegate); | |
5963 context.Init(); | |
5964 | |
5965 TestDelegate d; | |
5966 d.set_credentials(AuthCredentials(kUser, kSecret)); | |
5967 | |
5968 scoped_ptr<URLRequest> r(context.CreateRequest( | |
5969 url_requiring_auth, DEFAULT_PRIORITY, &d, NULL)); | |
5970 r->Start(); | |
5971 | |
5972 base::RunLoop().Run(); | |
5973 | |
5974 EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos); | |
5975 | |
5976 // Make sure we sent the cookie in the restarted transaction. | |
5977 EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true") | |
5978 != std::string::npos); | |
5979 } | |
5980 | |
5981 // Same test as above, except this time the restart is initiated earlier | |
5982 // (without user intervention since identity is embedded in the URL). | |
5983 { | |
5984 TestNetworkDelegate network_delegate; // Must outlive URLRequest. | |
5985 TestURLRequestContext context(true); | |
5986 context.set_network_delegate(&network_delegate); | |
5987 context.Init(); | |
5988 | |
5989 TestDelegate d; | |
5990 | |
5991 GURL::Replacements replacements; | |
5992 replacements.SetUsernameStr("user2"); | |
5993 replacements.SetPasswordStr("secret"); | |
5994 GURL url_with_identity = url_requiring_auth.ReplaceComponents(replacements); | |
5995 | |
5996 scoped_ptr<URLRequest> r(context.CreateRequest( | |
5997 url_with_identity, DEFAULT_PRIORITY, &d, NULL)); | |
5998 r->Start(); | |
5999 | |
6000 base::RunLoop().Run(); | |
6001 | |
6002 EXPECT_TRUE(d.data_received().find("user2/secret") != std::string::npos); | |
6003 | |
6004 // Make sure we sent the cookie in the restarted transaction. | |
6005 EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true") | |
6006 != std::string::npos); | |
6007 } | |
6008 } | |
6009 | |
6010 // Tests that load timing works as expected with auth and the cache. | |
6011 TEST_F(URLRequestTestHTTP, BasicAuthLoadTiming) { | |
6012 ASSERT_TRUE(test_server_.Start()); | |
6013 | |
6014 // populate the cache | |
6015 { | |
6016 TestDelegate d; | |
6017 d.set_credentials(AuthCredentials(kUser, kSecret)); | |
6018 | |
6019 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
6020 test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL)); | |
6021 r->Start(); | |
6022 | |
6023 base::RunLoop().Run(); | |
6024 | |
6025 EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos); | |
6026 | |
6027 LoadTimingInfo load_timing_info_before_auth; | |
6028 EXPECT_TRUE(default_network_delegate_.GetLoadTimingInfoBeforeAuth( | |
6029 &load_timing_info_before_auth)); | |
6030 TestLoadTimingNotReused(load_timing_info_before_auth, | |
6031 CONNECT_TIMING_HAS_DNS_TIMES); | |
6032 | |
6033 LoadTimingInfo load_timing_info; | |
6034 r->GetLoadTimingInfo(&load_timing_info); | |
6035 // The test server does not support keep alive sockets, so the second | |
6036 // request with auth should use a new socket. | |
6037 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); | |
6038 EXPECT_NE(load_timing_info_before_auth.socket_log_id, | |
6039 load_timing_info.socket_log_id); | |
6040 EXPECT_LE(load_timing_info_before_auth.receive_headers_end, | |
6041 load_timing_info.connect_timing.connect_start); | |
6042 } | |
6043 | |
6044 // Repeat request with end-to-end validation. Since auth-basic results in a | |
6045 // cachable page, we expect this test to result in a 304. In which case, the | |
6046 // response should be fetched from the cache. | |
6047 { | |
6048 TestDelegate d; | |
6049 d.set_credentials(AuthCredentials(kUser, kSecret)); | |
6050 | |
6051 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
6052 test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d, NULL)); | |
6053 r->SetLoadFlags(LOAD_VALIDATE_CACHE); | |
6054 r->Start(); | |
6055 | |
6056 base::RunLoop().Run(); | |
6057 | |
6058 EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos); | |
6059 | |
6060 // Should be the same cached document. | |
6061 EXPECT_TRUE(r->was_cached()); | |
6062 | |
6063 // Since there was a request that went over the wire, the load timing | |
6064 // information should include connection times. | |
6065 LoadTimingInfo load_timing_info; | |
6066 r->GetLoadTimingInfo(&load_timing_info); | |
6067 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); | |
6068 } | |
6069 } | |
6070 | |
6071 // In this test, we do a POST which the server will 302 redirect. | |
6072 // The subsequent transaction should use GET, and should not send the | |
6073 // Content-Type header. | |
6074 // http://code.google.com/p/chromium/issues/detail?id=843 | |
6075 TEST_F(URLRequestTestHTTP, Post302RedirectGet) { | |
6076 ASSERT_TRUE(test_server_.Start()); | |
6077 | |
6078 const char kData[] = "hello world"; | |
6079 | |
6080 TestDelegate d; | |
6081 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
6082 test_server_.GetURL("files/redirect-to-echoall"), DEFAULT_PRIORITY, &d, | |
6083 NULL)); | |
6084 req->set_method("POST"); | |
6085 req->set_upload(CreateSimpleUploadData(kData)); | |
6086 | |
6087 // Set headers (some of which are specific to the POST). | |
6088 HttpRequestHeaders headers; | |
6089 headers.AddHeadersFromString( | |
6090 "Content-Type: multipart/form-data; " | |
6091 "boundary=----WebKitFormBoundaryAADeAA+NAAWMAAwZ\r\n" | |
6092 "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9," | |
6093 "text/plain;q=0.8,image/png,*/*;q=0.5\r\n" | |
6094 "Accept-Language: en-US,en\r\n" | |
6095 "Accept-Charset: ISO-8859-1,*,utf-8\r\n" | |
6096 "Content-Length: 11\r\n" | |
6097 "Origin: http://localhost:1337/"); | |
6098 req->SetExtraRequestHeaders(headers); | |
6099 req->Start(); | |
6100 base::RunLoop().Run(); | |
6101 | |
6102 std::string mime_type; | |
6103 req->GetMimeType(&mime_type); | |
6104 EXPECT_EQ("text/html", mime_type); | |
6105 | |
6106 const std::string& data = d.data_received(); | |
6107 | |
6108 // Check that the post-specific headers were stripped: | |
6109 EXPECT_FALSE(ContainsString(data, "Content-Length:")); | |
6110 EXPECT_FALSE(ContainsString(data, "Content-Type:")); | |
6111 EXPECT_FALSE(ContainsString(data, "Origin:")); | |
6112 | |
6113 // These extra request headers should not have been stripped. | |
6114 EXPECT_TRUE(ContainsString(data, "Accept:")); | |
6115 EXPECT_TRUE(ContainsString(data, "Accept-Language:")); | |
6116 EXPECT_TRUE(ContainsString(data, "Accept-Charset:")); | |
6117 } | |
6118 | |
6119 // The following tests check that we handle mutating the request method for | |
6120 // HTTP redirects as expected. | |
6121 // See http://crbug.com/56373 and http://crbug.com/102130. | |
6122 | |
6123 TEST_F(URLRequestTestHTTP, Redirect301Tests) { | |
6124 ASSERT_TRUE(test_server_.Start()); | |
6125 | |
6126 const GURL url = test_server_.GetURL("files/redirect301-to-echo"); | |
6127 | |
6128 HTTPRedirectMethodTest(url, "POST", "GET", true); | |
6129 HTTPRedirectMethodTest(url, "PUT", "PUT", true); | |
6130 HTTPRedirectMethodTest(url, "HEAD", "HEAD", false); | |
6131 } | |
6132 | |
6133 TEST_F(URLRequestTestHTTP, Redirect302Tests) { | |
6134 ASSERT_TRUE(test_server_.Start()); | |
6135 | |
6136 const GURL url = test_server_.GetURL("files/redirect302-to-echo"); | |
6137 | |
6138 HTTPRedirectMethodTest(url, "POST", "GET", true); | |
6139 HTTPRedirectMethodTest(url, "PUT", "PUT", true); | |
6140 HTTPRedirectMethodTest(url, "HEAD", "HEAD", false); | |
6141 } | |
6142 | |
6143 TEST_F(URLRequestTestHTTP, Redirect303Tests) { | |
6144 ASSERT_TRUE(test_server_.Start()); | |
6145 | |
6146 const GURL url = test_server_.GetURL("files/redirect303-to-echo"); | |
6147 | |
6148 HTTPRedirectMethodTest(url, "POST", "GET", true); | |
6149 HTTPRedirectMethodTest(url, "PUT", "GET", true); | |
6150 HTTPRedirectMethodTest(url, "HEAD", "HEAD", false); | |
6151 } | |
6152 | |
6153 TEST_F(URLRequestTestHTTP, Redirect307Tests) { | |
6154 ASSERT_TRUE(test_server_.Start()); | |
6155 | |
6156 const GURL url = test_server_.GetURL("files/redirect307-to-echo"); | |
6157 | |
6158 HTTPRedirectMethodTest(url, "POST", "POST", true); | |
6159 HTTPRedirectMethodTest(url, "PUT", "PUT", true); | |
6160 HTTPRedirectMethodTest(url, "HEAD", "HEAD", false); | |
6161 } | |
6162 | |
6163 TEST_F(URLRequestTestHTTP, Redirect308Tests) { | |
6164 ASSERT_TRUE(test_server_.Start()); | |
6165 | |
6166 const GURL url = test_server_.GetURL("files/redirect308-to-echo"); | |
6167 | |
6168 HTTPRedirectMethodTest(url, "POST", "POST", true); | |
6169 HTTPRedirectMethodTest(url, "PUT", "PUT", true); | |
6170 HTTPRedirectMethodTest(url, "HEAD", "HEAD", false); | |
6171 } | |
6172 | |
6173 // Make sure that 308 responses without bodies are not treated as redirects. | |
6174 // Certain legacy apis that pre-date the response code expect this behavior | |
6175 // (Like Google Drive). | |
6176 TEST_F(URLRequestTestHTTP, NoRedirectOn308WithoutLocationHeader) { | |
6177 ASSERT_TRUE(test_server_.Start()); | |
6178 | |
6179 TestDelegate d; | |
6180 const GURL url = test_server_.GetURL("files/308-without-location-header"); | |
6181 | |
6182 scoped_ptr<URLRequest> request(default_context_.CreateRequest( | |
6183 url, DEFAULT_PRIORITY, &d, NULL)); | |
6184 | |
6185 request->Start(); | |
6186 base::RunLoop().Run(); | |
6187 EXPECT_EQ(URLRequestStatus::SUCCESS, request->status().status()); | |
6188 EXPECT_EQ(OK, request->status().error()); | |
6189 EXPECT_EQ(0, d.received_redirect_count()); | |
6190 EXPECT_EQ(308, request->response_headers()->response_code()); | |
6191 EXPECT_EQ("This is not a redirect.", d.data_received()); | |
6192 } | |
6193 | |
6194 TEST_F(URLRequestTestHTTP, Redirect302PreserveReferenceFragment) { | |
6195 ASSERT_TRUE(test_server_.Start()); | |
6196 | |
6197 GURL original_url(test_server_.GetURL("files/redirect302-to-echo#fragment")); | |
6198 GURL expected_url(test_server_.GetURL("echo#fragment")); | |
6199 | |
6200 TestDelegate d; | |
6201 { | |
6202 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
6203 original_url, DEFAULT_PRIORITY, &d, NULL)); | |
6204 | |
6205 r->Start(); | |
6206 base::RunLoop().Run(); | |
6207 | |
6208 EXPECT_EQ(2U, r->url_chain().size()); | |
6209 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
6210 EXPECT_EQ(OK, r->status().error()); | |
6211 EXPECT_EQ(original_url, r->original_url()); | |
6212 EXPECT_EQ(expected_url, r->url()); | |
6213 } | |
6214 } | |
6215 | |
6216 TEST_F(URLRequestTestHTTP, RedirectPreserveFirstPartyURL) { | |
6217 ASSERT_TRUE(test_server_.Start()); | |
6218 | |
6219 GURL url(test_server_.GetURL("files/redirect302-to-echo")); | |
6220 GURL first_party_url("http://example.com"); | |
6221 | |
6222 TestDelegate d; | |
6223 { | |
6224 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
6225 url, DEFAULT_PRIORITY, &d, NULL)); | |
6226 r->set_first_party_for_cookies(first_party_url); | |
6227 | |
6228 r->Start(); | |
6229 base::RunLoop().Run(); | |
6230 | |
6231 EXPECT_EQ(2U, r->url_chain().size()); | |
6232 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
6233 EXPECT_EQ(OK, r->status().error()); | |
6234 EXPECT_EQ(first_party_url, r->first_party_for_cookies()); | |
6235 } | |
6236 } | |
6237 | |
6238 TEST_F(URLRequestTestHTTP, RedirectUpdateFirstPartyURL) { | |
6239 ASSERT_TRUE(test_server_.Start()); | |
6240 | |
6241 GURL url(test_server_.GetURL("files/redirect302-to-echo")); | |
6242 GURL original_first_party_url("http://example.com"); | |
6243 GURL expected_first_party_url(test_server_.GetURL("echo")); | |
6244 | |
6245 TestDelegate d; | |
6246 { | |
6247 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
6248 url, DEFAULT_PRIORITY, &d, NULL)); | |
6249 r->set_first_party_for_cookies(original_first_party_url); | |
6250 r->set_first_party_url_policy( | |
6251 URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT); | |
6252 | |
6253 r->Start(); | |
6254 base::RunLoop().Run(); | |
6255 | |
6256 EXPECT_EQ(2U, r->url_chain().size()); | |
6257 EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status()); | |
6258 EXPECT_EQ(OK, r->status().error()); | |
6259 EXPECT_EQ(expected_first_party_url, r->first_party_for_cookies()); | |
6260 } | |
6261 } | |
6262 | |
6263 TEST_F(URLRequestTestHTTP, InterceptPost302RedirectGet) { | |
6264 ASSERT_TRUE(test_server_.Start()); | |
6265 | |
6266 const char kData[] = "hello world"; | |
6267 | |
6268 TestDelegate d; | |
6269 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
6270 test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d, NULL)); | |
6271 req->set_method("POST"); | |
6272 req->set_upload(CreateSimpleUploadData(kData)); | |
6273 HttpRequestHeaders headers; | |
6274 headers.SetHeader(HttpRequestHeaders::kContentLength, | |
6275 base::UintToString(arraysize(kData) - 1)); | |
6276 req->SetExtraRequestHeaders(headers); | |
6277 | |
6278 URLRequestRedirectJob* job = new URLRequestRedirectJob( | |
6279 req.get(), &default_network_delegate_, test_server_.GetURL("echo"), | |
6280 URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason"); | |
6281 AddTestInterceptor()->set_main_intercept_job(job); | |
6282 | |
6283 req->Start(); | |
6284 base::RunLoop().Run(); | |
6285 EXPECT_EQ("GET", req->method()); | |
6286 } | |
6287 | |
6288 TEST_F(URLRequestTestHTTP, InterceptPost307RedirectPost) { | |
6289 ASSERT_TRUE(test_server_.Start()); | |
6290 | |
6291 const char kData[] = "hello world"; | |
6292 | |
6293 TestDelegate d; | |
6294 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
6295 test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d, NULL)); | |
6296 req->set_method("POST"); | |
6297 req->set_upload(CreateSimpleUploadData(kData)); | |
6298 HttpRequestHeaders headers; | |
6299 headers.SetHeader(HttpRequestHeaders::kContentLength, | |
6300 base::UintToString(arraysize(kData) - 1)); | |
6301 req->SetExtraRequestHeaders(headers); | |
6302 | |
6303 URLRequestRedirectJob* job = new URLRequestRedirectJob( | |
6304 req.get(), &default_network_delegate_, test_server_.GetURL("echo"), | |
6305 URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, | |
6306 "Very Good Reason"); | |
6307 AddTestInterceptor()->set_main_intercept_job(job); | |
6308 | |
6309 req->Start(); | |
6310 base::RunLoop().Run(); | |
6311 EXPECT_EQ("POST", req->method()); | |
6312 EXPECT_EQ(kData, d.data_received()); | |
6313 } | |
6314 | |
6315 // Check that default A-L header is sent. | |
6316 TEST_F(URLRequestTestHTTP, DefaultAcceptLanguage) { | |
6317 ASSERT_TRUE(test_server_.Start()); | |
6318 | |
6319 StaticHttpUserAgentSettings settings("en", std::string()); | |
6320 TestNetworkDelegate network_delegate; // Must outlive URLRequests. | |
6321 TestURLRequestContext context(true); | |
6322 context.set_network_delegate(&network_delegate); | |
6323 context.set_http_user_agent_settings(&settings); | |
6324 context.Init(); | |
6325 | |
6326 TestDelegate d; | |
6327 scoped_ptr<URLRequest> req(context.CreateRequest( | |
6328 test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d, | |
6329 NULL)); | |
6330 req->Start(); | |
6331 base::RunLoop().Run(); | |
6332 EXPECT_EQ("en", d.data_received()); | |
6333 } | |
6334 | |
6335 // Check that an empty A-L header is not sent. http://crbug.com/77365. | |
6336 TEST_F(URLRequestTestHTTP, EmptyAcceptLanguage) { | |
6337 ASSERT_TRUE(test_server_.Start()); | |
6338 | |
6339 std::string empty_string; // Avoid most vexing parse on line below. | |
6340 StaticHttpUserAgentSettings settings(empty_string, empty_string); | |
6341 TestNetworkDelegate network_delegate; // Must outlive URLRequests. | |
6342 TestURLRequestContext context(true); | |
6343 context.set_network_delegate(&network_delegate); | |
6344 context.Init(); | |
6345 // We override the language after initialization because empty entries | |
6346 // get overridden by Init(). | |
6347 context.set_http_user_agent_settings(&settings); | |
6348 | |
6349 TestDelegate d; | |
6350 scoped_ptr<URLRequest> req(context.CreateRequest( | |
6351 test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d, | |
6352 NULL)); | |
6353 req->Start(); | |
6354 base::RunLoop().Run(); | |
6355 EXPECT_EQ("None", d.data_received()); | |
6356 } | |
6357 | |
6358 // Check that if request overrides the A-L header, the default is not appended. | |
6359 // See http://crbug.com/20894 | |
6360 TEST_F(URLRequestTestHTTP, OverrideAcceptLanguage) { | |
6361 ASSERT_TRUE(test_server_.Start()); | |
6362 | |
6363 TestDelegate d; | |
6364 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
6365 test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d, | |
6366 NULL)); | |
6367 HttpRequestHeaders headers; | |
6368 headers.SetHeader(HttpRequestHeaders::kAcceptLanguage, "ru"); | |
6369 req->SetExtraRequestHeaders(headers); | |
6370 req->Start(); | |
6371 base::RunLoop().Run(); | |
6372 EXPECT_EQ(std::string("ru"), d.data_received()); | |
6373 } | |
6374 | |
6375 // Check that default A-E header is sent. | |
6376 TEST_F(URLRequestTestHTTP, DefaultAcceptEncoding) { | |
6377 ASSERT_TRUE(test_server_.Start()); | |
6378 | |
6379 TestDelegate d; | |
6380 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
6381 test_server_.GetURL("echoheader?Accept-Encoding"), DEFAULT_PRIORITY, &d, | |
6382 NULL)); | |
6383 HttpRequestHeaders headers; | |
6384 req->SetExtraRequestHeaders(headers); | |
6385 req->Start(); | |
6386 base::RunLoop().Run(); | |
6387 EXPECT_TRUE(ContainsString(d.data_received(), "gzip")); | |
6388 } | |
6389 | |
6390 // Check that if request overrides the A-E header, the default is not appended. | |
6391 // See http://crbug.com/47381 | |
6392 TEST_F(URLRequestTestHTTP, OverrideAcceptEncoding) { | |
6393 ASSERT_TRUE(test_server_.Start()); | |
6394 | |
6395 TestDelegate d; | |
6396 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
6397 test_server_.GetURL("echoheader?Accept-Encoding"), DEFAULT_PRIORITY, &d, | |
6398 NULL)); | |
6399 HttpRequestHeaders headers; | |
6400 headers.SetHeader(HttpRequestHeaders::kAcceptEncoding, "identity"); | |
6401 req->SetExtraRequestHeaders(headers); | |
6402 req->Start(); | |
6403 base::RunLoop().Run(); | |
6404 EXPECT_FALSE(ContainsString(d.data_received(), "gzip")); | |
6405 EXPECT_TRUE(ContainsString(d.data_received(), "identity")); | |
6406 } | |
6407 | |
6408 // Check that setting the A-C header sends the proper header. | |
6409 TEST_F(URLRequestTestHTTP, SetAcceptCharset) { | |
6410 ASSERT_TRUE(test_server_.Start()); | |
6411 | |
6412 TestDelegate d; | |
6413 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
6414 test_server_.GetURL("echoheader?Accept-Charset"), DEFAULT_PRIORITY, &d, | |
6415 NULL)); | |
6416 HttpRequestHeaders headers; | |
6417 headers.SetHeader(HttpRequestHeaders::kAcceptCharset, "koi-8r"); | |
6418 req->SetExtraRequestHeaders(headers); | |
6419 req->Start(); | |
6420 base::RunLoop().Run(); | |
6421 EXPECT_EQ(std::string("koi-8r"), d.data_received()); | |
6422 } | |
6423 | |
6424 // Check that default User-Agent header is sent. | |
6425 TEST_F(URLRequestTestHTTP, DefaultUserAgent) { | |
6426 ASSERT_TRUE(test_server_.Start()); | |
6427 | |
6428 TestDelegate d; | |
6429 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
6430 test_server_.GetURL("echoheader?User-Agent"), DEFAULT_PRIORITY, &d, | |
6431 NULL)); | |
6432 req->Start(); | |
6433 base::RunLoop().Run(); | |
6434 EXPECT_EQ(default_context_.http_user_agent_settings()->GetUserAgent(), | |
6435 d.data_received()); | |
6436 } | |
6437 | |
6438 // Check that if request overrides the User-Agent header, | |
6439 // the default is not appended. | |
6440 TEST_F(URLRequestTestHTTP, OverrideUserAgent) { | |
6441 ASSERT_TRUE(test_server_.Start()); | |
6442 | |
6443 TestDelegate d; | |
6444 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
6445 test_server_.GetURL("echoheader?User-Agent"), DEFAULT_PRIORITY, &d, | |
6446 NULL)); | |
6447 HttpRequestHeaders headers; | |
6448 headers.SetHeader(HttpRequestHeaders::kUserAgent, "Lynx (textmode)"); | |
6449 req->SetExtraRequestHeaders(headers); | |
6450 req->Start(); | |
6451 base::RunLoop().Run(); | |
6452 EXPECT_EQ(std::string("Lynx (textmode)"), d.data_received()); | |
6453 } | |
6454 | |
6455 // Check that a NULL HttpUserAgentSettings causes the corresponding empty | |
6456 // User-Agent header to be sent but does not send the Accept-Language and | |
6457 // Accept-Charset headers. | |
6458 TEST_F(URLRequestTestHTTP, EmptyHttpUserAgentSettings) { | |
6459 ASSERT_TRUE(test_server_.Start()); | |
6460 | |
6461 TestNetworkDelegate network_delegate; // Must outlive URLRequests. | |
6462 TestURLRequestContext context(true); | |
6463 context.set_network_delegate(&network_delegate); | |
6464 context.Init(); | |
6465 // We override the HttpUserAgentSettings after initialization because empty | |
6466 // entries get overridden by Init(). | |
6467 context.set_http_user_agent_settings(NULL); | |
6468 | |
6469 struct { | |
6470 const char* request; | |
6471 const char* expected_response; | |
6472 } tests[] = { { "echoheader?Accept-Language", "None" }, | |
6473 { "echoheader?Accept-Charset", "None" }, | |
6474 { "echoheader?User-Agent", "" } }; | |
6475 | |
6476 for (size_t i = 0; i < arraysize(tests); i++) { | |
6477 TestDelegate d; | |
6478 scoped_ptr<URLRequest> req(context.CreateRequest( | |
6479 test_server_.GetURL(tests[i].request), DEFAULT_PRIORITY, &d, NULL)); | |
6480 req->Start(); | |
6481 base::RunLoop().Run(); | |
6482 EXPECT_EQ(tests[i].expected_response, d.data_received()) | |
6483 << " Request = \"" << tests[i].request << "\""; | |
6484 } | |
6485 } | |
6486 | |
6487 // Make sure that URLRequest passes on its priority updates to | |
6488 // newly-created jobs after the first one. | |
6489 TEST_F(URLRequestTestHTTP, SetSubsequentJobPriority) { | |
6490 ASSERT_TRUE(test_server_.Start()); | |
6491 | |
6492 TestDelegate d; | |
6493 scoped_ptr<URLRequest> req(default_context_.CreateRequest( | |
6494 test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d, NULL)); | |
6495 EXPECT_EQ(DEFAULT_PRIORITY, req->priority()); | |
6496 | |
6497 scoped_refptr<URLRequestRedirectJob> redirect_job = | |
6498 new URLRequestRedirectJob( | |
6499 req.get(), &default_network_delegate_, test_server_.GetURL("echo"), | |
6500 URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason"); | |
6501 AddTestInterceptor()->set_main_intercept_job(redirect_job.get()); | |
6502 | |
6503 req->SetPriority(LOW); | |
6504 req->Start(); | |
6505 EXPECT_TRUE(req->is_pending()); | |
6506 | |
6507 scoped_refptr<URLRequestTestJob> job = | |
6508 new URLRequestTestJob(req.get(), &default_network_delegate_); | |
6509 AddTestInterceptor()->set_main_intercept_job(job.get()); | |
6510 | |
6511 // Should trigger |job| to be started. | |
6512 base::RunLoop().Run(); | |
6513 EXPECT_EQ(LOW, job->priority()); | |
6514 } | |
6515 | |
6516 // Check that creating a network request while entering/exiting suspend mode | |
6517 // fails as it should. This is the only case where an HttpTransactionFactory | |
6518 // does not return an HttpTransaction. | |
6519 TEST_F(URLRequestTestHTTP, NetworkSuspendTest) { | |
6520 // Create a new HttpNetworkLayer that thinks it's suspended. | |
6521 HttpNetworkSession::Params params; | |
6522 params.host_resolver = default_context_.host_resolver(); | |
6523 params.cert_verifier = default_context_.cert_verifier(); | |
6524 params.transport_security_state = default_context_.transport_security_state(); | |
6525 params.proxy_service = default_context_.proxy_service(); | |
6526 params.ssl_config_service = default_context_.ssl_config_service(); | |
6527 params.http_auth_handler_factory = | |
6528 default_context_.http_auth_handler_factory(); | |
6529 params.network_delegate = &default_network_delegate_; | |
6530 params.http_server_properties = default_context_.http_server_properties(); | |
6531 scoped_ptr<HttpNetworkLayer> network_layer( | |
6532 new HttpNetworkLayer(new HttpNetworkSession(params))); | |
6533 network_layer->OnSuspend(); | |
6534 | |
6535 HttpCache http_cache(network_layer.release(), default_context_.net_log(), | |
6536 HttpCache::DefaultBackend::InMemory(0)); | |
6537 | |
6538 TestURLRequestContext context(true); | |
6539 context.set_http_transaction_factory(&http_cache); | |
6540 context.Init(); | |
6541 | |
6542 TestDelegate d; | |
6543 scoped_ptr<URLRequest> req(context.CreateRequest( | |
6544 GURL("http://127.0.0.1/"), DEFAULT_PRIORITY, &d, NULL)); | |
6545 req->Start(); | |
6546 base::RunLoop().Run(); | |
6547 | |
6548 EXPECT_TRUE(d.request_failed()); | |
6549 EXPECT_EQ(URLRequestStatus::FAILED, req->status().status()); | |
6550 EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, req->status().error()); | |
6551 } | |
6552 | |
6553 // Check that creating a network request while entering/exiting suspend mode | |
6554 // fails as it should in the case there is no cache. This is the only case | |
6555 // where an HttpTransactionFactory does not return an HttpTransaction. | |
6556 TEST_F(URLRequestTestHTTP, NetworkSuspendTestNoCache) { | |
6557 // Create a new HttpNetworkLayer that thinks it's suspended. | |
6558 HttpNetworkSession::Params params; | |
6559 params.host_resolver = default_context_.host_resolver(); | |
6560 params.cert_verifier = default_context_.cert_verifier(); | |
6561 params.transport_security_state = default_context_.transport_security_state(); | |
6562 params.proxy_service = default_context_.proxy_service(); | |
6563 params.ssl_config_service = default_context_.ssl_config_service(); | |
6564 params.http_auth_handler_factory = | |
6565 default_context_.http_auth_handler_factory(); | |
6566 params.network_delegate = &default_network_delegate_; | |
6567 params.http_server_properties = default_context_.http_server_properties(); | |
6568 HttpNetworkLayer network_layer(new HttpNetworkSession(params)); | |
6569 network_layer.OnSuspend(); | |
6570 | |
6571 TestURLRequestContext context(true); | |
6572 context.set_http_transaction_factory(&network_layer); | |
6573 context.Init(); | |
6574 | |
6575 TestDelegate d; | |
6576 scoped_ptr<URLRequest> req(context.CreateRequest( | |
6577 GURL("http://127.0.0.1/"), DEFAULT_PRIORITY, &d, NULL)); | |
6578 req->Start(); | |
6579 base::RunLoop().Run(); | |
6580 | |
6581 EXPECT_TRUE(d.request_failed()); | |
6582 EXPECT_EQ(URLRequestStatus::FAILED, req->status().status()); | |
6583 EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, req->status().error()); | |
6584 } | |
6585 | |
6586 class URLRequestInterceptorTestHTTP : public URLRequestTestHTTP { | |
6587 public: | |
6588 // TODO(bengr): Merge this with the URLRequestInterceptorHTTPTest fixture, | |
6589 // ideally remove the dependency on URLRequestTestJob, and maybe move these | |
6590 // tests into the factory tests. | |
6591 URLRequestInterceptorTestHTTP() : URLRequestTestHTTP(), interceptor_(NULL) { | |
6592 } | |
6593 | |
6594 void SetUpFactory() override { | |
6595 interceptor_ = new MockURLRequestInterceptor(); | |
6596 job_factory_.reset(new URLRequestInterceptingJobFactory( | |
6597 job_factory_.Pass(), make_scoped_ptr(interceptor_))); | |
6598 } | |
6599 | |
6600 MockURLRequestInterceptor* interceptor() const { | |
6601 return interceptor_; | |
6602 } | |
6603 | |
6604 private: | |
6605 MockURLRequestInterceptor* interceptor_; | |
6606 }; | |
6607 | |
6608 TEST_F(URLRequestInterceptorTestHTTP, | |
6609 NetworkDelegateNotificationOnRedirectIntercept) { | |
6610 interceptor()->set_intercept_redirect(true); | |
6611 interceptor()->set_redirect_headers(MockURLRequestInterceptor::ok_headers()); | |
6612 interceptor()->set_redirect_data(MockURLRequestInterceptor::ok_data()); | |
6613 | |
6614 ASSERT_TRUE(test_server()->Start()); | |
6615 | |
6616 TestDelegate d; | |
6617 scoped_ptr<URLRequest> req(default_context().CreateRequest( | |
6618 test_server()->GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, | |
6619 &d, nullptr)); | |
6620 req->Start(); | |
6621 base::RunLoop().Run(); | |
6622 | |
6623 EXPECT_TRUE(interceptor()->did_intercept_redirect()); | |
6624 // Check we got one good response | |
6625 EXPECT_TRUE(req->status().is_success()); | |
6626 if (req->status().is_success()) | |
6627 EXPECT_EQ(200, req->response_headers()->response_code()); | |
6628 | |
6629 EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); | |
6630 EXPECT_EQ(1, d.response_started_count()); | |
6631 EXPECT_EQ(0, d.received_redirect_count()); | |
6632 | |
6633 EXPECT_EQ(1, default_network_delegate()->created_requests()); | |
6634 EXPECT_EQ(1, default_network_delegate()->before_send_headers_count()); | |
6635 EXPECT_EQ(1, default_network_delegate()->headers_received_count()); | |
6636 } | |
6637 | |
6638 TEST_F(URLRequestInterceptorTestHTTP, | |
6639 NetworkDelegateNotificationOnErrorIntercept) { | |
6640 // Intercept that error and respond with an OK response. | |
6641 interceptor()->set_intercept_final_response(true); | |
6642 interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers()); | |
6643 interceptor()->set_final_data(MockURLRequestInterceptor::ok_data()); | |
6644 default_network_delegate()->set_can_be_intercepted_on_error(true); | |
6645 | |
6646 ASSERT_TRUE(test_server()->Start()); | |
6647 | |
6648 TestDelegate d; | |
6649 scoped_ptr<URLRequest> req(default_context().CreateRequest( | |
6650 test_server()->GetURL("files/two-content-lengths.html"), DEFAULT_PRIORITY, | |
6651 &d, nullptr)); | |
6652 req->set_method("GET"); | |
6653 req->Start(); | |
6654 base::RunLoop().Run(); | |
6655 | |
6656 EXPECT_TRUE(interceptor()->did_intercept_final()); | |
6657 | |
6658 // Check we received one good response. | |
6659 EXPECT_TRUE(req->status().is_success()); | |
6660 if (req->status().is_success()) | |
6661 EXPECT_EQ(200, req->response_headers()->response_code()); | |
6662 EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received()); | |
6663 EXPECT_EQ(1, d.response_started_count()); | |
6664 EXPECT_EQ(0, d.received_redirect_count()); | |
6665 | |
6666 EXPECT_EQ(1, default_network_delegate()->created_requests()); | |
6667 EXPECT_EQ(1, default_network_delegate()->before_send_headers_count()); | |
6668 EXPECT_EQ(0, default_network_delegate()->headers_received_count()); | |
6669 } | |
6670 | |
6671 TEST_F(URLRequestInterceptorTestHTTP, | |
6672 NetworkDelegateNotificationOnResponseIntercept) { | |
6673 // Intercept that error and respond with an OK response. | |
6674 interceptor()->set_intercept_final_response(true); | |
6675 | |
6676 // Intercept with a real URLRequestHttpJob. | |
6677 interceptor()->set_use_url_request_http_job(true); | |
6678 | |
6679 ASSERT_TRUE(test_server()->Start()); | |
6680 | |
6681 TestDelegate d; | |
6682 scoped_ptr<URLRequest> req(default_context().CreateRequest( | |
6683 test_server()->GetURL("files/simple.html"), DEFAULT_PRIORITY, | |
6684 &d, nullptr)); | |
6685 req->set_method("GET"); | |
6686 req->Start(); | |
6687 base::RunLoop().Run(); | |
6688 | |
6689 EXPECT_TRUE(interceptor()->did_intercept_final()); | |
6690 | |
6691 // Check we received one good response. | |
6692 EXPECT_TRUE(req->status().is_success()); | |
6693 if (req->status().is_success()) | |
6694 EXPECT_EQ(200, req->response_headers()->response_code()); | |
6695 EXPECT_EQ("hello", d.data_received()); | |
6696 EXPECT_EQ(1, d.response_started_count()); | |
6697 EXPECT_EQ(0, d.received_redirect_count()); | |
6698 | |
6699 EXPECT_EQ(1, default_network_delegate()->created_requests()); | |
6700 EXPECT_EQ(2, default_network_delegate()->before_send_headers_count()); | |
6701 EXPECT_EQ(2, default_network_delegate()->headers_received_count()); | |
6702 } | |
6703 | |
6704 class URLRequestTestReferrerPolicy : public URLRequestTest { | |
6705 public: | |
6706 URLRequestTestReferrerPolicy() {} | |
6707 | |
6708 void InstantiateSameOriginServers(SpawnedTestServer::Type origin_type) { | |
6709 origin_server_.reset(new SpawnedTestServer( | |
6710 origin_type, SpawnedTestServer::kLocalhost, | |
6711 origin_type == SpawnedTestServer::TYPE_HTTPS | |
6712 ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl")) | |
6713 : base::FilePath( | |
6714 FILE_PATH_LITERAL("net/data/url_request_unittest")))); | |
6715 ASSERT_TRUE(origin_server_->Start()); | |
6716 } | |
6717 | |
6718 void InstantiateCrossOriginServers(SpawnedTestServer::Type origin_type, | |
6719 SpawnedTestServer::Type destination_type) { | |
6720 origin_server_.reset(new SpawnedTestServer( | |
6721 origin_type, SpawnedTestServer::kLocalhost, | |
6722 origin_type == SpawnedTestServer::TYPE_HTTPS | |
6723 ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl")) | |
6724 : base::FilePath( | |
6725 FILE_PATH_LITERAL("net/data/url_request_unittest")))); | |
6726 ASSERT_TRUE(origin_server_->Start()); | |
6727 | |
6728 destination_server_.reset(new SpawnedTestServer( | |
6729 destination_type, SpawnedTestServer::kLocalhost, | |
6730 destination_type == SpawnedTestServer::TYPE_HTTPS | |
6731 ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl")) | |
6732 : base::FilePath( | |
6733 FILE_PATH_LITERAL("net/data/url_request_unittest")))); | |
6734 ASSERT_TRUE(destination_server_->Start()); | |
6735 } | |
6736 | |
6737 void VerifyReferrerAfterRedirect(URLRequest::ReferrerPolicy policy, | |
6738 const GURL& referrer, | |
6739 const GURL& expected) { | |
6740 // Create and execute the request: we'll only have a |destination_server_| | |
6741 // if the origins are meant to be distinct. Otherwise, we'll use the | |
6742 // |origin_server_| for both endpoints. | |
6743 GURL destination_url = | |
6744 destination_server_ ? destination_server_->GetURL("echoheader?Referer") | |
6745 : origin_server_->GetURL("echoheader?Referer"); | |
6746 GURL origin_url = | |
6747 origin_server_->GetURL("server-redirect?" + destination_url.spec()); | |
6748 | |
6749 TestDelegate d; | |
6750 scoped_ptr<URLRequest> req( | |
6751 default_context_.CreateRequest(origin_url, DEFAULT_PRIORITY, &d, NULL)); | |
6752 req->set_referrer_policy(policy); | |
6753 req->SetReferrer(referrer.spec()); | |
6754 req->Start(); | |
6755 base::RunLoop().Run(); | |
6756 | |
6757 EXPECT_EQ(1, d.response_started_count()); | |
6758 EXPECT_EQ(1, d.received_redirect_count()); | |
6759 EXPECT_EQ(destination_url, req->url()); | |
6760 EXPECT_TRUE(req->status().is_success()); | |
6761 EXPECT_EQ(200, req->response_headers()->response_code()); | |
6762 | |
6763 EXPECT_EQ(expected.spec(), req->referrer()); | |
6764 if (expected.is_empty()) | |
6765 EXPECT_EQ("None", d.data_received()); | |
6766 else | |
6767 EXPECT_EQ(expected.spec(), d.data_received()); | |
6768 } | |
6769 | |
6770 SpawnedTestServer* origin_server() const { return origin_server_.get(); } | |
6771 | |
6772 private: | |
6773 scoped_ptr<SpawnedTestServer> origin_server_; | |
6774 scoped_ptr<SpawnedTestServer> destination_server_; | |
6775 }; | |
6776 | |
6777 TEST_F(URLRequestTestReferrerPolicy, HTTPToSameOriginHTTP) { | |
6778 InstantiateSameOriginServers(SpawnedTestServer::TYPE_HTTP); | |
6779 | |
6780 VerifyReferrerAfterRedirect( | |
6781 URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, | |
6782 origin_server()->GetURL("path/to/file.html"), | |
6783 origin_server()->GetURL("path/to/file.html")); | |
6784 | |
6785 VerifyReferrerAfterRedirect( | |
6786 URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, | |
6787 origin_server()->GetURL("path/to/file.html"), | |
6788 origin_server()->GetURL("path/to/file.html")); | |
6789 | |
6790 VerifyReferrerAfterRedirect( | |
6791 URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, | |
6792 origin_server()->GetURL("path/to/file.html"), | |
6793 origin_server()->GetURL("path/to/file.html")); | |
6794 | |
6795 VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, | |
6796 origin_server()->GetURL("path/to/file.html"), | |
6797 origin_server()->GetURL("path/to/file.html")); | |
6798 } | |
6799 | |
6800 TEST_F(URLRequestTestReferrerPolicy, HTTPToCrossOriginHTTP) { | |
6801 InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTP, | |
6802 SpawnedTestServer::TYPE_HTTP); | |
6803 | |
6804 VerifyReferrerAfterRedirect( | |
6805 URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, | |
6806 origin_server()->GetURL("path/to/file.html"), | |
6807 origin_server()->GetURL("path/to/file.html")); | |
6808 | |
6809 VerifyReferrerAfterRedirect( | |
6810 URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, | |
6811 origin_server()->GetURL("path/to/file.html"), | |
6812 origin_server()->GetURL(std::string())); | |
6813 | |
6814 VerifyReferrerAfterRedirect( | |
6815 URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, | |
6816 origin_server()->GetURL("path/to/file.html"), | |
6817 origin_server()->GetURL(std::string())); | |
6818 | |
6819 VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, | |
6820 origin_server()->GetURL("path/to/file.html"), | |
6821 origin_server()->GetURL("path/to/file.html")); | |
6822 } | |
6823 | |
6824 TEST_F(URLRequestTestReferrerPolicy, HTTPSToSameOriginHTTPS) { | |
6825 InstantiateSameOriginServers(SpawnedTestServer::TYPE_HTTPS); | |
6826 | |
6827 VerifyReferrerAfterRedirect( | |
6828 URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, | |
6829 origin_server()->GetURL("path/to/file.html"), | |
6830 origin_server()->GetURL("path/to/file.html")); | |
6831 | |
6832 VerifyReferrerAfterRedirect( | |
6833 URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, | |
6834 origin_server()->GetURL("path/to/file.html"), | |
6835 origin_server()->GetURL("path/to/file.html")); | |
6836 | |
6837 VerifyReferrerAfterRedirect( | |
6838 URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, | |
6839 origin_server()->GetURL("path/to/file.html"), | |
6840 origin_server()->GetURL("path/to/file.html")); | |
6841 | |
6842 VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, | |
6843 origin_server()->GetURL("path/to/file.html"), | |
6844 origin_server()->GetURL("path/to/file.html")); | |
6845 } | |
6846 | |
6847 TEST_F(URLRequestTestReferrerPolicy, HTTPSToCrossOriginHTTPS) { | |
6848 InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTPS, | |
6849 SpawnedTestServer::TYPE_HTTPS); | |
6850 | |
6851 VerifyReferrerAfterRedirect( | |
6852 URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, | |
6853 origin_server()->GetURL("path/to/file.html"), | |
6854 origin_server()->GetURL("path/to/file.html")); | |
6855 | |
6856 VerifyReferrerAfterRedirect( | |
6857 URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, | |
6858 origin_server()->GetURL("path/to/file.html"), | |
6859 origin_server()->GetURL(std::string())); | |
6860 | |
6861 VerifyReferrerAfterRedirect( | |
6862 URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, | |
6863 origin_server()->GetURL("path/to/file.html"), | |
6864 origin_server()->GetURL(std::string())); | |
6865 | |
6866 VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, | |
6867 origin_server()->GetURL("path/to/file.html"), | |
6868 origin_server()->GetURL("path/to/file.html")); | |
6869 } | |
6870 | |
6871 TEST_F(URLRequestTestReferrerPolicy, HTTPToHTTPS) { | |
6872 InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTP, | |
6873 SpawnedTestServer::TYPE_HTTPS); | |
6874 | |
6875 VerifyReferrerAfterRedirect( | |
6876 URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, | |
6877 origin_server()->GetURL("path/to/file.html"), | |
6878 origin_server()->GetURL("path/to/file.html")); | |
6879 | |
6880 VerifyReferrerAfterRedirect( | |
6881 URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, | |
6882 origin_server()->GetURL("path/to/file.html"), | |
6883 origin_server()->GetURL(std::string())); | |
6884 | |
6885 VerifyReferrerAfterRedirect( | |
6886 URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, | |
6887 origin_server()->GetURL("path/to/file.html"), | |
6888 origin_server()->GetURL(std::string())); | |
6889 | |
6890 VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, | |
6891 origin_server()->GetURL("path/to/file.html"), | |
6892 origin_server()->GetURL("path/to/file.html")); | |
6893 } | |
6894 | |
6895 TEST_F(URLRequestTestReferrerPolicy, HTTPSToHTTP) { | |
6896 InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTPS, | |
6897 SpawnedTestServer::TYPE_HTTP); | |
6898 | |
6899 VerifyReferrerAfterRedirect( | |
6900 URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, | |
6901 origin_server()->GetURL("path/to/file.html"), GURL()); | |
6902 | |
6903 VerifyReferrerAfterRedirect( | |
6904 URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN, | |
6905 origin_server()->GetURL("path/to/file.html"), GURL()); | |
6906 | |
6907 VerifyReferrerAfterRedirect( | |
6908 URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN, | |
6909 origin_server()->GetURL("path/to/file.html"), | |
6910 origin_server()->GetURL(std::string())); | |
6911 | |
6912 VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER, | |
6913 origin_server()->GetURL("path/to/file.html"), | |
6914 origin_server()->GetURL("path/to/file.html")); | |
6915 } | |
6916 | |
6917 class HTTPSRequestTest : public testing::Test { | |
6918 public: | |
6919 HTTPSRequestTest() : default_context_(true) { | |
6920 default_context_.set_network_delegate(&default_network_delegate_); | |
6921 default_context_.Init(); | |
6922 } | |
6923 ~HTTPSRequestTest() override {} | |
6924 | |
6925 protected: | |
6926 TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest. | |
6927 TestURLRequestContext default_context_; | |
6928 }; | |
6929 | |
6930 TEST_F(HTTPSRequestTest, HTTPSGetTest) { | |
6931 SpawnedTestServer test_server( | |
6932 SpawnedTestServer::TYPE_HTTPS, | |
6933 SpawnedTestServer::kLocalhost, | |
6934 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
6935 ASSERT_TRUE(test_server.Start()); | |
6936 | |
6937 TestDelegate d; | |
6938 { | |
6939 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
6940 test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
6941 r->Start(); | |
6942 EXPECT_TRUE(r->is_pending()); | |
6943 | |
6944 base::RunLoop().Run(); | |
6945 | |
6946 EXPECT_EQ(1, d.response_started_count()); | |
6947 EXPECT_FALSE(d.received_data_before_response()); | |
6948 EXPECT_NE(0, d.bytes_received()); | |
6949 CheckSSLInfo(r->ssl_info()); | |
6950 EXPECT_EQ(test_server.host_port_pair().host(), | |
6951 r->GetSocketAddress().host()); | |
6952 EXPECT_EQ(test_server.host_port_pair().port(), | |
6953 r->GetSocketAddress().port()); | |
6954 } | |
6955 } | |
6956 | |
6957 TEST_F(HTTPSRequestTest, HTTPSMismatchedTest) { | |
6958 SpawnedTestServer::SSLOptions ssl_options( | |
6959 SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME); | |
6960 SpawnedTestServer test_server( | |
6961 SpawnedTestServer::TYPE_HTTPS, | |
6962 ssl_options, | |
6963 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
6964 ASSERT_TRUE(test_server.Start()); | |
6965 | |
6966 bool err_allowed = true; | |
6967 for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) { | |
6968 TestDelegate d; | |
6969 { | |
6970 d.set_allow_certificate_errors(err_allowed); | |
6971 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
6972 test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
6973 | |
6974 r->Start(); | |
6975 EXPECT_TRUE(r->is_pending()); | |
6976 | |
6977 base::RunLoop().Run(); | |
6978 | |
6979 EXPECT_EQ(1, d.response_started_count()); | |
6980 EXPECT_FALSE(d.received_data_before_response()); | |
6981 EXPECT_TRUE(d.have_certificate_errors()); | |
6982 if (err_allowed) { | |
6983 EXPECT_NE(0, d.bytes_received()); | |
6984 CheckSSLInfo(r->ssl_info()); | |
6985 } else { | |
6986 EXPECT_EQ(0, d.bytes_received()); | |
6987 } | |
6988 } | |
6989 } | |
6990 } | |
6991 | |
6992 TEST_F(HTTPSRequestTest, HTTPSExpiredTest) { | |
6993 SpawnedTestServer::SSLOptions ssl_options( | |
6994 SpawnedTestServer::SSLOptions::CERT_EXPIRED); | |
6995 SpawnedTestServer test_server( | |
6996 SpawnedTestServer::TYPE_HTTPS, | |
6997 ssl_options, | |
6998 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
6999 ASSERT_TRUE(test_server.Start()); | |
7000 | |
7001 // Iterate from false to true, just so that we do the opposite of the | |
7002 // previous test in order to increase test coverage. | |
7003 bool err_allowed = false; | |
7004 for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) { | |
7005 TestDelegate d; | |
7006 { | |
7007 d.set_allow_certificate_errors(err_allowed); | |
7008 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
7009 test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
7010 | |
7011 r->Start(); | |
7012 EXPECT_TRUE(r->is_pending()); | |
7013 | |
7014 base::RunLoop().Run(); | |
7015 | |
7016 EXPECT_EQ(1, d.response_started_count()); | |
7017 EXPECT_FALSE(d.received_data_before_response()); | |
7018 EXPECT_TRUE(d.have_certificate_errors()); | |
7019 if (err_allowed) { | |
7020 EXPECT_NE(0, d.bytes_received()); | |
7021 CheckSSLInfo(r->ssl_info()); | |
7022 } else { | |
7023 EXPECT_EQ(0, d.bytes_received()); | |
7024 } | |
7025 } | |
7026 } | |
7027 } | |
7028 | |
7029 // This tests that a load of www.google.com with a certificate error sets | |
7030 // the |certificate_errors_are_fatal| flag correctly. This flag will cause | |
7031 // the interstitial to be fatal. | |
7032 TEST_F(HTTPSRequestTest, HTTPSPreloadedHSTSTest) { | |
7033 SpawnedTestServer::SSLOptions ssl_options( | |
7034 SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME); | |
7035 SpawnedTestServer test_server( | |
7036 SpawnedTestServer::TYPE_HTTPS, | |
7037 ssl_options, | |
7038 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
7039 ASSERT_TRUE(test_server.Start()); | |
7040 | |
7041 // We require that the URL be www.google.com in order to pick up the | |
7042 // preloaded HSTS entries in the TransportSecurityState. This means that we | |
7043 // have to use a MockHostResolver in order to direct www.google.com to the | |
7044 // testserver. By default, MockHostResolver maps all hosts to 127.0.0.1. | |
7045 | |
7046 MockHostResolver host_resolver; | |
7047 TestNetworkDelegate network_delegate; // Must outlive URLRequest. | |
7048 TestURLRequestContext context(true); | |
7049 context.set_network_delegate(&network_delegate); | |
7050 context.set_host_resolver(&host_resolver); | |
7051 TransportSecurityState transport_security_state; | |
7052 context.set_transport_security_state(&transport_security_state); | |
7053 context.Init(); | |
7054 | |
7055 TestDelegate d; | |
7056 scoped_ptr<URLRequest> r(context.CreateRequest( | |
7057 GURL(base::StringPrintf("https://www.google.com:%d", | |
7058 test_server.host_port_pair().port())), | |
7059 DEFAULT_PRIORITY, &d, NULL)); | |
7060 | |
7061 r->Start(); | |
7062 EXPECT_TRUE(r->is_pending()); | |
7063 | |
7064 base::RunLoop().Run(); | |
7065 | |
7066 EXPECT_EQ(1, d.response_started_count()); | |
7067 EXPECT_FALSE(d.received_data_before_response()); | |
7068 EXPECT_TRUE(d.have_certificate_errors()); | |
7069 EXPECT_TRUE(d.certificate_errors_are_fatal()); | |
7070 } | |
7071 | |
7072 // This tests that cached HTTPS page loads do not cause any updates to the | |
7073 // TransportSecurityState. | |
7074 TEST_F(HTTPSRequestTest, HTTPSErrorsNoClobberTSSTest) { | |
7075 // The actual problem -- CERT_MISMATCHED_NAME in this case -- doesn't | |
7076 // matter. It just has to be any error. | |
7077 SpawnedTestServer::SSLOptions ssl_options( | |
7078 SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME); | |
7079 SpawnedTestServer test_server( | |
7080 SpawnedTestServer::TYPE_HTTPS, | |
7081 ssl_options, | |
7082 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
7083 ASSERT_TRUE(test_server.Start()); | |
7084 | |
7085 // We require that the URL be www.google.com in order to pick up the static | |
7086 // and dynamic STS and PKP entries in the TransportSecurityState. This means | |
7087 // that we have to use a MockHostResolver in order to direct www.google.com to | |
7088 // the testserver. By default, MockHostResolver maps all hosts to 127.0.0.1. | |
7089 | |
7090 MockHostResolver host_resolver; | |
7091 TestNetworkDelegate network_delegate; // Must outlive URLRequest. | |
7092 TestURLRequestContext context(true); | |
7093 context.set_network_delegate(&network_delegate); | |
7094 context.set_host_resolver(&host_resolver); | |
7095 TransportSecurityState transport_security_state; | |
7096 | |
7097 TransportSecurityState::DomainState static_domain_state; | |
7098 EXPECT_TRUE(transport_security_state.GetStaticDomainState( | |
7099 "www.google.com", &static_domain_state)); | |
7100 context.set_transport_security_state(&transport_security_state); | |
7101 context.Init(); | |
7102 | |
7103 TransportSecurityState::DomainState dynamic_domain_state; | |
7104 EXPECT_FALSE(transport_security_state.GetDynamicDomainState( | |
7105 "www.google.com", &dynamic_domain_state)); | |
7106 | |
7107 TestDelegate d; | |
7108 scoped_ptr<URLRequest> r(context.CreateRequest( | |
7109 GURL(base::StringPrintf("https://www.google.com:%d", | |
7110 test_server.host_port_pair().port())), | |
7111 DEFAULT_PRIORITY, &d, NULL)); | |
7112 | |
7113 r->Start(); | |
7114 EXPECT_TRUE(r->is_pending()); | |
7115 | |
7116 base::RunLoop().Run(); | |
7117 | |
7118 EXPECT_EQ(1, d.response_started_count()); | |
7119 EXPECT_FALSE(d.received_data_before_response()); | |
7120 EXPECT_TRUE(d.have_certificate_errors()); | |
7121 EXPECT_TRUE(d.certificate_errors_are_fatal()); | |
7122 | |
7123 // Get a fresh copy of the states, and check that they haven't changed. | |
7124 TransportSecurityState::DomainState new_static_domain_state; | |
7125 EXPECT_TRUE(transport_security_state.GetStaticDomainState( | |
7126 "www.google.com", &new_static_domain_state)); | |
7127 TransportSecurityState::DomainState new_dynamic_domain_state; | |
7128 EXPECT_FALSE(transport_security_state.GetDynamicDomainState( | |
7129 "www.google.com", &new_dynamic_domain_state)); | |
7130 | |
7131 EXPECT_EQ(new_static_domain_state.sts.upgrade_mode, | |
7132 static_domain_state.sts.upgrade_mode); | |
7133 EXPECT_EQ(new_static_domain_state.sts.include_subdomains, | |
7134 static_domain_state.sts.include_subdomains); | |
7135 EXPECT_EQ(new_static_domain_state.pkp.include_subdomains, | |
7136 static_domain_state.pkp.include_subdomains); | |
7137 EXPECT_TRUE(FingerprintsEqual(new_static_domain_state.pkp.spki_hashes, | |
7138 static_domain_state.pkp.spki_hashes)); | |
7139 EXPECT_TRUE(FingerprintsEqual(new_static_domain_state.pkp.bad_spki_hashes, | |
7140 static_domain_state.pkp.bad_spki_hashes)); | |
7141 } | |
7142 | |
7143 // Make sure HSTS preserves a POST request's method and body. | |
7144 TEST_F(HTTPSRequestTest, HSTSPreservesPosts) { | |
7145 static const char kData[] = "hello world"; | |
7146 | |
7147 SpawnedTestServer::SSLOptions ssl_options( | |
7148 SpawnedTestServer::SSLOptions::CERT_OK); | |
7149 SpawnedTestServer test_server( | |
7150 SpawnedTestServer::TYPE_HTTPS, | |
7151 ssl_options, | |
7152 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
7153 ASSERT_TRUE(test_server.Start()); | |
7154 | |
7155 | |
7156 // Per spec, TransportSecurityState expects a domain name, rather than an IP | |
7157 // address, so a MockHostResolver is needed to redirect www.somewhere.com to | |
7158 // the SpawnedTestServer. By default, MockHostResolver maps all hosts | |
7159 // to 127.0.0.1. | |
7160 MockHostResolver host_resolver; | |
7161 | |
7162 // Force https for www.somewhere.com. | |
7163 TransportSecurityState transport_security_state; | |
7164 base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1000); | |
7165 bool include_subdomains = false; | |
7166 transport_security_state.AddHSTS("www.somewhere.com", expiry, | |
7167 include_subdomains); | |
7168 | |
7169 TestNetworkDelegate network_delegate; // Must outlive URLRequest. | |
7170 | |
7171 TestURLRequestContext context(true); | |
7172 context.set_host_resolver(&host_resolver); | |
7173 context.set_transport_security_state(&transport_security_state); | |
7174 context.set_network_delegate(&network_delegate); | |
7175 context.Init(); | |
7176 | |
7177 TestDelegate d; | |
7178 // Navigating to https://www.somewhere.com instead of https://127.0.0.1 will | |
7179 // cause a certificate error. Ignore the error. | |
7180 d.set_allow_certificate_errors(true); | |
7181 | |
7182 scoped_ptr<URLRequest> req(context.CreateRequest( | |
7183 GURL(base::StringPrintf("http://www.somewhere.com:%d/echo", | |
7184 test_server.host_port_pair().port())), | |
7185 DEFAULT_PRIORITY, &d, NULL)); | |
7186 req->set_method("POST"); | |
7187 req->set_upload(CreateSimpleUploadData(kData)); | |
7188 | |
7189 req->Start(); | |
7190 base::RunLoop().Run(); | |
7191 | |
7192 EXPECT_EQ("https", req->url().scheme()); | |
7193 EXPECT_EQ("POST", req->method()); | |
7194 EXPECT_EQ(kData, d.data_received()); | |
7195 | |
7196 LoadTimingInfo load_timing_info; | |
7197 network_delegate.GetLoadTimingInfoBeforeRedirect(&load_timing_info); | |
7198 // LoadTimingInfo of HSTS redirects is similar to that of network cache hits | |
7199 TestLoadTimingCacheHitNoNetwork(load_timing_info); | |
7200 } | |
7201 | |
7202 // Make sure that the CORS headers are added to cross-origin HSTS redirects. | |
7203 TEST_F(HTTPSRequestTest, HSTSCrossOriginAddHeaders) { | |
7204 static const char kOriginHeaderValue[] = "http://www.example.com"; | |
7205 | |
7206 SpawnedTestServer::SSLOptions ssl_options( | |
7207 SpawnedTestServer::SSLOptions::CERT_OK); | |
7208 SpawnedTestServer test_server( | |
7209 SpawnedTestServer::TYPE_HTTPS, | |
7210 ssl_options, | |
7211 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
7212 ASSERT_TRUE(test_server.Start()); | |
7213 | |
7214 // Per spec, TransportSecurityState expects a domain name, rather than an IP | |
7215 // address, so a MockHostResolver is needed to redirect example.net to the | |
7216 // SpawnedTestServer. MockHostResolver maps all hosts to 127.0.0.1 by default. | |
7217 MockHostResolver host_resolver; | |
7218 | |
7219 TransportSecurityState transport_security_state; | |
7220 base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1); | |
7221 bool include_subdomains = false; | |
7222 transport_security_state.AddHSTS("example.net", expiry, include_subdomains); | |
7223 | |
7224 TestNetworkDelegate network_delegate; // Must outlive URLRequest. | |
7225 | |
7226 MockCertVerifier cert_verifier; | |
7227 cert_verifier.set_default_result(OK); | |
7228 | |
7229 TestURLRequestContext context(true); | |
7230 context.set_host_resolver(&host_resolver); | |
7231 context.set_transport_security_state(&transport_security_state); | |
7232 context.set_network_delegate(&network_delegate); | |
7233 context.set_cert_verifier(&cert_verifier); | |
7234 context.Init(); | |
7235 | |
7236 GURL hsts_http_url(base::StringPrintf("http://example.net:%d/somehstssite", | |
7237 test_server.host_port_pair().port())); | |
7238 url::Replacements<char> replacements; | |
7239 const char kNewScheme[] = "https"; | |
7240 replacements.SetScheme(kNewScheme, url::Component(0, strlen(kNewScheme))); | |
7241 GURL hsts_https_url = hsts_http_url.ReplaceComponents(replacements); | |
7242 | |
7243 TestDelegate d; | |
7244 // Quit on redirect to allow response header inspection upon redirect. | |
7245 d.set_quit_on_redirect(true); | |
7246 | |
7247 scoped_ptr<URLRequest> req(context.CreateRequest(hsts_http_url, | |
7248 DEFAULT_PRIORITY, &d, NULL)); | |
7249 // Set Origin header to simulate a cross-origin request. | |
7250 HttpRequestHeaders request_headers; | |
7251 request_headers.SetHeader("Origin", kOriginHeaderValue); | |
7252 req->SetExtraRequestHeaders(request_headers); | |
7253 | |
7254 req->Start(); | |
7255 base::RunLoop().Run(); | |
7256 | |
7257 EXPECT_EQ(1, d.received_redirect_count()); | |
7258 | |
7259 const HttpResponseHeaders* headers = req->response_headers(); | |
7260 std::string redirect_location; | |
7261 EXPECT_TRUE(headers->EnumerateHeader(NULL, "Location", &redirect_location)); | |
7262 EXPECT_EQ(hsts_https_url.spec(), redirect_location); | |
7263 | |
7264 std::string received_cors_header; | |
7265 EXPECT_TRUE(headers->EnumerateHeader(NULL, "Access-Control-Allow-Origin", | |
7266 &received_cors_header)); | |
7267 EXPECT_EQ(kOriginHeaderValue, received_cors_header); | |
7268 } | |
7269 | |
7270 namespace { | |
7271 | |
7272 class SSLClientAuthTestDelegate : public TestDelegate { | |
7273 public: | |
7274 SSLClientAuthTestDelegate() : on_certificate_requested_count_(0) { | |
7275 } | |
7276 void OnCertificateRequested(URLRequest* request, | |
7277 SSLCertRequestInfo* cert_request_info) override { | |
7278 on_certificate_requested_count_++; | |
7279 base::MessageLoop::current()->Quit(); | |
7280 } | |
7281 int on_certificate_requested_count() { | |
7282 return on_certificate_requested_count_; | |
7283 } | |
7284 private: | |
7285 int on_certificate_requested_count_; | |
7286 }; | |
7287 | |
7288 } // namespace | |
7289 | |
7290 // TODO(davidben): Test the rest of the code. Specifically, | |
7291 // - Filtering which certificates to select. | |
7292 // - Sending a certificate back. | |
7293 // - Getting a certificate request in an SSL renegotiation sending the | |
7294 // HTTP request. | |
7295 TEST_F(HTTPSRequestTest, ClientAuthTest) { | |
7296 SpawnedTestServer::SSLOptions ssl_options; | |
7297 ssl_options.request_client_certificate = true; | |
7298 SpawnedTestServer test_server( | |
7299 SpawnedTestServer::TYPE_HTTPS, | |
7300 ssl_options, | |
7301 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
7302 ASSERT_TRUE(test_server.Start()); | |
7303 | |
7304 SSLClientAuthTestDelegate d; | |
7305 { | |
7306 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
7307 test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
7308 | |
7309 r->Start(); | |
7310 EXPECT_TRUE(r->is_pending()); | |
7311 | |
7312 base::RunLoop().Run(); | |
7313 | |
7314 EXPECT_EQ(1, d.on_certificate_requested_count()); | |
7315 EXPECT_FALSE(d.received_data_before_response()); | |
7316 EXPECT_EQ(0, d.bytes_received()); | |
7317 | |
7318 // Send no certificate. | |
7319 // TODO(davidben): Get temporary client cert import (with keys) working on | |
7320 // all platforms so we can test sending a cert as well. | |
7321 r->ContinueWithCertificate(NULL); | |
7322 | |
7323 base::RunLoop().Run(); | |
7324 | |
7325 EXPECT_EQ(1, d.response_started_count()); | |
7326 EXPECT_FALSE(d.received_data_before_response()); | |
7327 EXPECT_NE(0, d.bytes_received()); | |
7328 } | |
7329 } | |
7330 | |
7331 TEST_F(HTTPSRequestTest, ResumeTest) { | |
7332 // Test that we attempt a session resume when making two connections to the | |
7333 // same host. | |
7334 SpawnedTestServer::SSLOptions ssl_options; | |
7335 ssl_options.record_resume = true; | |
7336 SpawnedTestServer test_server( | |
7337 SpawnedTestServer::TYPE_HTTPS, | |
7338 ssl_options, | |
7339 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
7340 ASSERT_TRUE(test_server.Start()); | |
7341 | |
7342 SSLClientSocket::ClearSessionCache(); | |
7343 | |
7344 { | |
7345 TestDelegate d; | |
7346 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
7347 test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL)); | |
7348 | |
7349 r->Start(); | |
7350 EXPECT_TRUE(r->is_pending()); | |
7351 | |
7352 base::RunLoop().Run(); | |
7353 | |
7354 EXPECT_EQ(1, d.response_started_count()); | |
7355 } | |
7356 | |
7357 reinterpret_cast<HttpCache*>(default_context_.http_transaction_factory())-> | |
7358 CloseAllConnections(); | |
7359 | |
7360 { | |
7361 TestDelegate d; | |
7362 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
7363 test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL)); | |
7364 | |
7365 r->Start(); | |
7366 EXPECT_TRUE(r->is_pending()); | |
7367 | |
7368 base::RunLoop().Run(); | |
7369 | |
7370 // The response will look like; | |
7371 // insert abc | |
7372 // lookup abc | |
7373 // insert xyz | |
7374 // | |
7375 // With a newline at the end which makes the split think that there are | |
7376 // four lines. | |
7377 | |
7378 EXPECT_EQ(1, d.response_started_count()); | |
7379 std::vector<std::string> lines; | |
7380 base::SplitString(d.data_received(), '\n', &lines); | |
7381 ASSERT_EQ(4u, lines.size()) << d.data_received(); | |
7382 | |
7383 std::string session_id; | |
7384 | |
7385 for (size_t i = 0; i < 2; i++) { | |
7386 std::vector<std::string> parts; | |
7387 base::SplitString(lines[i], '\t', &parts); | |
7388 ASSERT_EQ(2u, parts.size()); | |
7389 if (i == 0) { | |
7390 EXPECT_EQ("insert", parts[0]); | |
7391 session_id = parts[1]; | |
7392 } else { | |
7393 EXPECT_EQ("lookup", parts[0]); | |
7394 EXPECT_EQ(session_id, parts[1]); | |
7395 } | |
7396 } | |
7397 } | |
7398 } | |
7399 | |
7400 // AssertTwoDistinctSessionsInserted checks that |session_info|, which must be | |
7401 // the result of fetching "ssl-session-cache" from the test server, indicates | |
7402 // that exactly two different sessions were inserted, with no lookups etc. | |
7403 static void AssertTwoDistinctSessionsInserted(const string& session_info) { | |
7404 std::vector<std::string> lines; | |
7405 base::SplitString(session_info, '\n', &lines); | |
7406 ASSERT_EQ(3u, lines.size()) << session_info; | |
7407 | |
7408 std::string session_id; | |
7409 for (size_t i = 0; i < 2; i++) { | |
7410 std::vector<std::string> parts; | |
7411 base::SplitString(lines[i], '\t', &parts); | |
7412 ASSERT_EQ(2u, parts.size()); | |
7413 EXPECT_EQ("insert", parts[0]); | |
7414 if (i == 0) { | |
7415 session_id = parts[1]; | |
7416 } else { | |
7417 EXPECT_NE(session_id, parts[1]); | |
7418 } | |
7419 } | |
7420 } | |
7421 | |
7422 TEST_F(HTTPSRequestTest, SSLSessionCacheShardTest) { | |
7423 // Test that sessions aren't resumed when the value of ssl_session_cache_shard | |
7424 // differs. | |
7425 SpawnedTestServer::SSLOptions ssl_options; | |
7426 ssl_options.record_resume = true; | |
7427 SpawnedTestServer test_server( | |
7428 SpawnedTestServer::TYPE_HTTPS, | |
7429 ssl_options, | |
7430 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
7431 ASSERT_TRUE(test_server.Start()); | |
7432 | |
7433 SSLClientSocket::ClearSessionCache(); | |
7434 | |
7435 { | |
7436 TestDelegate d; | |
7437 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
7438 test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL)); | |
7439 | |
7440 r->Start(); | |
7441 EXPECT_TRUE(r->is_pending()); | |
7442 | |
7443 base::RunLoop().Run(); | |
7444 | |
7445 EXPECT_EQ(1, d.response_started_count()); | |
7446 } | |
7447 | |
7448 // Now create a new HttpCache with a different ssl_session_cache_shard value. | |
7449 HttpNetworkSession::Params params; | |
7450 params.host_resolver = default_context_.host_resolver(); | |
7451 params.cert_verifier = default_context_.cert_verifier(); | |
7452 params.transport_security_state = default_context_.transport_security_state(); | |
7453 params.proxy_service = default_context_.proxy_service(); | |
7454 params.ssl_config_service = default_context_.ssl_config_service(); | |
7455 params.http_auth_handler_factory = | |
7456 default_context_.http_auth_handler_factory(); | |
7457 params.network_delegate = &default_network_delegate_; | |
7458 params.http_server_properties = default_context_.http_server_properties(); | |
7459 params.ssl_session_cache_shard = "alternate"; | |
7460 | |
7461 scoped_ptr<HttpCache> cache(new HttpCache( | |
7462 new HttpNetworkSession(params), | |
7463 HttpCache::DefaultBackend::InMemory(0))); | |
7464 | |
7465 default_context_.set_http_transaction_factory(cache.get()); | |
7466 | |
7467 { | |
7468 TestDelegate d; | |
7469 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
7470 test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL)); | |
7471 | |
7472 r->Start(); | |
7473 EXPECT_TRUE(r->is_pending()); | |
7474 | |
7475 base::RunLoop().Run(); | |
7476 | |
7477 // The response will look like; | |
7478 // insert abc | |
7479 // insert xyz | |
7480 // | |
7481 // With a newline at the end which makes the split think that there are | |
7482 // three lines. | |
7483 | |
7484 EXPECT_EQ(1, d.response_started_count()); | |
7485 AssertTwoDistinctSessionsInserted(d.data_received()); | |
7486 } | |
7487 } | |
7488 | |
7489 #if defined(OS_WIN) | |
7490 | |
7491 namespace { | |
7492 | |
7493 bool IsECDSACipherSuite(uint16_t cipher_suite) { | |
7494 const char* key_exchange; | |
7495 const char* cipher; | |
7496 const char* mac; | |
7497 bool is_aead; | |
7498 SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, cipher_suite); | |
7499 return std::string(key_exchange).find("ECDSA") != std::string::npos; | |
7500 } | |
7501 | |
7502 } // namespace | |
7503 | |
7504 // Test that ECDSA is disabled on Windows XP, where ECDSA certificates cannot be | |
7505 // verified. | |
7506 TEST_F(HTTPSRequestTest, DisableECDSAOnXP) { | |
7507 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { | |
7508 LOG(INFO) << "Skipping test on this version."; | |
7509 return; | |
7510 } | |
7511 | |
7512 SpawnedTestServer test_server( | |
7513 SpawnedTestServer::TYPE_HTTPS, | |
7514 SpawnedTestServer::kLocalhost, | |
7515 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
7516 ASSERT_TRUE(test_server.Start()); | |
7517 | |
7518 TestDelegate d; | |
7519 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
7520 test_server.GetURL("client-cipher-list"), DEFAULT_PRIORITY, &d, NULL)); | |
7521 r->Start(); | |
7522 EXPECT_TRUE(r->is_pending()); | |
7523 | |
7524 base::RunLoop().Run(); | |
7525 | |
7526 EXPECT_EQ(1, d.response_started_count()); | |
7527 std::vector<std::string> lines; | |
7528 base::SplitString(d.data_received(), '\n', &lines); | |
7529 | |
7530 for (size_t i = 0; i < lines.size(); i++) { | |
7531 int cipher_suite; | |
7532 ASSERT_TRUE(base::StringToInt(lines[i], &cipher_suite)); | |
7533 EXPECT_FALSE(IsECDSACipherSuite(cipher_suite)) | |
7534 << "ClientHello advertised " << cipher_suite; | |
7535 } | |
7536 } | |
7537 | |
7538 #endif // OS_WIN | |
7539 | |
7540 class TestSSLConfigService : public SSLConfigService { | |
7541 public: | |
7542 TestSSLConfigService(bool ev_enabled, | |
7543 bool online_rev_checking, | |
7544 bool rev_checking_required_local_anchors) | |
7545 : ev_enabled_(ev_enabled), | |
7546 online_rev_checking_(online_rev_checking), | |
7547 rev_checking_required_local_anchors_( | |
7548 rev_checking_required_local_anchors), | |
7549 min_version_(kDefaultSSLVersionMin), | |
7550 fallback_min_version_(kDefaultSSLVersionFallbackMin) {} | |
7551 | |
7552 void set_min_version(uint16 version) { | |
7553 min_version_ = version; | |
7554 } | |
7555 | |
7556 void set_fallback_min_version(uint16 version) { | |
7557 fallback_min_version_ = version; | |
7558 } | |
7559 | |
7560 // SSLConfigService: | |
7561 void GetSSLConfig(SSLConfig* config) override { | |
7562 *config = SSLConfig(); | |
7563 config->rev_checking_enabled = online_rev_checking_; | |
7564 config->verify_ev_cert = ev_enabled_; | |
7565 config->rev_checking_required_local_anchors = | |
7566 rev_checking_required_local_anchors_; | |
7567 if (fallback_min_version_) { | |
7568 config->version_fallback_min = fallback_min_version_; | |
7569 } | |
7570 if (min_version_) { | |
7571 config->version_min = min_version_; | |
7572 } | |
7573 } | |
7574 | |
7575 protected: | |
7576 ~TestSSLConfigService() override {} | |
7577 | |
7578 private: | |
7579 const bool ev_enabled_; | |
7580 const bool online_rev_checking_; | |
7581 const bool rev_checking_required_local_anchors_; | |
7582 uint16 min_version_; | |
7583 uint16 fallback_min_version_; | |
7584 }; | |
7585 | |
7586 class FallbackTestURLRequestContext : public TestURLRequestContext { | |
7587 public: | |
7588 explicit FallbackTestURLRequestContext(bool delay_initialization) | |
7589 : TestURLRequestContext(delay_initialization) {} | |
7590 | |
7591 void set_fallback_min_version(uint16 version) { | |
7592 TestSSLConfigService *ssl_config_service = | |
7593 new TestSSLConfigService(true /* check for EV */, | |
7594 false /* online revocation checking */, | |
7595 false /* require rev. checking for local | |
7596 anchors */); | |
7597 ssl_config_service->set_min_version(SSL_PROTOCOL_VERSION_SSL3); | |
7598 ssl_config_service->set_fallback_min_version(version); | |
7599 set_ssl_config_service(ssl_config_service); | |
7600 } | |
7601 }; | |
7602 | |
7603 class HTTPSFallbackTest : public testing::Test { | |
7604 public: | |
7605 HTTPSFallbackTest() : context_(true) {} | |
7606 ~HTTPSFallbackTest() override {} | |
7607 | |
7608 protected: | |
7609 void DoFallbackTest(const SpawnedTestServer::SSLOptions& ssl_options) { | |
7610 DCHECK(!request_); | |
7611 context_.Init(); | |
7612 delegate_.set_allow_certificate_errors(true); | |
7613 | |
7614 SpawnedTestServer test_server( | |
7615 SpawnedTestServer::TYPE_HTTPS, | |
7616 ssl_options, | |
7617 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
7618 ASSERT_TRUE(test_server.Start()); | |
7619 | |
7620 request_ = context_.CreateRequest( | |
7621 test_server.GetURL(std::string()), DEFAULT_PRIORITY, &delegate_, NULL); | |
7622 request_->Start(); | |
7623 | |
7624 base::RunLoop().Run(); | |
7625 } | |
7626 | |
7627 void set_fallback_min_version(uint16 version) { | |
7628 context_.set_fallback_min_version(version); | |
7629 } | |
7630 | |
7631 void ExpectConnection(int version) { | |
7632 EXPECT_EQ(1, delegate_.response_started_count()); | |
7633 EXPECT_NE(0, delegate_.bytes_received()); | |
7634 EXPECT_EQ(version, SSLConnectionStatusToVersion( | |
7635 request_->ssl_info().connection_status)); | |
7636 EXPECT_TRUE(request_->ssl_info().connection_status & | |
7637 SSL_CONNECTION_VERSION_FALLBACK); | |
7638 } | |
7639 | |
7640 void ExpectFailure(int error) { | |
7641 EXPECT_EQ(1, delegate_.response_started_count()); | |
7642 EXPECT_FALSE(request_->status().is_success()); | |
7643 EXPECT_EQ(URLRequestStatus::FAILED, request_->status().status()); | |
7644 EXPECT_EQ(error, request_->status().error()); | |
7645 } | |
7646 | |
7647 private: | |
7648 TestDelegate delegate_; | |
7649 FallbackTestURLRequestContext context_; | |
7650 scoped_ptr<URLRequest> request_; | |
7651 }; | |
7652 | |
7653 // Tests TLSv1.1 -> TLSv1 fallback. Verifies that we don't fall back more | |
7654 // than necessary. | |
7655 TEST_F(HTTPSFallbackTest, TLSv1Fallback) { | |
7656 SpawnedTestServer::SSLOptions ssl_options( | |
7657 SpawnedTestServer::SSLOptions::CERT_OK); | |
7658 ssl_options.tls_intolerant = | |
7659 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1; | |
7660 | |
7661 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); | |
7662 ExpectConnection(SSL_CONNECTION_VERSION_TLS1); | |
7663 } | |
7664 | |
7665 // This test is disabled on Android because the remote test server doesn't cause | |
7666 // a TCP reset. | |
7667 #if !defined(OS_ANDROID) | |
7668 // Tests fallback to TLS 1.0 on connection reset. | |
7669 TEST_F(HTTPSFallbackTest, TLSv1FallbackReset) { | |
7670 SpawnedTestServer::SSLOptions ssl_options( | |
7671 SpawnedTestServer::SSLOptions::CERT_OK); | |
7672 ssl_options.tls_intolerant = | |
7673 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1; | |
7674 ssl_options.tls_intolerance_type = | |
7675 SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_RESET; | |
7676 | |
7677 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); | |
7678 ExpectConnection(SSL_CONNECTION_VERSION_TLS1); | |
7679 } | |
7680 #endif // !OS_ANDROID | |
7681 | |
7682 // Tests that we don't fallback on handshake failure with servers that implement | |
7683 // TLS_FALLBACK_SCSV. Also ensure that the original error code is reported. | |
7684 TEST_F(HTTPSFallbackTest, FallbackSCSV) { | |
7685 SpawnedTestServer::SSLOptions ssl_options( | |
7686 SpawnedTestServer::SSLOptions::CERT_OK); | |
7687 // Configure HTTPS server to be intolerant of TLS >= 1.1 in order to trigger | |
7688 // a version fallback. | |
7689 ssl_options.tls_intolerant = | |
7690 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1; | |
7691 // Have the server process TLS_FALLBACK_SCSV so that version fallback | |
7692 // connections are rejected. | |
7693 ssl_options.fallback_scsv_enabled = true; | |
7694 | |
7695 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); | |
7696 | |
7697 // ERR_SSL_VERSION_OR_CIPHER_MISMATCH is how the server simulates version | |
7698 // intolerance. If the fallback SCSV is processed when the original error | |
7699 // that caused the fallback should be returned, which should be | |
7700 // ERR_SSL_VERSION_OR_CIPHER_MISMATCH. | |
7701 ExpectFailure(ERR_SSL_VERSION_OR_CIPHER_MISMATCH); | |
7702 } | |
7703 | |
7704 // Tests that we don't fallback on connection closed with servers that implement | |
7705 // TLS_FALLBACK_SCSV. Also ensure that the original error code is reported. | |
7706 TEST_F(HTTPSFallbackTest, FallbackSCSVClosed) { | |
7707 SpawnedTestServer::SSLOptions ssl_options( | |
7708 SpawnedTestServer::SSLOptions::CERT_OK); | |
7709 // Configure HTTPS server to be intolerant of TLS >= 1.1 in order to trigger | |
7710 // a version fallback. | |
7711 ssl_options.tls_intolerant = | |
7712 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1; | |
7713 ssl_options.tls_intolerance_type = | |
7714 SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_CLOSE; | |
7715 // Have the server process TLS_FALLBACK_SCSV so that version fallback | |
7716 // connections are rejected. | |
7717 ssl_options.fallback_scsv_enabled = true; | |
7718 | |
7719 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); | |
7720 | |
7721 // The original error should be replayed on rejected fallback. | |
7722 ExpectFailure(ERR_CONNECTION_CLOSED); | |
7723 } | |
7724 | |
7725 // Tests that the SSLv3 fallback doesn't happen by default. | |
7726 TEST_F(HTTPSFallbackTest, SSLv3Fallback) { | |
7727 SpawnedTestServer::SSLOptions ssl_options( | |
7728 SpawnedTestServer::SSLOptions::CERT_OK); | |
7729 ssl_options.tls_intolerant = | |
7730 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL; | |
7731 | |
7732 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); | |
7733 ExpectFailure(ERR_SSL_VERSION_OR_CIPHER_MISMATCH); | |
7734 } | |
7735 | |
7736 // Tests that the SSLv3 fallback works when explicitly enabled. | |
7737 TEST_F(HTTPSFallbackTest, SSLv3FallbackEnabled) { | |
7738 SpawnedTestServer::SSLOptions ssl_options( | |
7739 SpawnedTestServer::SSLOptions::CERT_OK); | |
7740 ssl_options.tls_intolerant = | |
7741 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL; | |
7742 set_fallback_min_version(SSL_PROTOCOL_VERSION_SSL3); | |
7743 | |
7744 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); | |
7745 ExpectConnection(SSL_CONNECTION_VERSION_SSL3); | |
7746 } | |
7747 | |
7748 // Tests that the SSLv3 fallback triggers on closed connections when explicitly | |
7749 // enabled. | |
7750 TEST_F(HTTPSFallbackTest, SSLv3FallbackClosed) { | |
7751 SpawnedTestServer::SSLOptions ssl_options( | |
7752 SpawnedTestServer::SSLOptions::CERT_OK); | |
7753 ssl_options.tls_intolerant = | |
7754 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL; | |
7755 ssl_options.tls_intolerance_type = | |
7756 SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_CLOSE; | |
7757 set_fallback_min_version(SSL_PROTOCOL_VERSION_SSL3); | |
7758 | |
7759 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); | |
7760 ExpectConnection(SSL_CONNECTION_VERSION_SSL3); | |
7761 } | |
7762 | |
7763 // Test that SSLv3 fallback probe connections don't cause sessions to be cached. | |
7764 TEST_F(HTTPSRequestTest, SSLv3FallbackNoCache) { | |
7765 SpawnedTestServer::SSLOptions ssl_options( | |
7766 SpawnedTestServer::SSLOptions::CERT_OK); | |
7767 ssl_options.tls_intolerant = | |
7768 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL; | |
7769 ssl_options.tls_intolerance_type = | |
7770 SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_CLOSE; | |
7771 ssl_options.record_resume = true; | |
7772 | |
7773 SpawnedTestServer test_server( | |
7774 SpawnedTestServer::TYPE_HTTPS, | |
7775 ssl_options, | |
7776 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
7777 ASSERT_TRUE(test_server.Start()); | |
7778 | |
7779 SSLClientSocket::ClearSessionCache(); | |
7780 | |
7781 // Make a connection that does a probe fallback to SSLv3 but fails because | |
7782 // SSLv3 fallback is disabled. We don't wish a session for this connection to | |
7783 // be inserted locally. | |
7784 { | |
7785 TestDelegate delegate; | |
7786 FallbackTestURLRequestContext context(true); | |
7787 | |
7788 context.set_fallback_min_version(SSL_PROTOCOL_VERSION_TLS1); | |
7789 context.Init(); | |
7790 scoped_ptr<URLRequest> request(context.CreateRequest( | |
7791 test_server.GetURL(std::string()), DEFAULT_PRIORITY, &delegate, NULL)); | |
7792 request->Start(); | |
7793 | |
7794 base::RunLoop().Run(); | |
7795 | |
7796 EXPECT_EQ(1, delegate.response_started_count()); | |
7797 EXPECT_FALSE(request->status().is_success()); | |
7798 EXPECT_EQ(URLRequestStatus::FAILED, request->status().status()); | |
7799 EXPECT_EQ(ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION, | |
7800 request->status().error()); | |
7801 } | |
7802 | |
7803 // Now allow SSLv3 connections and request the session cache log. | |
7804 { | |
7805 TestDelegate delegate; | |
7806 FallbackTestURLRequestContext context(true); | |
7807 context.set_fallback_min_version(SSL_PROTOCOL_VERSION_SSL3); | |
7808 | |
7809 context.Init(); | |
7810 scoped_ptr<URLRequest> request( | |
7811 context.CreateRequest(test_server.GetURL("ssl-session-cache"), | |
7812 DEFAULT_PRIORITY, | |
7813 &delegate, | |
7814 NULL)); | |
7815 request->Start(); | |
7816 | |
7817 base::RunLoop().Run(); | |
7818 | |
7819 EXPECT_EQ(1, delegate.response_started_count()); | |
7820 EXPECT_NE(0, delegate.bytes_received()); | |
7821 EXPECT_EQ(SSL_CONNECTION_VERSION_SSL3, SSLConnectionStatusToVersion( | |
7822 request->ssl_info().connection_status)); | |
7823 EXPECT_TRUE(request->ssl_info().connection_status & | |
7824 SSL_CONNECTION_VERSION_FALLBACK); | |
7825 | |
7826 std::vector<std::string> lines; | |
7827 // If no sessions were cached then the server should have seen two sessions | |
7828 // inserted with no lookups. | |
7829 AssertTwoDistinctSessionsInserted(delegate.data_received()); | |
7830 } | |
7831 } | |
7832 | |
7833 // This test is disabled on Android because the remote test server doesn't cause | |
7834 // a TCP reset. | |
7835 #if !defined(OS_ANDROID) | |
7836 // Tests that a reset connection does not fallback down to SSL3. | |
7837 TEST_F(HTTPSFallbackTest, SSLv3NoFallbackReset) { | |
7838 SpawnedTestServer::SSLOptions ssl_options( | |
7839 SpawnedTestServer::SSLOptions::CERT_OK); | |
7840 ssl_options.tls_intolerant = | |
7841 SpawnedTestServer::SSLOptions::TLS_INTOLERANT_ALL; | |
7842 ssl_options.tls_intolerance_type = | |
7843 SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_RESET; | |
7844 | |
7845 ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options)); | |
7846 ExpectFailure(ERR_CONNECTION_RESET); | |
7847 } | |
7848 #endif // !OS_ANDROID | |
7849 | |
7850 class HTTPSSessionTest : public testing::Test { | |
7851 public: | |
7852 HTTPSSessionTest() : default_context_(true) { | |
7853 cert_verifier_.set_default_result(OK); | |
7854 | |
7855 default_context_.set_network_delegate(&default_network_delegate_); | |
7856 default_context_.set_cert_verifier(&cert_verifier_); | |
7857 default_context_.Init(); | |
7858 } | |
7859 ~HTTPSSessionTest() override {} | |
7860 | |
7861 protected: | |
7862 MockCertVerifier cert_verifier_; | |
7863 TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest. | |
7864 TestURLRequestContext default_context_; | |
7865 }; | |
7866 | |
7867 // Tests that session resumption is not attempted if an invalid certificate | |
7868 // is presented. | |
7869 TEST_F(HTTPSSessionTest, DontResumeSessionsForInvalidCertificates) { | |
7870 SpawnedTestServer::SSLOptions ssl_options; | |
7871 ssl_options.record_resume = true; | |
7872 SpawnedTestServer test_server( | |
7873 SpawnedTestServer::TYPE_HTTPS, | |
7874 ssl_options, | |
7875 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
7876 ASSERT_TRUE(test_server.Start()); | |
7877 | |
7878 SSLClientSocket::ClearSessionCache(); | |
7879 | |
7880 // Simulate the certificate being expired and attempt a connection. | |
7881 cert_verifier_.set_default_result(ERR_CERT_DATE_INVALID); | |
7882 { | |
7883 TestDelegate d; | |
7884 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
7885 test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL)); | |
7886 | |
7887 r->Start(); | |
7888 EXPECT_TRUE(r->is_pending()); | |
7889 | |
7890 base::RunLoop().Run(); | |
7891 | |
7892 EXPECT_EQ(1, d.response_started_count()); | |
7893 } | |
7894 | |
7895 reinterpret_cast<HttpCache*>(default_context_.http_transaction_factory())-> | |
7896 CloseAllConnections(); | |
7897 | |
7898 // Now change the certificate to be acceptable (so that the response is | |
7899 // loaded), and ensure that no session id is presented to the peer. | |
7900 cert_verifier_.set_default_result(OK); | |
7901 { | |
7902 TestDelegate d; | |
7903 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
7904 test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d, NULL)); | |
7905 | |
7906 r->Start(); | |
7907 EXPECT_TRUE(r->is_pending()); | |
7908 | |
7909 base::RunLoop().Run(); | |
7910 | |
7911 // The response will look like; | |
7912 // insert abc | |
7913 // insert xyz | |
7914 // | |
7915 // With a newline at the end which makes the split think that there are | |
7916 // three lines. | |
7917 // | |
7918 // If a session was presented (eg: a bug), then the response would look | |
7919 // like; | |
7920 // insert abc | |
7921 // lookup abc | |
7922 // insert xyz | |
7923 | |
7924 EXPECT_EQ(1, d.response_started_count()); | |
7925 AssertTwoDistinctSessionsInserted(d.data_received()); | |
7926 } | |
7927 } | |
7928 | |
7929 // This the fingerprint of the "Testing CA" certificate used by the testserver. | |
7930 // See net/data/ssl/certificates/ocsp-test-root.pem. | |
7931 static const SHA1HashValue kOCSPTestCertFingerprint = | |
7932 { { 0xf1, 0xad, 0xf6, 0xce, 0x42, 0xac, 0xe7, 0xb4, 0xf4, 0x24, | |
7933 0xdb, 0x1a, 0xf7, 0xa0, 0x9f, 0x09, 0xa1, 0xea, 0xf1, 0x5c } }; | |
7934 | |
7935 // This is the SHA256, SPKI hash of the "Testing CA" certificate used by the | |
7936 // testserver. | |
7937 static const SHA256HashValue kOCSPTestCertSPKI = { { | |
7938 0xee, 0xe6, 0x51, 0x2d, 0x4c, 0xfa, 0xf7, 0x3e, | |
7939 0x6c, 0xd8, 0xca, 0x67, 0xed, 0xb5, 0x5d, 0x49, | |
7940 0x76, 0xe1, 0x52, 0xa7, 0x6e, 0x0e, 0xa0, 0x74, | |
7941 0x09, 0x75, 0xe6, 0x23, 0x24, 0xbd, 0x1b, 0x28, | |
7942 } }; | |
7943 | |
7944 // This is the policy OID contained in the certificates that testserver | |
7945 // generates. | |
7946 static const char kOCSPTestCertPolicy[] = "1.3.6.1.4.1.11129.2.4.1"; | |
7947 | |
7948 class HTTPSOCSPTest : public HTTPSRequestTest { | |
7949 public: | |
7950 HTTPSOCSPTest() | |
7951 : context_(true), | |
7952 ev_test_policy_( | |
7953 new ScopedTestEVPolicy(EVRootCAMetadata::GetInstance(), | |
7954 kOCSPTestCertFingerprint, | |
7955 kOCSPTestCertPolicy)) { | |
7956 } | |
7957 | |
7958 void SetUp() override { | |
7959 SetupContext(&context_); | |
7960 context_.Init(); | |
7961 | |
7962 scoped_refptr<X509Certificate> root_cert = | |
7963 ImportCertFromFile(GetTestCertsDirectory(), "ocsp-test-root.pem"); | |
7964 CHECK_NE(static_cast<X509Certificate*>(NULL), root_cert.get()); | |
7965 test_root_.reset(new ScopedTestRoot(root_cert.get())); | |
7966 | |
7967 #if defined(USE_NSS) || defined(OS_IOS) | |
7968 SetURLRequestContextForNSSHttpIO(&context_); | |
7969 EnsureNSSHttpIOInit(); | |
7970 #endif | |
7971 } | |
7972 | |
7973 void DoConnection(const SpawnedTestServer::SSLOptions& ssl_options, | |
7974 CertStatus* out_cert_status) { | |
7975 // We always overwrite out_cert_status. | |
7976 *out_cert_status = 0; | |
7977 SpawnedTestServer test_server( | |
7978 SpawnedTestServer::TYPE_HTTPS, | |
7979 ssl_options, | |
7980 base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))); | |
7981 ASSERT_TRUE(test_server.Start()); | |
7982 | |
7983 TestDelegate d; | |
7984 d.set_allow_certificate_errors(true); | |
7985 scoped_ptr<URLRequest> r(context_.CreateRequest( | |
7986 test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d, NULL)); | |
7987 r->Start(); | |
7988 | |
7989 base::RunLoop().Run(); | |
7990 | |
7991 EXPECT_EQ(1, d.response_started_count()); | |
7992 *out_cert_status = r->ssl_info().cert_status; | |
7993 } | |
7994 | |
7995 ~HTTPSOCSPTest() override { | |
7996 #if defined(USE_NSS) || defined(OS_IOS) | |
7997 ShutdownNSSHttpIO(); | |
7998 #endif | |
7999 } | |
8000 | |
8001 protected: | |
8002 // SetupContext configures the URLRequestContext that will be used for making | |
8003 // connetions to testserver. This can be overridden in test subclasses for | |
8004 // different behaviour. | |
8005 virtual void SetupContext(URLRequestContext* context) { | |
8006 context->set_ssl_config_service( | |
8007 new TestSSLConfigService(true /* check for EV */, | |
8008 true /* online revocation checking */, | |
8009 false /* require rev. checking for local | |
8010 anchors */)); | |
8011 } | |
8012 | |
8013 scoped_ptr<ScopedTestRoot> test_root_; | |
8014 TestURLRequestContext context_; | |
8015 scoped_ptr<ScopedTestEVPolicy> ev_test_policy_; | |
8016 }; | |
8017 | |
8018 static CertStatus ExpectedCertStatusForFailedOnlineRevocationCheck() { | |
8019 #if defined(OS_WIN) | |
8020 // Windows can return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION but we don't | |
8021 // have that ability on other platforms. | |
8022 return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION; | |
8023 #else | |
8024 return 0; | |
8025 #endif | |
8026 } | |
8027 | |
8028 // SystemSupportsHardFailRevocationChecking returns true iff the current | |
8029 // operating system supports revocation checking and can distinguish between | |
8030 // situations where a given certificate lacks any revocation information (eg: | |
8031 // no CRLDistributionPoints and no OCSP Responder AuthorityInfoAccess) and when | |
8032 // revocation information cannot be obtained (eg: the CRL was unreachable). | |
8033 // If it does not, then tests which rely on 'hard fail' behaviour should be | |
8034 // skipped. | |
8035 static bool SystemSupportsHardFailRevocationChecking() { | |
8036 #if defined(OS_WIN) || defined(USE_NSS) || defined(OS_IOS) | |
8037 return true; | |
8038 #else | |
8039 return false; | |
8040 #endif | |
8041 } | |
8042 | |
8043 // SystemUsesChromiumEVMetadata returns true iff the current operating system | |
8044 // uses Chromium's EV metadata (i.e. EVRootCAMetadata). If it does not, then | |
8045 // several tests are effected because our testing EV certificate won't be | |
8046 // recognised as EV. | |
8047 static bool SystemUsesChromiumEVMetadata() { | |
8048 #if defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID) | |
8049 // http://crbug.com/117478 - OpenSSL does not support EV validation. | |
8050 return false; | |
8051 #elif (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_ANDROID) | |
8052 // On OS X and Android, we use the system to tell us whether a certificate is | |
8053 // EV or not and the system won't recognise our testing root. | |
8054 return false; | |
8055 #else | |
8056 return true; | |
8057 #endif | |
8058 } | |
8059 | |
8060 static bool SystemSupportsOCSP() { | |
8061 #if defined(USE_OPENSSL_CERTS) | |
8062 // http://crbug.com/117478 - OpenSSL does not support OCSP. | |
8063 return false; | |
8064 #elif defined(OS_WIN) | |
8065 return base::win::GetVersion() >= base::win::VERSION_VISTA; | |
8066 #elif defined(OS_ANDROID) | |
8067 // TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported. | |
8068 return false; | |
8069 #else | |
8070 return true; | |
8071 #endif | |
8072 } | |
8073 | |
8074 static bool SystemSupportsOCSPStapling() { | |
8075 #if defined(USE_NSS) | |
8076 return true; | |
8077 #elif defined(OS_WIN) | |
8078 return base::win::GetVersion() >= base::win::VERSION_VISTA; | |
8079 #else | |
8080 return false; | |
8081 #endif | |
8082 } | |
8083 | |
8084 TEST_F(HTTPSOCSPTest, Valid) { | |
8085 if (!SystemSupportsOCSP()) { | |
8086 LOG(WARNING) << "Skipping test because system doesn't support OCSP"; | |
8087 return; | |
8088 } | |
8089 | |
8090 SpawnedTestServer::SSLOptions ssl_options( | |
8091 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8092 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK; | |
8093 | |
8094 CertStatus cert_status; | |
8095 DoConnection(ssl_options, &cert_status); | |
8096 | |
8097 EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); | |
8098 | |
8099 EXPECT_EQ(SystemUsesChromiumEVMetadata(), | |
8100 static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); | |
8101 | |
8102 EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); | |
8103 } | |
8104 | |
8105 TEST_F(HTTPSOCSPTest, Revoked) { | |
8106 if (!SystemSupportsOCSP()) { | |
8107 LOG(WARNING) << "Skipping test because system doesn't support OCSP"; | |
8108 return; | |
8109 } | |
8110 | |
8111 SpawnedTestServer::SSLOptions ssl_options( | |
8112 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8113 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED; | |
8114 | |
8115 CertStatus cert_status; | |
8116 DoConnection(ssl_options, &cert_status); | |
8117 | |
8118 #if !(defined(OS_MACOSX) && !defined(OS_IOS)) | |
8119 // Doesn't pass on OS X yet for reasons that need to be investigated. | |
8120 EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); | |
8121 #endif | |
8122 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); | |
8123 EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); | |
8124 } | |
8125 | |
8126 TEST_F(HTTPSOCSPTest, Invalid) { | |
8127 if (!SystemSupportsOCSP()) { | |
8128 LOG(WARNING) << "Skipping test because system doesn't support OCSP"; | |
8129 return; | |
8130 } | |
8131 | |
8132 SpawnedTestServer::SSLOptions ssl_options( | |
8133 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8134 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; | |
8135 | |
8136 CertStatus cert_status; | |
8137 DoConnection(ssl_options, &cert_status); | |
8138 | |
8139 EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(), | |
8140 cert_status & CERT_STATUS_ALL_ERRORS); | |
8141 | |
8142 // Without a positive OCSP response, we shouldn't show the EV status. | |
8143 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); | |
8144 EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); | |
8145 } | |
8146 | |
8147 TEST_F(HTTPSOCSPTest, ValidStapled) { | |
8148 if (!SystemSupportsOCSPStapling()) { | |
8149 LOG(WARNING) | |
8150 << "Skipping test because system doesn't support OCSP stapling"; | |
8151 return; | |
8152 } | |
8153 | |
8154 SpawnedTestServer::SSLOptions ssl_options( | |
8155 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8156 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK; | |
8157 ssl_options.staple_ocsp_response = true; | |
8158 ssl_options.ocsp_server_unavailable = true; | |
8159 | |
8160 CertStatus cert_status; | |
8161 DoConnection(ssl_options, &cert_status); | |
8162 | |
8163 EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); | |
8164 | |
8165 EXPECT_EQ(SystemUsesChromiumEVMetadata(), | |
8166 static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); | |
8167 | |
8168 EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); | |
8169 } | |
8170 | |
8171 // Disabled on NSS ports. See https://crbug.com/431716. | |
8172 #if defined(USE_NSS) | |
8173 #define MAYBE_RevokedStapled DISABLED_RevokedStapled | |
8174 #else | |
8175 #define MAYBE_RevokedStapled RevokedStapled | |
8176 #endif | |
8177 TEST_F(HTTPSOCSPTest, MAYBE_RevokedStapled) { | |
8178 if (!SystemSupportsOCSPStapling()) { | |
8179 LOG(WARNING) | |
8180 << "Skipping test because system doesn't support OCSP stapling"; | |
8181 return; | |
8182 } | |
8183 | |
8184 SpawnedTestServer::SSLOptions ssl_options( | |
8185 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8186 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED; | |
8187 ssl_options.staple_ocsp_response = true; | |
8188 ssl_options.ocsp_server_unavailable = true; | |
8189 | |
8190 CertStatus cert_status; | |
8191 DoConnection(ssl_options, &cert_status); | |
8192 | |
8193 EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); | |
8194 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); | |
8195 EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); | |
8196 } | |
8197 | |
8198 class HTTPSHardFailTest : public HTTPSOCSPTest { | |
8199 protected: | |
8200 void SetupContext(URLRequestContext* context) override { | |
8201 context->set_ssl_config_service( | |
8202 new TestSSLConfigService(false /* check for EV */, | |
8203 false /* online revocation checking */, | |
8204 true /* require rev. checking for local | |
8205 anchors */)); | |
8206 } | |
8207 }; | |
8208 | |
8209 TEST_F(HTTPSHardFailTest, FailsOnOCSPInvalid) { | |
8210 if (!SystemSupportsOCSP()) { | |
8211 LOG(WARNING) << "Skipping test because system doesn't support OCSP"; | |
8212 return; | |
8213 } | |
8214 | |
8215 if (!SystemSupportsHardFailRevocationChecking()) { | |
8216 LOG(WARNING) << "Skipping test because system doesn't support hard fail " | |
8217 << "revocation checking"; | |
8218 return; | |
8219 } | |
8220 | |
8221 SpawnedTestServer::SSLOptions ssl_options( | |
8222 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8223 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; | |
8224 | |
8225 CertStatus cert_status; | |
8226 DoConnection(ssl_options, &cert_status); | |
8227 | |
8228 EXPECT_EQ(CERT_STATUS_REVOKED, | |
8229 cert_status & CERT_STATUS_REVOKED); | |
8230 | |
8231 // Without a positive OCSP response, we shouldn't show the EV status. | |
8232 EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); | |
8233 } | |
8234 | |
8235 class HTTPSEVCRLSetTest : public HTTPSOCSPTest { | |
8236 protected: | |
8237 void SetupContext(URLRequestContext* context) override { | |
8238 context->set_ssl_config_service( | |
8239 new TestSSLConfigService(true /* check for EV */, | |
8240 false /* online revocation checking */, | |
8241 false /* require rev. checking for local | |
8242 anchors */)); | |
8243 } | |
8244 }; | |
8245 | |
8246 TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndInvalidOCSP) { | |
8247 if (!SystemSupportsOCSP()) { | |
8248 LOG(WARNING) << "Skipping test because system doesn't support OCSP"; | |
8249 return; | |
8250 } | |
8251 | |
8252 SpawnedTestServer::SSLOptions ssl_options( | |
8253 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8254 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; | |
8255 SSLConfigService::SetCRLSet(scoped_refptr<CRLSet>()); | |
8256 | |
8257 CertStatus cert_status; | |
8258 DoConnection(ssl_options, &cert_status); | |
8259 | |
8260 EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(), | |
8261 cert_status & CERT_STATUS_ALL_ERRORS); | |
8262 | |
8263 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); | |
8264 EXPECT_EQ(SystemUsesChromiumEVMetadata(), | |
8265 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); | |
8266 } | |
8267 | |
8268 TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndRevokedOCSP) { | |
8269 if (!SystemSupportsOCSP()) { | |
8270 LOG(WARNING) << "Skipping test because system doesn't support OCSP"; | |
8271 return; | |
8272 } | |
8273 | |
8274 SpawnedTestServer::SSLOptions ssl_options( | |
8275 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8276 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED; | |
8277 SSLConfigService::SetCRLSet(scoped_refptr<CRLSet>()); | |
8278 | |
8279 CertStatus cert_status; | |
8280 DoConnection(ssl_options, &cert_status); | |
8281 | |
8282 // Currently only works for Windows. When using NSS or OS X, it's not | |
8283 // possible to determine whether the check failed because of actual | |
8284 // revocation or because there was an OCSP failure. | |
8285 #if defined(OS_WIN) | |
8286 EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); | |
8287 #else | |
8288 EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); | |
8289 #endif | |
8290 | |
8291 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); | |
8292 EXPECT_EQ(SystemUsesChromiumEVMetadata(), | |
8293 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); | |
8294 } | |
8295 | |
8296 TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndGoodOCSP) { | |
8297 if (!SystemSupportsOCSP()) { | |
8298 LOG(WARNING) << "Skipping test because system doesn't support OCSP"; | |
8299 return; | |
8300 } | |
8301 | |
8302 SpawnedTestServer::SSLOptions ssl_options( | |
8303 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8304 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK; | |
8305 SSLConfigService::SetCRLSet(scoped_refptr<CRLSet>()); | |
8306 | |
8307 CertStatus cert_status; | |
8308 DoConnection(ssl_options, &cert_status); | |
8309 | |
8310 EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); | |
8311 | |
8312 EXPECT_EQ(SystemUsesChromiumEVMetadata(), | |
8313 static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); | |
8314 EXPECT_EQ(SystemUsesChromiumEVMetadata(), | |
8315 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); | |
8316 } | |
8317 | |
8318 TEST_F(HTTPSEVCRLSetTest, ExpiredCRLSet) { | |
8319 if (!SystemSupportsOCSP()) { | |
8320 LOG(WARNING) << "Skipping test because system doesn't support OCSP"; | |
8321 return; | |
8322 } | |
8323 | |
8324 SpawnedTestServer::SSLOptions ssl_options( | |
8325 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8326 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; | |
8327 SSLConfigService::SetCRLSet( | |
8328 scoped_refptr<CRLSet>(CRLSet::ExpiredCRLSetForTesting())); | |
8329 | |
8330 CertStatus cert_status; | |
8331 DoConnection(ssl_options, &cert_status); | |
8332 | |
8333 EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(), | |
8334 cert_status & CERT_STATUS_ALL_ERRORS); | |
8335 | |
8336 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); | |
8337 EXPECT_EQ(SystemUsesChromiumEVMetadata(), | |
8338 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); | |
8339 } | |
8340 | |
8341 TEST_F(HTTPSEVCRLSetTest, FreshCRLSetCovered) { | |
8342 if (!SystemSupportsOCSP()) { | |
8343 LOG(WARNING) << "Skipping test because system doesn't support OCSP"; | |
8344 return; | |
8345 } | |
8346 | |
8347 SpawnedTestServer::SSLOptions ssl_options( | |
8348 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8349 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; | |
8350 SSLConfigService::SetCRLSet( | |
8351 scoped_refptr<CRLSet>(CRLSet::ForTesting( | |
8352 false, &kOCSPTestCertSPKI, ""))); | |
8353 | |
8354 CertStatus cert_status; | |
8355 DoConnection(ssl_options, &cert_status); | |
8356 | |
8357 // With a fresh CRLSet that covers the issuing certificate, we shouldn't do a | |
8358 // revocation check for EV. | |
8359 EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); | |
8360 EXPECT_EQ(SystemUsesChromiumEVMetadata(), | |
8361 static_cast<bool>(cert_status & CERT_STATUS_IS_EV)); | |
8362 EXPECT_FALSE( | |
8363 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); | |
8364 } | |
8365 | |
8366 TEST_F(HTTPSEVCRLSetTest, FreshCRLSetNotCovered) { | |
8367 if (!SystemSupportsOCSP()) { | |
8368 LOG(WARNING) << "Skipping test because system doesn't support OCSP"; | |
8369 return; | |
8370 } | |
8371 | |
8372 SpawnedTestServer::SSLOptions ssl_options( | |
8373 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8374 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; | |
8375 SSLConfigService::SetCRLSet( | |
8376 scoped_refptr<CRLSet>(CRLSet::EmptyCRLSetForTesting())); | |
8377 | |
8378 CertStatus cert_status = 0; | |
8379 DoConnection(ssl_options, &cert_status); | |
8380 | |
8381 // Even with a fresh CRLSet, we should still do online revocation checks when | |
8382 // the certificate chain isn't covered by the CRLSet, which it isn't in this | |
8383 // test. | |
8384 EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(), | |
8385 cert_status & CERT_STATUS_ALL_ERRORS); | |
8386 | |
8387 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); | |
8388 EXPECT_EQ(SystemUsesChromiumEVMetadata(), | |
8389 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); | |
8390 } | |
8391 | |
8392 TEST_F(HTTPSEVCRLSetTest, ExpiredCRLSetAndRevokedNonEVCert) { | |
8393 // Test that when EV verification is requested, but online revocation | |
8394 // checking is disabled, and the leaf certificate is not in fact EV, that | |
8395 // no revocation checking actually happens. | |
8396 if (!SystemSupportsOCSP()) { | |
8397 LOG(WARNING) << "Skipping test because system doesn't support OCSP"; | |
8398 return; | |
8399 } | |
8400 | |
8401 // Unmark the certificate's OID as EV, which should disable revocation | |
8402 // checking (as per the user preference) | |
8403 ev_test_policy_.reset(); | |
8404 | |
8405 SpawnedTestServer::SSLOptions ssl_options( | |
8406 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8407 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED; | |
8408 SSLConfigService::SetCRLSet( | |
8409 scoped_refptr<CRLSet>(CRLSet::ExpiredCRLSetForTesting())); | |
8410 | |
8411 CertStatus cert_status; | |
8412 DoConnection(ssl_options, &cert_status); | |
8413 | |
8414 EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); | |
8415 | |
8416 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); | |
8417 EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); | |
8418 } | |
8419 | |
8420 class HTTPSCRLSetTest : public HTTPSOCSPTest { | |
8421 protected: | |
8422 void SetupContext(URLRequestContext* context) override { | |
8423 context->set_ssl_config_service( | |
8424 new TestSSLConfigService(false /* check for EV */, | |
8425 false /* online revocation checking */, | |
8426 false /* require rev. checking for local | |
8427 anchors */)); | |
8428 } | |
8429 }; | |
8430 | |
8431 TEST_F(HTTPSCRLSetTest, ExpiredCRLSet) { | |
8432 SpawnedTestServer::SSLOptions ssl_options( | |
8433 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8434 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID; | |
8435 SSLConfigService::SetCRLSet( | |
8436 scoped_refptr<CRLSet>(CRLSet::ExpiredCRLSetForTesting())); | |
8437 | |
8438 CertStatus cert_status; | |
8439 DoConnection(ssl_options, &cert_status); | |
8440 | |
8441 // If we're not trying EV verification then, even if the CRLSet has expired, | |
8442 // we don't fall back to online revocation checks. | |
8443 EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS); | |
8444 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); | |
8445 EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED); | |
8446 } | |
8447 | |
8448 TEST_F(HTTPSCRLSetTest, CRLSetRevoked) { | |
8449 #if defined(OS_ANDROID) | |
8450 LOG(WARNING) << "Skipping test because system doesn't support CRLSets"; | |
8451 return; | |
8452 #endif | |
8453 | |
8454 SpawnedTestServer::SSLOptions ssl_options( | |
8455 SpawnedTestServer::SSLOptions::CERT_AUTO); | |
8456 ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK; | |
8457 ssl_options.cert_serial = 10; | |
8458 SSLConfigService::SetCRLSet( | |
8459 scoped_refptr<CRLSet>(CRLSet::ForTesting( | |
8460 false, &kOCSPTestCertSPKI, "\x0a"))); | |
8461 | |
8462 CertStatus cert_status = 0; | |
8463 DoConnection(ssl_options, &cert_status); | |
8464 | |
8465 // If the certificate is recorded as revoked in the CRLSet, that should be | |
8466 // reflected without online revocation checking. | |
8467 EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS); | |
8468 EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV); | |
8469 EXPECT_FALSE( | |
8470 static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED)); | |
8471 } | |
8472 #endif // !defined(OS_IOS) | |
8473 | |
8474 #if !defined(DISABLE_FTP_SUPPORT) | |
8475 class URLRequestTestFTP : public URLRequestTest { | |
8476 public: | |
8477 URLRequestTestFTP() | |
8478 : test_server_(SpawnedTestServer::TYPE_FTP, SpawnedTestServer::kLocalhost, | |
8479 base::FilePath()) { | |
8480 } | |
8481 | |
8482 protected: | |
8483 SpawnedTestServer test_server_; | |
8484 }; | |
8485 | |
8486 // Make sure an FTP request using an unsafe ports fails. | |
8487 TEST_F(URLRequestTestFTP, UnsafePort) { | |
8488 ASSERT_TRUE(test_server_.Start()); | |
8489 | |
8490 URLRequestJobFactoryImpl job_factory; | |
8491 FtpNetworkLayer ftp_transaction_factory(default_context_.host_resolver()); | |
8492 | |
8493 GURL url("ftp://127.0.0.1:7"); | |
8494 job_factory.SetProtocolHandler( | |
8495 "ftp", | |
8496 new FtpProtocolHandler(&ftp_transaction_factory)); | |
8497 default_context_.set_job_factory(&job_factory); | |
8498 | |
8499 TestDelegate d; | |
8500 { | |
8501 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
8502 url, DEFAULT_PRIORITY, &d, NULL)); | |
8503 r->Start(); | |
8504 EXPECT_TRUE(r->is_pending()); | |
8505 | |
8506 base::RunLoop().Run(); | |
8507 | |
8508 EXPECT_FALSE(r->is_pending()); | |
8509 EXPECT_EQ(URLRequestStatus::FAILED, r->status().status()); | |
8510 EXPECT_EQ(ERR_UNSAFE_PORT, r->status().error()); | |
8511 } | |
8512 } | |
8513 | |
8514 // Flaky, see http://crbug.com/25045. | |
8515 TEST_F(URLRequestTestFTP, DISABLED_FTPDirectoryListing) { | |
8516 ASSERT_TRUE(test_server_.Start()); | |
8517 | |
8518 TestDelegate d; | |
8519 { | |
8520 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
8521 test_server_.GetURL("/"), DEFAULT_PRIORITY, &d, NULL)); | |
8522 r->Start(); | |
8523 EXPECT_TRUE(r->is_pending()); | |
8524 | |
8525 base::RunLoop().Run(); | |
8526 | |
8527 EXPECT_FALSE(r->is_pending()); | |
8528 EXPECT_EQ(1, d.response_started_count()); | |
8529 EXPECT_FALSE(d.received_data_before_response()); | |
8530 EXPECT_LT(0, d.bytes_received()); | |
8531 EXPECT_EQ(test_server_.host_port_pair().host(), | |
8532 r->GetSocketAddress().host()); | |
8533 EXPECT_EQ(test_server_.host_port_pair().port(), | |
8534 r->GetSocketAddress().port()); | |
8535 } | |
8536 } | |
8537 | |
8538 // Flaky, see http://crbug.com/25045. | |
8539 TEST_F(URLRequestTestFTP, DISABLED_FTPGetTestAnonymous) { | |
8540 ASSERT_TRUE(test_server_.Start()); | |
8541 | |
8542 base::FilePath app_path; | |
8543 PathService::Get(base::DIR_SOURCE_ROOT, &app_path); | |
8544 app_path = app_path.AppendASCII("LICENSE"); | |
8545 TestDelegate d; | |
8546 { | |
8547 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
8548 test_server_.GetURL("/LICENSE"), DEFAULT_PRIORITY, &d, NULL)); | |
8549 r->Start(); | |
8550 EXPECT_TRUE(r->is_pending()); | |
8551 | |
8552 base::RunLoop().Run(); | |
8553 | |
8554 int64 file_size = 0; | |
8555 base::GetFileSize(app_path, &file_size); | |
8556 | |
8557 EXPECT_FALSE(r->is_pending()); | |
8558 EXPECT_EQ(1, d.response_started_count()); | |
8559 EXPECT_FALSE(d.received_data_before_response()); | |
8560 EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); | |
8561 EXPECT_EQ(test_server_.host_port_pair().host(), | |
8562 r->GetSocketAddress().host()); | |
8563 EXPECT_EQ(test_server_.host_port_pair().port(), | |
8564 r->GetSocketAddress().port()); | |
8565 } | |
8566 } | |
8567 | |
8568 // Flaky, see http://crbug.com/25045. | |
8569 TEST_F(URLRequestTestFTP, DISABLED_FTPGetTest) { | |
8570 ASSERT_TRUE(test_server_.Start()); | |
8571 | |
8572 base::FilePath app_path; | |
8573 PathService::Get(base::DIR_SOURCE_ROOT, &app_path); | |
8574 app_path = app_path.AppendASCII("LICENSE"); | |
8575 TestDelegate d; | |
8576 { | |
8577 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
8578 test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome", "chrome"), | |
8579 DEFAULT_PRIORITY, &d, NULL)); | |
8580 r->Start(); | |
8581 EXPECT_TRUE(r->is_pending()); | |
8582 | |
8583 base::RunLoop().Run(); | |
8584 | |
8585 int64 file_size = 0; | |
8586 base::GetFileSize(app_path, &file_size); | |
8587 | |
8588 EXPECT_FALSE(r->is_pending()); | |
8589 EXPECT_EQ(test_server_.host_port_pair().host(), | |
8590 r->GetSocketAddress().host()); | |
8591 EXPECT_EQ(test_server_.host_port_pair().port(), | |
8592 r->GetSocketAddress().port()); | |
8593 EXPECT_EQ(1, d.response_started_count()); | |
8594 EXPECT_FALSE(d.received_data_before_response()); | |
8595 EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); | |
8596 | |
8597 LoadTimingInfo load_timing_info; | |
8598 r->GetLoadTimingInfo(&load_timing_info); | |
8599 TestLoadTimingNoHttpResponse(load_timing_info); | |
8600 } | |
8601 } | |
8602 | |
8603 // Flaky, see http://crbug.com/25045. | |
8604 TEST_F(URLRequestTestFTP, DISABLED_FTPCheckWrongPassword) { | |
8605 ASSERT_TRUE(test_server_.Start()); | |
8606 | |
8607 base::FilePath app_path; | |
8608 PathService::Get(base::DIR_SOURCE_ROOT, &app_path); | |
8609 app_path = app_path.AppendASCII("LICENSE"); | |
8610 TestDelegate d; | |
8611 { | |
8612 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
8613 test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome", | |
8614 "wrong_password"), | |
8615 DEFAULT_PRIORITY, &d, NULL)); | |
8616 r->Start(); | |
8617 EXPECT_TRUE(r->is_pending()); | |
8618 | |
8619 base::RunLoop().Run(); | |
8620 | |
8621 int64 file_size = 0; | |
8622 base::GetFileSize(app_path, &file_size); | |
8623 | |
8624 EXPECT_FALSE(r->is_pending()); | |
8625 EXPECT_EQ(1, d.response_started_count()); | |
8626 EXPECT_FALSE(d.received_data_before_response()); | |
8627 EXPECT_EQ(d.bytes_received(), 0); | |
8628 } | |
8629 } | |
8630 | |
8631 // Flaky, see http://crbug.com/25045. | |
8632 TEST_F(URLRequestTestFTP, DISABLED_FTPCheckWrongPasswordRestart) { | |
8633 ASSERT_TRUE(test_server_.Start()); | |
8634 | |
8635 base::FilePath app_path; | |
8636 PathService::Get(base::DIR_SOURCE_ROOT, &app_path); | |
8637 app_path = app_path.AppendASCII("LICENSE"); | |
8638 TestDelegate d; | |
8639 // Set correct login credentials. The delegate will be asked for them when | |
8640 // the initial login with wrong credentials will fail. | |
8641 d.set_credentials(AuthCredentials(kChrome, kChrome)); | |
8642 { | |
8643 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
8644 test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome", | |
8645 "wrong_password"), | |
8646 DEFAULT_PRIORITY, &d, NULL)); | |
8647 r->Start(); | |
8648 EXPECT_TRUE(r->is_pending()); | |
8649 | |
8650 base::RunLoop().Run(); | |
8651 | |
8652 int64 file_size = 0; | |
8653 base::GetFileSize(app_path, &file_size); | |
8654 | |
8655 EXPECT_FALSE(r->is_pending()); | |
8656 EXPECT_EQ(1, d.response_started_count()); | |
8657 EXPECT_FALSE(d.received_data_before_response()); | |
8658 EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); | |
8659 } | |
8660 } | |
8661 | |
8662 // Flaky, see http://crbug.com/25045. | |
8663 TEST_F(URLRequestTestFTP, DISABLED_FTPCheckWrongUser) { | |
8664 ASSERT_TRUE(test_server_.Start()); | |
8665 | |
8666 base::FilePath app_path; | |
8667 PathService::Get(base::DIR_SOURCE_ROOT, &app_path); | |
8668 app_path = app_path.AppendASCII("LICENSE"); | |
8669 TestDelegate d; | |
8670 { | |
8671 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
8672 test_server_.GetURLWithUserAndPassword("/LICENSE", "wrong_user", | |
8673 "chrome"), | |
8674 DEFAULT_PRIORITY, &d, NULL)); | |
8675 r->Start(); | |
8676 EXPECT_TRUE(r->is_pending()); | |
8677 | |
8678 base::RunLoop().Run(); | |
8679 | |
8680 int64 file_size = 0; | |
8681 base::GetFileSize(app_path, &file_size); | |
8682 | |
8683 EXPECT_FALSE(r->is_pending()); | |
8684 EXPECT_EQ(1, d.response_started_count()); | |
8685 EXPECT_FALSE(d.received_data_before_response()); | |
8686 EXPECT_EQ(d.bytes_received(), 0); | |
8687 } | |
8688 } | |
8689 | |
8690 // Flaky, see http://crbug.com/25045. | |
8691 TEST_F(URLRequestTestFTP, DISABLED_FTPCheckWrongUserRestart) { | |
8692 ASSERT_TRUE(test_server_.Start()); | |
8693 | |
8694 base::FilePath app_path; | |
8695 PathService::Get(base::DIR_SOURCE_ROOT, &app_path); | |
8696 app_path = app_path.AppendASCII("LICENSE"); | |
8697 TestDelegate d; | |
8698 // Set correct login credentials. The delegate will be asked for them when | |
8699 // the initial login with wrong credentials will fail. | |
8700 d.set_credentials(AuthCredentials(kChrome, kChrome)); | |
8701 { | |
8702 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
8703 test_server_.GetURLWithUserAndPassword("/LICENSE", "wrong_user", | |
8704 "chrome"), | |
8705 DEFAULT_PRIORITY, &d, NULL)); | |
8706 r->Start(); | |
8707 EXPECT_TRUE(r->is_pending()); | |
8708 | |
8709 base::RunLoop().Run(); | |
8710 | |
8711 int64 file_size = 0; | |
8712 base::GetFileSize(app_path, &file_size); | |
8713 | |
8714 EXPECT_FALSE(r->is_pending()); | |
8715 EXPECT_EQ(1, d.response_started_count()); | |
8716 EXPECT_FALSE(d.received_data_before_response()); | |
8717 EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size)); | |
8718 } | |
8719 } | |
8720 | |
8721 // Flaky, see http://crbug.com/25045. | |
8722 TEST_F(URLRequestTestFTP, DISABLED_FTPCacheURLCredentials) { | |
8723 ASSERT_TRUE(test_server_.Start()); | |
8724 | |
8725 base::FilePath app_path; | |
8726 PathService::Get(base::DIR_SOURCE_ROOT, &app_path); | |
8727 app_path = app_path.AppendASCII("LICENSE"); | |
8728 | |
8729 scoped_ptr<TestDelegate> d(new TestDelegate); | |
8730 { | |
8731 // Pass correct login identity in the URL. | |
8732 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
8733 test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome", "chrome"), | |
8734 DEFAULT_PRIORITY, d.get(), NULL)); | |
8735 r->Start(); | |
8736 EXPECT_TRUE(r->is_pending()); | |
8737 | |
8738 base::RunLoop().Run(); | |
8739 | |
8740 int64 file_size = 0; | |
8741 base::GetFileSize(app_path, &file_size); | |
8742 | |
8743 EXPECT_FALSE(r->is_pending()); | |
8744 EXPECT_EQ(1, d->response_started_count()); | |
8745 EXPECT_FALSE(d->received_data_before_response()); | |
8746 EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); | |
8747 } | |
8748 | |
8749 d.reset(new TestDelegate); | |
8750 { | |
8751 // This request should use cached identity from previous request. | |
8752 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
8753 test_server_.GetURL("/LICENSE"), DEFAULT_PRIORITY, d.get(), NULL)); | |
8754 r->Start(); | |
8755 EXPECT_TRUE(r->is_pending()); | |
8756 | |
8757 base::RunLoop().Run(); | |
8758 | |
8759 int64 file_size = 0; | |
8760 base::GetFileSize(app_path, &file_size); | |
8761 | |
8762 EXPECT_FALSE(r->is_pending()); | |
8763 EXPECT_EQ(1, d->response_started_count()); | |
8764 EXPECT_FALSE(d->received_data_before_response()); | |
8765 EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); | |
8766 } | |
8767 } | |
8768 | |
8769 // Flaky, see http://crbug.com/25045. | |
8770 TEST_F(URLRequestTestFTP, DISABLED_FTPCacheLoginBoxCredentials) { | |
8771 ASSERT_TRUE(test_server_.Start()); | |
8772 | |
8773 base::FilePath app_path; | |
8774 PathService::Get(base::DIR_SOURCE_ROOT, &app_path); | |
8775 app_path = app_path.AppendASCII("LICENSE"); | |
8776 | |
8777 scoped_ptr<TestDelegate> d(new TestDelegate); | |
8778 // Set correct login credentials. The delegate will be asked for them when | |
8779 // the initial login with wrong credentials will fail. | |
8780 d->set_credentials(AuthCredentials(kChrome, kChrome)); | |
8781 { | |
8782 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
8783 test_server_.GetURLWithUserAndPassword("/LICENSE", "chrome", | |
8784 "wrong_password"), | |
8785 DEFAULT_PRIORITY, d.get(), NULL)); | |
8786 r->Start(); | |
8787 EXPECT_TRUE(r->is_pending()); | |
8788 | |
8789 base::RunLoop().Run(); | |
8790 | |
8791 int64 file_size = 0; | |
8792 base::GetFileSize(app_path, &file_size); | |
8793 | |
8794 EXPECT_FALSE(r->is_pending()); | |
8795 EXPECT_EQ(1, d->response_started_count()); | |
8796 EXPECT_FALSE(d->received_data_before_response()); | |
8797 EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); | |
8798 } | |
8799 | |
8800 // Use a new delegate without explicit credentials. The cached ones should be | |
8801 // used. | |
8802 d.reset(new TestDelegate); | |
8803 { | |
8804 // Don't pass wrong credentials in the URL, they would override valid cached | |
8805 // ones. | |
8806 scoped_ptr<URLRequest> r(default_context_.CreateRequest( | |
8807 test_server_.GetURL("/LICENSE"), DEFAULT_PRIORITY, d.get(), NULL)); | |
8808 r->Start(); | |
8809 EXPECT_TRUE(r->is_pending()); | |
8810 | |
8811 base::RunLoop().Run(); | |
8812 | |
8813 int64 file_size = 0; | |
8814 base::GetFileSize(app_path, &file_size); | |
8815 | |
8816 EXPECT_FALSE(r->is_pending()); | |
8817 EXPECT_EQ(1, d->response_started_count()); | |
8818 EXPECT_FALSE(d->received_data_before_response()); | |
8819 EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); | |
8820 } | |
8821 } | |
8822 #endif // !defined(DISABLE_FTP_SUPPORT) | |
8823 | |
8824 } // namespace net | |
OLD | NEW |