OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <windows.h> | 8 #include <windows.h> |
9 #include <shlobj.h> | 9 #include <shlobj.h> |
10 #endif | 10 #endif |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
331 ASSERT_NE(AUTH_REQUIRED_RESPONSE_IO_PENDING, auth_retval); | 331 ASSERT_NE(AUTH_REQUIRED_RESPONSE_IO_PENDING, auth_retval); |
332 auth_retval_ = auth_retval; | 332 auth_retval_ = auth_retval; |
333 } | 333 } |
334 void set_auth_credentials(const AuthCredentials& auth_credentials) { | 334 void set_auth_credentials(const AuthCredentials& auth_credentials) { |
335 auth_credentials_ = auth_credentials; | 335 auth_credentials_ = auth_credentials; |
336 } | 336 } |
337 | 337 |
338 void set_redirect_url(const GURL& url) { | 338 void set_redirect_url(const GURL& url) { |
339 redirect_url_ = url; | 339 redirect_url_ = url; |
340 } | 340 } |
341 void set_redirect_url_on_headers_received(const GURL& url) { | |
342 redirect_url_on_headers_received_ = url; | |
343 } | |
341 | 344 |
342 void set_block_on(int block_on) { | 345 void set_block_on(int block_on) { |
343 block_on_ = block_on; | 346 block_on_ = block_on; |
344 } | 347 } |
345 | 348 |
346 // Allows the user to check in which state did we block. | 349 // Allows the user to check in which state did we block. |
347 Stage stage_blocked_for_callback() const { | 350 Stage stage_blocked_for_callback() const { |
348 EXPECT_EQ(USER_CALLBACK, block_mode_); | 351 EXPECT_EQ(USER_CALLBACK, block_mode_); |
349 return stage_blocked_for_callback_; | 352 return stage_blocked_for_callback_; |
350 } | 353 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
383 int MaybeBlockStage(Stage stage, const CompletionCallback& callback); | 386 int MaybeBlockStage(Stage stage, const CompletionCallback& callback); |
384 | 387 |
385 // Configuration parameters, can be adjusted by public methods: | 388 // Configuration parameters, can be adjusted by public methods: |
386 const BlockMode block_mode_; | 389 const BlockMode block_mode_; |
387 | 390 |
388 // Values returned on blocking stages when mode is SYNCHRONOUS or | 391 // Values returned on blocking stages when mode is SYNCHRONOUS or |
389 // AUTO_CALLBACK. For USER_CALLBACK these are set automatically to IO_PENDING. | 392 // AUTO_CALLBACK. For USER_CALLBACK these are set automatically to IO_PENDING. |
390 int retval_; // To be returned in non-auth stages. | 393 int retval_; // To be returned in non-auth stages. |
391 AuthRequiredResponse auth_retval_; | 394 AuthRequiredResponse auth_retval_; |
392 | 395 |
393 GURL redirect_url_; // Used if non-empty. | 396 GURL redirect_url_; // Used if non-empty during OnBeforeURLRequest. |
397 GURL redirect_url_on_headers_received_; // Used if non-empty. | |
394 int block_on_; // Bit mask: in which stages to block. | 398 int block_on_; // Bit mask: in which stages to block. |
395 | 399 |
396 // |auth_credentials_| will be copied to |*target_auth_credential_| on | 400 // |auth_credentials_| will be copied to |*target_auth_credential_| on |
397 // callback. | 401 // callback. |
398 AuthCredentials auth_credentials_; | 402 AuthCredentials auth_credentials_; |
399 AuthCredentials* target_auth_credentials_; | 403 AuthCredentials* target_auth_credentials_; |
400 | 404 |
401 // Internal variables, not set by not the user: | 405 // Internal variables, not set by not the user: |
402 // Last blocked stage waiting for user callback (unused if |block_mode_| != | 406 // Last blocked stage waiting for user callback (unused if |block_mode_| != |
403 // USER_CALLBACK). | 407 // USER_CALLBACK). |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
480 | 484 |
481 int BlockingNetworkDelegate::OnHeadersReceived( | 485 int BlockingNetworkDelegate::OnHeadersReceived( |
482 URLRequest* request, | 486 URLRequest* request, |
483 const CompletionCallback& callback, | 487 const CompletionCallback& callback, |
484 const HttpResponseHeaders* original_response_headers, | 488 const HttpResponseHeaders* original_response_headers, |
485 scoped_refptr<HttpResponseHeaders>* override_response_headers) { | 489 scoped_refptr<HttpResponseHeaders>* override_response_headers) { |
486 TestNetworkDelegate::OnHeadersReceived( | 490 TestNetworkDelegate::OnHeadersReceived( |
487 request, callback, original_response_headers, | 491 request, callback, original_response_headers, |
488 override_response_headers); | 492 override_response_headers); |
489 | 493 |
494 // Redirects to the same URL are allowed, but for simplicity, assume that | |
495 // the tests only redirect to a different URL. | |
496 if (!redirect_url_on_headers_received_.is_empty() && | |
497 redirect_url_on_headers_received_ != request->url()) { | |
mmenke
2014/03/20 15:22:25
Suggest resetting redirect_url_on_headers_received
| |
498 if (override_response_headers->get() == NULL) { | |
499 *override_response_headers = new net::HttpResponseHeaders( | |
500 original_response_headers->raw_headers()); | |
501 } | |
502 (*override_response_headers)->SetSafeRedirect( | |
503 redirect_url_on_headers_received_); | |
504 } | |
505 | |
490 return MaybeBlockStage(ON_HEADERS_RECEIVED, callback); | 506 return MaybeBlockStage(ON_HEADERS_RECEIVED, callback); |
491 } | 507 } |
492 | 508 |
493 NetworkDelegate::AuthRequiredResponse BlockingNetworkDelegate::OnAuthRequired( | 509 NetworkDelegate::AuthRequiredResponse BlockingNetworkDelegate::OnAuthRequired( |
494 URLRequest* request, | 510 URLRequest* request, |
495 const AuthChallengeInfo& auth_info, | 511 const AuthChallengeInfo& auth_info, |
496 const AuthCallback& callback, | 512 const AuthCallback& callback, |
497 AuthCredentials* credentials) { | 513 AuthCredentials* credentials) { |
498 TestNetworkDelegate::OnAuthRequired(request, auth_info, callback, | 514 TestNetworkDelegate::OnAuthRequired(request, auth_info, callback, |
499 credentials); | 515 credentials); |
(...skipping 2189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2689 EXPECT_TRUE(test_server_.Stop()); | 2705 EXPECT_TRUE(test_server_.Stop()); |
2690 EXPECT_TRUE(test_server_.Start()); | 2706 EXPECT_TRUE(test_server_.Start()); |
2691 } | 2707 } |
2692 | 2708 |
2693 return is_success; | 2709 return is_success; |
2694 } | 2710 } |
2695 | 2711 |
2696 LocalHttpTestServer test_server_; | 2712 LocalHttpTestServer test_server_; |
2697 }; | 2713 }; |
2698 | 2714 |
2715 // Unsafe URL that has been marked as safe in OverrideRedirectNetworkDelegate. | |
mmenke
2014/03/20 15:22:25
This stuff (class and globals) should be in an ano
| |
2716 const char kUnsafeUrlMarkedAsSafe[] = "data:text/html,something"; | |
mmenke
2014/03/20 15:22:25
nit: Blank line before class definition.
optiona
| |
2717 // OverrideRedirectNetworkDelegate first redirects to |redirect_url1|, then to | |
2718 // |redirect_url2| (if set). | |
mmenke
2014/03/20 15:22:25
Fix description.
| |
2719 class OverrideRedirectNetworkDelegate : public TestNetworkDelegate { | |
mmenke
2014/03/20 15:22:25
Suggest a clearer name. Maybe "RedirectOnHeadersR
| |
2720 public: | |
2721 explicit OverrideRedirectNetworkDelegate(const GURL& redirect_url) | |
2722 : redirect_url_(redirect_url) {} | |
2723 virtual ~OverrideRedirectNetworkDelegate() {} | |
2724 | |
2725 // net::NetworkDelegate implementation | |
2726 virtual int OnHeadersReceived( | |
2727 net::URLRequest* request, | |
2728 const net::CompletionCallback& callback, | |
2729 const net::HttpResponseHeaders* original_response_headers, | |
2730 scoped_refptr<net::HttpResponseHeaders>* override_response_headers) | |
2731 OVERRIDE; | |
2732 | |
2733 private: | |
2734 GURL redirect_url_; | |
2735 | |
2736 DISALLOW_COPY_AND_ASSIGN(OverrideRedirectNetworkDelegate); | |
2737 }; | |
2738 | |
2739 int OverrideRedirectNetworkDelegate::OnHeadersReceived( | |
2740 net::URLRequest* request, | |
2741 const net::CompletionCallback& callback, | |
2742 const net::HttpResponseHeaders* original_response_headers, | |
2743 scoped_refptr<net::HttpResponseHeaders>* override_response_headers) { | |
2744 | |
2745 if (redirect_url_ != request->url()) { | |
2746 net::HttpResponseHeaders* new_response_headers = | |
2747 new net::HttpResponseHeaders(original_response_headers->raw_headers()); | |
2748 | |
2749 new_response_headers->SetSafeRedirect(GURL(kUnsafeUrlMarkedAsSafe)); | |
2750 new_response_headers->RemoveHeader("Location"); | |
2751 new_response_headers->AddHeader("Location: " + redirect_url_.spec()); | |
2752 | |
2753 *override_response_headers = new_response_headers; | |
2754 } | |
2755 return TestNetworkDelegate::OnHeadersReceived(request, | |
2756 callback, | |
2757 original_response_headers, | |
2758 override_response_headers); | |
2759 } | |
2760 | |
2761 // Tests that replacing the allowed redirect URL is preserved when the | |
2762 // Location header has been overwritten. | |
2763 TEST_F(URLRequestTestHTTP, UnsafeRedirectToWhitelistedUnsafeURL) { | |
2764 ASSERT_TRUE(test_server_.Start()); | |
2765 | |
2766 GURL unsafe_redirect_url(kUnsafeUrlMarkedAsSafe); | |
2767 OverrideRedirectNetworkDelegate network_delegate(unsafe_redirect_url); | |
2768 default_context_.set_network_delegate(&network_delegate); | |
2769 TestDelegate d; | |
2770 { | |
2771 URLRequest r(test_server_.GetURL("empty.html"), | |
2772 DEFAULT_PRIORITY, | |
2773 &d, | |
2774 &default_context_); | |
2775 | |
2776 r.Start(); | |
2777 base::RunLoop().Run(); | |
2778 | |
2779 EXPECT_EQ(URLRequestStatus::SUCCESS, r.status().status()); | |
2780 | |
2781 EXPECT_EQ(2U, r.url_chain().size()); | |
2782 EXPECT_EQ(0, r.status().error()); | |
2783 EXPECT_EQ(unsafe_redirect_url, r.url()); | |
2784 } | |
2785 } | |
2786 | |
2787 // Tests that a redirect to a different unsafe URL is blocked, even after adding | |
2788 // some other URL to the whitelist. | |
2789 TEST_F(URLRequestTestHTTP, UnsafeRedirectToDifferentUnsafeURL) { | |
2790 ASSERT_TRUE(test_server_.Start()); | |
2791 | |
2792 GURL unsafe_redirect_url("data:text/html,something-else"); | |
2793 OverrideRedirectNetworkDelegate network_delegate(unsafe_redirect_url); | |
2794 default_context_.set_network_delegate(&network_delegate); | |
2795 TestDelegate d; | |
2796 { | |
2797 URLRequest r(test_server_.GetURL("empty.html"), | |
2798 DEFAULT_PRIORITY, | |
2799 &d, | |
2800 &default_context_); | |
2801 | |
2802 r.Start(); | |
2803 base::RunLoop().Run(); | |
2804 | |
2805 EXPECT_EQ(URLRequestStatus::FAILED, r.status().status()); | |
2806 EXPECT_EQ(ERR_UNSAFE_REDIRECT, r.status().error()); | |
2807 } | |
2808 } | |
2809 | |
2810 // Tests that a redirect to a safe URL is allowed, regardless of whether an | |
2811 // unsafe URL was whitelisted. | |
2812 TEST_F(URLRequestTestHTTP, UnsafeRedirectToSafeURL) { | |
2813 ASSERT_TRUE(test_server_.Start()); | |
2814 | |
2815 GURL safe_url(test_server_.GetURL("simple.html")); | |
2816 OverrideRedirectNetworkDelegate network_delegate(safe_url); | |
2817 default_context_.set_network_delegate(&network_delegate); | |
2818 TestDelegate d; | |
2819 { | |
2820 URLRequest r(test_server_.GetURL("empty.html"), | |
2821 DEFAULT_PRIORITY, | |
2822 &d, | |
2823 &default_context_); | |
2824 | |
2825 r.Start(); | |
2826 base::RunLoop().Run(); | |
2827 | |
2828 EXPECT_EQ(2U, r.url_chain().size()); | |
2829 EXPECT_EQ(URLRequestStatus::SUCCESS, r.status().status()); | |
2830 EXPECT_EQ(0, r.status().error()); | |
2831 EXPECT_EQ(safe_url, r.url()); | |
mmenke
2014/03/20 15:22:25
Suggest testing the response body, too, for comple
| |
2832 } | |
2833 } | |
mmenke
2014/03/20 15:22:25
Hmm...Can we have a double invalid redirect? Redi
robwu
2014/03/20 16:21:11
Only HTTP responses can be redirected at onHeaders
mmenke
2014/03/20 16:40:28
And we always allow redirects to HTTP/HTTPS, of co
| |
2834 | |
2699 // In this unit test, we're using the HTTPTestServer as a proxy server and | 2835 // In this unit test, we're using the HTTPTestServer as a proxy server and |
2700 // issuing a CONNECT request with the magic host name "www.redirect.com". | 2836 // issuing a CONNECT request with the magic host name "www.redirect.com". |
2701 // The HTTPTestServer will return a 302 response, which we should not | 2837 // The HTTPTestServer will return a 302 response, which we should not |
2702 // follow. | 2838 // follow. |
2703 TEST_F(URLRequestTestHTTP, ProxyTunnelRedirectTest) { | 2839 TEST_F(URLRequestTestHTTP, ProxyTunnelRedirectTest) { |
2704 ASSERT_TRUE(test_server_.Start()); | 2840 ASSERT_TRUE(test_server_.Start()); |
2705 | 2841 |
2706 TestNetworkDelegate network_delegate; // Must outlive URLRequest. | 2842 TestNetworkDelegate network_delegate; // Must outlive URLRequest. |
2707 TestURLRequestContextWithProxy context( | 2843 TestURLRequestContextWithProxy context( |
2708 test_server_.host_port_pair().ToString(), &network_delegate); | 2844 test_server_.host_port_pair().ToString(), &network_delegate); |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3000 EXPECT_EQ(original_url, r.original_url()); | 3136 EXPECT_EQ(original_url, r.original_url()); |
3001 EXPECT_EQ(2U, r.url_chain().size()); | 3137 EXPECT_EQ(2U, r.url_chain().size()); |
3002 EXPECT_EQ(1, network_delegate.created_requests()); | 3138 EXPECT_EQ(1, network_delegate.created_requests()); |
3003 EXPECT_EQ(0, network_delegate.destroyed_requests()); | 3139 EXPECT_EQ(0, network_delegate.destroyed_requests()); |
3004 EXPECT_EQ("POST", r.method()); | 3140 EXPECT_EQ("POST", r.method()); |
3005 EXPECT_EQ(kData, d.data_received()); | 3141 EXPECT_EQ(kData, d.data_received()); |
3006 } | 3142 } |
3007 EXPECT_EQ(1, network_delegate.destroyed_requests()); | 3143 EXPECT_EQ(1, network_delegate.destroyed_requests()); |
3008 } | 3144 } |
3009 | 3145 |
3146 // Tests that the network delegate can block and redirect a request to a new | |
3147 // URL during OnHeadersReceived. | |
3148 TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestOnHeadersReceived) { | |
3149 ASSERT_TRUE(test_server_.Start()); | |
3150 | |
3151 TestDelegate d; | |
3152 BlockingNetworkDelegate network_delegate( | |
3153 BlockingNetworkDelegate::AUTO_CALLBACK); | |
3154 network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED); | |
3155 GURL redirect_url(test_server_.GetURL("simple.html")); | |
3156 network_delegate.set_redirect_url_on_headers_received(redirect_url); | |
3157 | |
3158 TestURLRequestContextWithProxy context( | |
3159 test_server_.host_port_pair().ToString(), &network_delegate); | |
3160 | |
3161 { | |
3162 GURL original_url(test_server_.GetURL("empty.html")); | |
3163 URLRequest r(original_url, DEFAULT_PRIORITY, &d, &context); | |
3164 | |
3165 r.Start(); | |
3166 base::RunLoop().Run(); | |
3167 | |
3168 EXPECT_EQ(URLRequestStatus::SUCCESS, r.status().status()); | |
3169 EXPECT_EQ(0, r.status().error()); | |
3170 EXPECT_EQ(redirect_url, r.url()); | |
3171 EXPECT_EQ(original_url, r.original_url()); | |
3172 EXPECT_EQ(2U, r.url_chain().size()); | |
3173 EXPECT_EQ(2, network_delegate.created_requests()); | |
3174 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3175 } | |
3176 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3177 } | |
3178 | |
3179 // Tests that redirects caused by the network delegate during OnHeadersReceived | |
3180 // preserve POST data. | |
3181 TEST_F(URLRequestTestHTTP, | |
3182 NetworkDelegateRedirectRequestOnHeadersReceivedPost) { | |
3183 ASSERT_TRUE(test_server_.Start()); | |
3184 | |
3185 const char kData[] = "hello world"; | |
3186 | |
3187 TestDelegate d; | |
3188 BlockingNetworkDelegate network_delegate( | |
3189 BlockingNetworkDelegate::AUTO_CALLBACK); | |
3190 network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED); | |
3191 GURL redirect_url(test_server_.GetURL("echo")); | |
3192 network_delegate.set_redirect_url_on_headers_received(redirect_url); | |
3193 | |
3194 TestURLRequestContext context(true); | |
3195 context.set_network_delegate(&network_delegate); | |
3196 context.Init(); | |
3197 | |
3198 { | |
3199 GURL original_url(test_server_.GetURL("empty.html")); | |
3200 URLRequest r(original_url, DEFAULT_PRIORITY, &d, &context); | |
3201 r.set_method("POST"); | |
3202 r.set_upload(make_scoped_ptr(CreateSimpleUploadData(kData))); | |
3203 HttpRequestHeaders headers; | |
3204 headers.SetHeader(HttpRequestHeaders::kContentLength, | |
3205 base::UintToString(arraysize(kData) - 1)); | |
3206 r.SetExtraRequestHeaders(headers); | |
3207 r.Start(); | |
3208 base::RunLoop().Run(); | |
3209 | |
3210 EXPECT_EQ(URLRequestStatus::SUCCESS, r.status().status()); | |
3211 EXPECT_EQ(0, r.status().error()); | |
3212 EXPECT_EQ(redirect_url, r.url()); | |
3213 EXPECT_EQ(original_url, r.original_url()); | |
3214 EXPECT_EQ(2U, r.url_chain().size()); | |
3215 EXPECT_EQ(2, network_delegate.created_requests()); | |
3216 EXPECT_EQ(0, network_delegate.destroyed_requests()); | |
3217 EXPECT_EQ("POST", r.method()); | |
3218 EXPECT_EQ(kData, d.data_received()); | |
3219 } | |
3220 EXPECT_EQ(1, network_delegate.destroyed_requests()); | |
3221 } | |
3222 | |
3010 // Tests that the network delegate can synchronously complete OnAuthRequired | 3223 // Tests that the network delegate can synchronously complete OnAuthRequired |
3011 // by taking no action. This indicates that the NetworkDelegate does not want to | 3224 // by taking no action. This indicates that the NetworkDelegate does not want to |
3012 // handle the challenge, and is passing the buck along to the | 3225 // handle the challenge, and is passing the buck along to the |
3013 // URLRequest::Delegate. | 3226 // URLRequest::Delegate. |
3014 TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncNoAction) { | 3227 TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncNoAction) { |
3015 ASSERT_TRUE(test_server_.Start()); | 3228 ASSERT_TRUE(test_server_.Start()); |
3016 | 3229 |
3017 TestDelegate d; | 3230 TestDelegate d; |
3018 BlockingNetworkDelegate network_delegate( | 3231 BlockingNetworkDelegate network_delegate( |
3019 BlockingNetworkDelegate::SYNCHRONOUS); | 3232 BlockingNetworkDelegate::SYNCHRONOUS); |
(...skipping 4573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7593 | 7806 |
7594 EXPECT_FALSE(r.is_pending()); | 7807 EXPECT_FALSE(r.is_pending()); |
7595 EXPECT_EQ(1, d->response_started_count()); | 7808 EXPECT_EQ(1, d->response_started_count()); |
7596 EXPECT_FALSE(d->received_data_before_response()); | 7809 EXPECT_FALSE(d->received_data_before_response()); |
7597 EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); | 7810 EXPECT_EQ(d->bytes_received(), static_cast<int>(file_size)); |
7598 } | 7811 } |
7599 } | 7812 } |
7600 #endif // !defined(DISABLE_FTP_SUPPORT) | 7813 #endif // !defined(DISABLE_FTP_SUPPORT) |
7601 | 7814 |
7602 } // namespace net | 7815 } // namespace net |
OLD | NEW |