Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(443)

Side by Side Diff: net/url_request/url_request_unittest.cc

Issue 154473002: Support redirectUrl at onHeadersReceived in WebRequest / DWR API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add more tests Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« net/url_request/url_request_http_job.cc ('K') | « net/url_request/url_request_http_job.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698