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 <queue> |
| 6 #include <string> |
5 #include <vector> | 7 #include <vector> |
6 | 8 |
7 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
8 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/callback.h" |
9 #include "base/command_line.h" | 12 #include "base/command_line.h" |
10 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
11 #include "base/files/file_util.h" | 14 #include "base/files/file_util.h" |
12 #include "base/location.h" | 15 #include "base/location.h" |
| 16 #include "base/macros.h" |
| 17 #include "base/memory/scoped_ptr.h" |
13 #include "base/memory/scoped_vector.h" | 18 #include "base/memory/scoped_vector.h" |
14 #include "base/memory/shared_memory.h" | 19 #include "base/memory/shared_memory.h" |
15 #include "base/pickle.h" | 20 #include "base/pickle.h" |
16 #include "base/run_loop.h" | 21 #include "base/run_loop.h" |
17 #include "base/single_thread_task_runner.h" | 22 #include "base/single_thread_task_runner.h" |
18 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
19 #include "base/strings/string_split.h" | 24 #include "base/strings/string_split.h" |
20 #include "base/thread_task_runner_handle.h" | 25 #include "base/thread_task_runner_handle.h" |
21 #include "content/browser/browser_thread_impl.h" | 26 #include "content/browser/browser_thread_impl.h" |
22 #include "content/browser/child_process_security_policy_impl.h" | 27 #include "content/browser/child_process_security_policy_impl.h" |
(...skipping 17 matching lines...) Expand all Loading... |
40 #include "content/public/browser/web_contents_observer.h" | 45 #include "content/public/browser/web_contents_observer.h" |
41 #include "content/public/common/child_process_host.h" | 46 #include "content/public/common/child_process_host.h" |
42 #include "content/public/common/content_switches.h" | 47 #include "content/public/common/content_switches.h" |
43 #include "content/public/common/process_type.h" | 48 #include "content/public/common/process_type.h" |
44 #include "content/public/common/resource_response.h" | 49 #include "content/public/common/resource_response.h" |
45 #include "content/public/test/test_browser_context.h" | 50 #include "content/public/test/test_browser_context.h" |
46 #include "content/public/test/test_browser_thread_bundle.h" | 51 #include "content/public/test/test_browser_thread_bundle.h" |
47 #include "content/public/test/test_renderer_host.h" | 52 #include "content/public/test/test_renderer_host.h" |
48 #include "content/test/test_content_browser_client.h" | 53 #include "content/test/test_content_browser_client.h" |
49 #include "net/base/elements_upload_data_stream.h" | 54 #include "net/base/elements_upload_data_stream.h" |
| 55 #include "net/base/load_flags.h" |
50 #include "net/base/net_errors.h" | 56 #include "net/base/net_errors.h" |
51 #include "net/base/request_priority.h" | 57 #include "net/base/request_priority.h" |
52 #include "net/base/upload_bytes_element_reader.h" | 58 #include "net/base/upload_bytes_element_reader.h" |
| 59 #include "net/http/http_response_headers.h" |
| 60 #include "net/http/http_response_info.h" |
53 #include "net/http/http_util.h" | 61 #include "net/http/http_util.h" |
54 #include "net/url_request/url_request.h" | 62 #include "net/url_request/url_request.h" |
55 #include "net/url_request/url_request_context.h" | 63 #include "net/url_request/url_request_context.h" |
56 #include "net/url_request/url_request_job.h" | 64 #include "net/url_request/url_request_job.h" |
57 #include "net/url_request/url_request_job_factory.h" | 65 #include "net/url_request/url_request_job_factory.h" |
58 #include "net/url_request/url_request_simple_job.h" | 66 #include "net/url_request/url_request_simple_job.h" |
59 #include "net/url_request/url_request_test_job.h" | 67 #include "net/url_request/url_request_test_job.h" |
60 #include "net/url_request/url_request_test_util.h" | 68 #include "net/url_request/url_request_test_util.h" |
61 #include "storage/browser/blob/shareable_file_reference.h" | 69 #include "storage/browser/blob/shareable_file_reference.h" |
62 #include "testing/gtest/include/gtest/gtest.h" | 70 #include "testing/gtest/include/gtest/gtest.h" |
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 net::LoadState load_state; | 831 net::LoadState load_state; |
824 net::UploadProgress upload_progress; | 832 net::UploadProgress upload_progress; |
825 }; | 833 }; |
826 | 834 |
827 class ResourceDispatcherHostTest : public testing::Test, | 835 class ResourceDispatcherHostTest : public testing::Test, |
828 public IPC::Sender { | 836 public IPC::Sender { |
829 public: | 837 public: |
830 typedef ResourceDispatcherHostImpl::LoadInfo LoadInfo; | 838 typedef ResourceDispatcherHostImpl::LoadInfo LoadInfo; |
831 typedef ResourceDispatcherHostImpl::LoadInfoMap LoadInfoMap; | 839 typedef ResourceDispatcherHostImpl::LoadInfoMap LoadInfoMap; |
832 | 840 |
833 ResourceDispatcherHostTest() | 841 ResourceDispatcherHostTest( |
| 842 scoped_ptr<net::TestNetworkDelegate> network_delegate) |
834 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), | 843 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), |
| 844 network_delegate_(network_delegate.Pass()), |
835 old_factory_(NULL), | 845 old_factory_(NULL), |
836 send_data_received_acks_(false) { | 846 send_data_received_acks_(false) { |
837 browser_context_.reset(new TestBrowserContext()); | 847 browser_context_.reset(new TestBrowserContext()); |
838 BrowserContext::EnsureResourceContextInitialized(browser_context_.get()); | 848 BrowserContext::EnsureResourceContextInitialized(browser_context_.get()); |
839 base::RunLoop().RunUntilIdle(); | 849 base::RunLoop().RunUntilIdle(); |
840 filter_ = MakeForwardingFilter(); | 850 filter_ = MakeForwardingFilter(); |
841 // TODO(cbentzel): Better way to get URLRequestContext? | 851 // TODO(cbentzel): Better way to get URLRequestContext? |
842 net::URLRequestContext* request_context = | 852 net::URLRequestContext* request_context = |
843 browser_context_->GetResourceContext()->GetRequestContext(); | 853 browser_context_->GetResourceContext()->GetRequestContext(); |
844 job_factory_.reset(new TestURLRequestJobFactory(this)); | 854 job_factory_.reset(new TestURLRequestJobFactory(this)); |
845 request_context->set_job_factory(job_factory_.get()); | 855 request_context->set_job_factory(job_factory_.get()); |
846 request_context->set_network_delegate(&network_delegate_); | 856 request_context->set_network_delegate(network_delegate_.get()); |
| 857 // TODO(ricea): Remove this when it becomes the default. |
| 858 host_.async_revalidation_enabled_ = true; |
847 } | 859 } |
848 | 860 |
| 861 ResourceDispatcherHostTest() |
| 862 : ResourceDispatcherHostTest( |
| 863 make_scoped_ptr(new net::TestNetworkDelegate)) {} |
| 864 |
849 // IPC::Sender implementation | 865 // IPC::Sender implementation |
850 bool Send(IPC::Message* msg) override { | 866 bool Send(IPC::Message* msg) override { |
851 accum_.AddMessage(*msg); | 867 accum_.AddMessage(*msg); |
852 | 868 |
853 if (send_data_received_acks_ && | 869 if (send_data_received_acks_ && |
854 msg->type() == ResourceMsg_DataReceived::ID) { | 870 msg->type() == ResourceMsg_DataReceived::ID) { |
855 GenerateDataReceivedACK(*msg); | 871 GenerateDataReceivedACK(*msg); |
856 } | 872 } |
857 | 873 |
858 if (wait_for_request_complete_loop_ && | 874 if (wait_for_request_complete_loop_ && |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
954 void CancelRequest(int request_id); | 970 void CancelRequest(int request_id); |
955 void RendererCancelRequest(int request_id) { | 971 void RendererCancelRequest(int request_id) { |
956 ResourceMessageFilter* old_filter = SetFilter(filter_.get()); | 972 ResourceMessageFilter* old_filter = SetFilter(filter_.get()); |
957 host_.OnCancelRequest(request_id); | 973 host_.OnCancelRequest(request_id); |
958 SetFilter(old_filter); | 974 SetFilter(old_filter); |
959 } | 975 } |
960 | 976 |
961 void CompleteStartRequest(int request_id); | 977 void CompleteStartRequest(int request_id); |
962 void CompleteStartRequest(ResourceMessageFilter* filter, int request_id); | 978 void CompleteStartRequest(ResourceMessageFilter* filter, int request_id); |
963 | 979 |
964 net::TestNetworkDelegate* network_delegate() { return &network_delegate_; } | 980 net::TestNetworkDelegate* network_delegate() { |
| 981 return network_delegate_.get(); |
| 982 } |
965 | 983 |
966 void EnsureSchemeIsAllowed(const std::string& scheme) { | 984 void EnsureSchemeIsAllowed(const std::string& scheme) { |
967 ChildProcessSecurityPolicyImpl* policy = | 985 ChildProcessSecurityPolicyImpl* policy = |
968 ChildProcessSecurityPolicyImpl::GetInstance(); | 986 ChildProcessSecurityPolicyImpl::GetInstance(); |
969 if (!policy->IsWebSafeScheme(scheme)) | 987 if (!policy->IsWebSafeScheme(scheme)) |
970 policy->RegisterWebSafeScheme(scheme); | 988 policy->RegisterWebSafeScheme(scheme); |
971 } | 989 } |
972 | 990 |
973 // Sets a particular response for any request from now on. To switch back to | 991 // Sets a particular response for any request from now on. To switch back to |
974 // the default bahavior, pass an empty |headers|. |headers| should be raw- | 992 // the default bahavior, pass an empty |headers|. |headers| should be raw- |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1014 return old_filter; | 1032 return old_filter; |
1015 } | 1033 } |
1016 | 1034 |
1017 void WaitForRequestComplete() { | 1035 void WaitForRequestComplete() { |
1018 DCHECK(!wait_for_request_complete_loop_); | 1036 DCHECK(!wait_for_request_complete_loop_); |
1019 wait_for_request_complete_loop_.reset(new base::RunLoop); | 1037 wait_for_request_complete_loop_.reset(new base::RunLoop); |
1020 wait_for_request_complete_loop_->Run(); | 1038 wait_for_request_complete_loop_->Run(); |
1021 wait_for_request_complete_loop_.reset(); | 1039 wait_for_request_complete_loop_.reset(); |
1022 } | 1040 } |
1023 | 1041 |
| 1042 typedef base::Callback<net::URLRequestJob*(net::URLRequest*, |
| 1043 net::NetworkDelegate*)> |
| 1044 URLRequestJobCreateCallback; |
| 1045 |
| 1046 void SetCustomURLRequestJobCreateCallback( |
| 1047 const URLRequestJobCreateCallback& callback) { |
| 1048 custom_url_request_job_create_callback_.reset( |
| 1049 new URLRequestJobCreateCallback(callback)); |
| 1050 } |
| 1051 |
1024 scoped_ptr<LoadInfoTestRequestInfo> loader_test_request_info_; | 1052 scoped_ptr<LoadInfoTestRequestInfo> loader_test_request_info_; |
1025 scoped_ptr<base::RunLoop> wait_for_request_create_loop_; | 1053 scoped_ptr<base::RunLoop> wait_for_request_create_loop_; |
1026 | 1054 |
| 1055 scoped_ptr<URLRequestJobCreateCallback> |
| 1056 custom_url_request_job_create_callback_; |
| 1057 |
1027 content::TestBrowserThreadBundle thread_bundle_; | 1058 content::TestBrowserThreadBundle thread_bundle_; |
1028 scoped_ptr<TestBrowserContext> browser_context_; | 1059 scoped_ptr<TestBrowserContext> browser_context_; |
1029 scoped_ptr<TestURLRequestJobFactory> job_factory_; | 1060 scoped_ptr<TestURLRequestJobFactory> job_factory_; |
1030 scoped_ptr<WebContents> web_contents_; | 1061 scoped_ptr<WebContents> web_contents_; |
1031 scoped_ptr<TestWebContentsObserver> web_contents_observer_; | 1062 scoped_ptr<TestWebContentsObserver> web_contents_observer_; |
1032 scoped_refptr<ForwardingFilter> filter_; | 1063 scoped_refptr<ForwardingFilter> filter_; |
1033 scoped_refptr<TestFilterSpecifyingChild> web_contents_filter_; | 1064 scoped_refptr<TestFilterSpecifyingChild> web_contents_filter_; |
1034 net::TestNetworkDelegate network_delegate_; | 1065 scoped_ptr<net::TestNetworkDelegate> network_delegate_; |
1035 ResourceDispatcherHostImpl host_; | 1066 ResourceDispatcherHostImpl host_; |
1036 ResourceIPCAccumulator accum_; | 1067 ResourceIPCAccumulator accum_; |
1037 std::string response_headers_; | 1068 std::string response_headers_; |
1038 std::string response_data_; | 1069 std::string response_data_; |
1039 std::string scheme_; | 1070 std::string scheme_; |
1040 net::URLRequest::ProtocolFactory* old_factory_; | 1071 net::URLRequest::ProtocolFactory* old_factory_; |
1041 bool send_data_received_acks_; | 1072 bool send_data_received_acks_; |
1042 std::set<int> child_ids_; | 1073 std::set<int> child_ids_; |
1043 scoped_ptr<base::RunLoop> wait_for_request_complete_loop_; | 1074 scoped_ptr<base::RunLoop> wait_for_request_complete_loop_; |
1044 RenderViewHostTestEnabler render_view_host_test_enabler_; | 1075 RenderViewHostTestEnabler render_view_host_test_enabler_; |
(...skipping 2345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3390 url_request_jobs_created_count_++; | 3421 url_request_jobs_created_count_++; |
3391 if (test_fixture_->wait_for_request_create_loop_) | 3422 if (test_fixture_->wait_for_request_create_loop_) |
3392 test_fixture_->wait_for_request_create_loop_->Quit(); | 3423 test_fixture_->wait_for_request_create_loop_->Quit(); |
3393 if (test_fixture_->loader_test_request_info_) { | 3424 if (test_fixture_->loader_test_request_info_) { |
3394 DCHECK_EQ(test_fixture_->loader_test_request_info_->url, request->url()); | 3425 DCHECK_EQ(test_fixture_->loader_test_request_info_->url, request->url()); |
3395 scoped_ptr<LoadInfoTestRequestInfo> info = | 3426 scoped_ptr<LoadInfoTestRequestInfo> info = |
3396 test_fixture_->loader_test_request_info_.Pass(); | 3427 test_fixture_->loader_test_request_info_.Pass(); |
3397 return new URLRequestLoadInfoJob(request, network_delegate, | 3428 return new URLRequestLoadInfoJob(request, network_delegate, |
3398 info->load_state, info->upload_progress); | 3429 info->load_state, info->upload_progress); |
3399 } | 3430 } |
| 3431 if (test_fixture_->custom_url_request_job_create_callback_) { |
| 3432 return test_fixture_->custom_url_request_job_create_callback_->Run( |
| 3433 request, network_delegate); |
| 3434 } |
3400 if (test_fixture_->response_headers_.empty()) { | 3435 if (test_fixture_->response_headers_.empty()) { |
3401 if (delay_start_) { | 3436 if (delay_start_) { |
3402 return new URLRequestTestDelayedStartJob(request, network_delegate); | 3437 return new URLRequestTestDelayedStartJob(request, network_delegate); |
3403 } else if (delay_complete_) { | 3438 } else if (delay_complete_) { |
3404 return new URLRequestTestDelayedCompletionJob(request, | 3439 return new URLRequestTestDelayedCompletionJob(request, |
3405 network_delegate); | 3440 network_delegate); |
3406 } else if (network_start_notification_) { | 3441 } else if (network_start_notification_) { |
3407 return new URLRequestTestDelayedNetworkJob(request, network_delegate); | 3442 return new URLRequestTestDelayedNetworkJob(request, network_delegate); |
3408 } else if (scheme == "big-job") { | 3443 } else if (scheme == "big-job") { |
3409 return new URLRequestBigJob(request, network_delegate); | 3444 return new URLRequestBigJob(request, network_delegate); |
(...skipping 26 matching lines...) Expand all Loading... |
3436 const GURL& location) const { | 3471 const GURL& location) const { |
3437 return nullptr; | 3472 return nullptr; |
3438 } | 3473 } |
3439 | 3474 |
3440 net::URLRequestJob* TestURLRequestJobFactory::MaybeInterceptResponse( | 3475 net::URLRequestJob* TestURLRequestJobFactory::MaybeInterceptResponse( |
3441 net::URLRequest* request, | 3476 net::URLRequest* request, |
3442 net::NetworkDelegate* network_delegate) const { | 3477 net::NetworkDelegate* network_delegate) const { |
3443 return nullptr; | 3478 return nullptr; |
3444 } | 3479 } |
3445 | 3480 |
| 3481 TEST_F(ResourceDispatcherHostTest, SupportsAsyncRevalidation) { |
| 3482 // Scheme has to be HTTP or HTTPS to support async revalidation. |
| 3483 HandleScheme("http"); |
| 3484 // Prevent the job from completing synchronously. |
| 3485 job_factory_->SetDelayedCompleteJobGeneration(true); |
| 3486 SetResponse(net::URLRequestTestJob::test_headers(), "delay complete"); |
| 3487 MakeTestRequest(0, 1, GURL("http://example.com/baz")); |
| 3488 |
| 3489 net::URLRequest* url_request( |
| 3490 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1))); |
| 3491 ASSERT_TRUE(url_request); |
| 3492 |
| 3493 EXPECT_TRUE(url_request->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION); |
| 3494 } |
| 3495 |
| 3496 TEST_F(ResourceDispatcherHostTest, AsyncRevalidationNotSupportedForPOST) { |
| 3497 // Scheme has to be HTTP or HTTPS to support async revalidation. |
| 3498 HandleScheme("http"); |
| 3499 // Prevent the job from completing synchronously. |
| 3500 job_factory_->SetDelayedCompleteJobGeneration(true); |
| 3501 SetResponse(net::URLRequestTestJob::test_headers(), "delay complete"); |
| 3502 // Create POST request. |
| 3503 ResourceHostMsg_Request request = CreateResourceRequest( |
| 3504 "POST", RESOURCE_TYPE_SUB_RESOURCE, GURL("http://example.com/baz.php")); |
| 3505 ResourceHostMsg_RequestResource msg(0, 1, request); |
| 3506 host_.OnMessageReceived(msg, filter_.get()); |
| 3507 KickOffRequest(); |
| 3508 |
| 3509 net::URLRequest* url_request( |
| 3510 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1))); |
| 3511 ASSERT_TRUE(url_request); |
| 3512 |
| 3513 EXPECT_FALSE(url_request->load_flags() & |
| 3514 net::LOAD_SUPPORT_ASYNC_REVALIDATION); |
| 3515 } |
| 3516 |
| 3517 TEST_F(ResourceDispatcherHostTest, AsyncRevalidationNotSupportedForRedirect) { |
| 3518 static const char kRedirectHeaders[] = |
| 3519 "HTTP/1.1 302 MOVED\n" |
| 3520 "Location: http://example.com/var\n" |
| 3521 "\n"; |
| 3522 // Scheme has to be HTTP or HTTPS to support async revalidation. |
| 3523 HandleScheme("http"); |
| 3524 // Prevent the job from completing synchronously. |
| 3525 job_factory_->SetDelayedCompleteJobGeneration(true); |
| 3526 SetResponse(kRedirectHeaders, ""); |
| 3527 |
| 3528 MakeTestRequest(0, 1, GURL("http://example.com/baz")); |
| 3529 |
| 3530 net::URLRequest* url_request( |
| 3531 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1))); |
| 3532 ASSERT_TRUE(url_request); |
| 3533 |
| 3534 EXPECT_FALSE(url_request->load_flags() & |
| 3535 net::LOAD_SUPPORT_ASYNC_REVALIDATION); |
| 3536 } |
| 3537 |
| 3538 // A URLRequestJob implementation which sets the |async_revalidation_required| |
| 3539 // flag on the HttpResponseInfo object to true if the request has the |
| 3540 // LOAD_SUPPORT_ASYNC_REVALIDATION flag. |
| 3541 class AsyncRevalidationRequiredURLRequestTestJob |
| 3542 : public net::URLRequestTestJob { |
| 3543 public: |
| 3544 // The Create() method is useful for wrapping the construction of the object |
| 3545 // in a Callback. |
| 3546 static net::URLRequestJob* Create(net::URLRequest* request, |
| 3547 net::NetworkDelegate* network_delegate) { |
| 3548 return new AsyncRevalidationRequiredURLRequestTestJob(request, |
| 3549 network_delegate); |
| 3550 } |
| 3551 |
| 3552 void GetResponseInfo(net::HttpResponseInfo* info) override { |
| 3553 if (request()->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION) |
| 3554 info->async_revalidation_required = true; |
| 3555 } |
| 3556 |
| 3557 private: |
| 3558 AsyncRevalidationRequiredURLRequestTestJob( |
| 3559 net::URLRequest* request, |
| 3560 net::NetworkDelegate* network_delegate) |
| 3561 : URLRequestTestJob(request, |
| 3562 network_delegate, |
| 3563 net::URLRequestTestJob::test_headers(), |
| 3564 std::string(), |
| 3565 false) {} |
| 3566 |
| 3567 ~AsyncRevalidationRequiredURLRequestTestJob() override {} |
| 3568 |
| 3569 DISALLOW_COPY_AND_ASSIGN(AsyncRevalidationRequiredURLRequestTestJob); |
| 3570 }; |
| 3571 |
| 3572 // A URLRequestJob implementation which serves a redirect and sets the |
| 3573 // |async_revalidation_required| flag on the HttpResponseInfo object to true if |
| 3574 // the request has the LOAD_SUPPORT_ASYNC_REVALIDATION flag. |
| 3575 class RedirectAndRevalidateURLRequestTestJob : public net::URLRequestTestJob { |
| 3576 public: |
| 3577 // The Create() method is useful for wrapping the construction of the object |
| 3578 // in a Callback. |
| 3579 static net::URLRequestJob* Create(net::URLRequest* request, |
| 3580 net::NetworkDelegate* network_delegate) { |
| 3581 return new RedirectAndRevalidateURLRequestTestJob(request, |
| 3582 network_delegate); |
| 3583 } |
| 3584 |
| 3585 void GetResponseInfo(net::HttpResponseInfo* info) override { |
| 3586 URLRequestTestJob::GetResponseInfo(info); |
| 3587 if (request()->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION) |
| 3588 info->async_revalidation_required = true; |
| 3589 } |
| 3590 |
| 3591 private: |
| 3592 RedirectAndRevalidateURLRequestTestJob(net::URLRequest* request, |
| 3593 net::NetworkDelegate* network_delegate) |
| 3594 : URLRequestTestJob( |
| 3595 request, |
| 3596 network_delegate, |
| 3597 std::string(CreateRedirectHeaders()), |
| 3598 std::string(), |
| 3599 false) {} |
| 3600 |
| 3601 ~RedirectAndRevalidateURLRequestTestJob() override {} |
| 3602 |
| 3603 static std::string CreateRedirectHeaders() { |
| 3604 static const char kRedirectHeaders[] = |
| 3605 "HTTP/1.1 302 MOVED\0" |
| 3606 "Location: http://example.com/var\0" |
| 3607 "\0"; |
| 3608 return std::string(kRedirectHeaders, arraysize(kRedirectHeaders)); |
| 3609 } |
| 3610 |
| 3611 DISALLOW_COPY_AND_ASSIGN(RedirectAndRevalidateURLRequestTestJob); |
| 3612 }; |
| 3613 |
| 3614 // A NetworkDelegate that records the URLRequests as they are created. |
| 3615 class URLRequestRecordingNetworkDelegate : public net::TestNetworkDelegate { |
| 3616 public: |
| 3617 URLRequestRecordingNetworkDelegate() : requests_() {} |
| 3618 |
| 3619 net::URLRequest* NextRequest() { |
| 3620 if (requests_.empty()) |
| 3621 return nullptr; |
| 3622 net::URLRequest* request = requests_.front(); |
| 3623 requests_.pop(); |
| 3624 return request; |
| 3625 } |
| 3626 |
| 3627 bool IsEmpty() { |
| 3628 return requests_.empty(); |
| 3629 } |
| 3630 |
| 3631 int OnBeforeURLRequest(net::URLRequest* request, |
| 3632 const net::CompletionCallback& callback, |
| 3633 GURL* new_url) override { |
| 3634 requests_.push(request); |
| 3635 return TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url); |
| 3636 } |
| 3637 |
| 3638 private: |
| 3639 std::queue<net::URLRequest*> requests_; |
| 3640 |
| 3641 DISALLOW_COPY_AND_ASSIGN(URLRequestRecordingNetworkDelegate); |
| 3642 }; |
| 3643 |
| 3644 class ResourceDispatcherHostAsyncRevalidationTest |
| 3645 : public ResourceDispatcherHostTest { |
| 3646 public: |
| 3647 ResourceDispatcherHostAsyncRevalidationTest() |
| 3648 : ResourceDispatcherHostTest( |
| 3649 make_scoped_ptr(new URLRequestRecordingNetworkDelegate)) { |
| 3650 // Scheme has to be HTTP or HTTPS to support async revalidation. |
| 3651 HandleScheme("http"); |
| 3652 // Use the AsyncRevalidationRequiredURLRequestTestJob. |
| 3653 SetCustomURLRequestJobCreateCallback( |
| 3654 base::Bind(&AsyncRevalidationRequiredURLRequestTestJob::Create)); |
| 3655 } |
| 3656 |
| 3657 URLRequestRecordingNetworkDelegate* recording_network_delegate() { |
| 3658 return static_cast<URLRequestRecordingNetworkDelegate*>(network_delegate()); |
| 3659 } |
| 3660 |
| 3661 net::URLRequest* NextRequest() { |
| 3662 return recording_network_delegate()->NextRequest(); |
| 3663 } |
| 3664 |
| 3665 bool IsEmpty() { |
| 3666 return recording_network_delegate()->IsEmpty(); |
| 3667 } |
| 3668 }; |
| 3669 |
| 3670 // Verify that an async revalidation is actually created when needed. |
| 3671 TEST_F(ResourceDispatcherHostAsyncRevalidationTest, Issued) { |
| 3672 // Create the original request. |
| 3673 MakeTestRequest(0, 1, GURL("http://example.com/baz")); |
| 3674 |
| 3675 net::URLRequest* initial_request = NextRequest(); |
| 3676 ASSERT_TRUE(initial_request); |
| 3677 EXPECT_TRUE(initial_request->load_flags() & |
| 3678 net::LOAD_SUPPORT_ASYNC_REVALIDATION); |
| 3679 |
| 3680 net::URLRequest* async_request = NextRequest(); |
| 3681 ASSERT_TRUE(async_request); |
| 3682 } |
| 3683 |
| 3684 // Verify the the URL of the async revalidation matches the original request. |
| 3685 TEST_F(ResourceDispatcherHostAsyncRevalidationTest, URLMatches) { |
| 3686 // Create the original request. |
| 3687 MakeTestRequest(0, 1, GURL("http://example.com/special-baz")); |
| 3688 |
| 3689 // Discard the original request. |
| 3690 NextRequest(); |
| 3691 |
| 3692 net::URLRequest* async_request = NextRequest(); |
| 3693 ASSERT_TRUE(async_request); |
| 3694 EXPECT_EQ(GURL("http://example.com/special-baz"), async_request->url()); |
| 3695 } |
| 3696 |
| 3697 TEST_F(ResourceDispatcherHostAsyncRevalidationTest, |
| 3698 AsyncRevalidationsDoNotSupportAsyncRevalidation) { |
| 3699 // Create the original request. |
| 3700 MakeTestRequest(0, 1, GURL("http://example.com/baz")); |
| 3701 |
| 3702 // Discard the original request. |
| 3703 NextRequest(); |
| 3704 |
| 3705 // Get the async revalidation request. |
| 3706 net::URLRequest* async_request = NextRequest(); |
| 3707 ASSERT_TRUE(async_request); |
| 3708 EXPECT_FALSE(async_request->load_flags() & |
| 3709 net::LOAD_SUPPORT_ASYNC_REVALIDATION); |
| 3710 } |
| 3711 |
| 3712 TEST_F(ResourceDispatcherHostAsyncRevalidationTest, |
| 3713 AsyncRevalidationsNotDuplicated) { |
| 3714 // Create the original request. |
| 3715 MakeTestRequest(0, 1, GURL("http://example.com/baz")); |
| 3716 |
| 3717 // Discard the original request. |
| 3718 NextRequest(); |
| 3719 |
| 3720 // Get the async revalidation request. |
| 3721 net::URLRequest* async_request = NextRequest(); |
| 3722 EXPECT_TRUE(async_request); |
| 3723 |
| 3724 // Start a second request to the same URL. |
| 3725 MakeTestRequest(0, 2, GURL("http://example.com/baz")); |
| 3726 |
| 3727 // Discard the second request. |
| 3728 NextRequest(); |
| 3729 |
| 3730 // There should not be another async revalidation request. |
| 3731 EXPECT_TRUE(IsEmpty()); |
| 3732 } |
| 3733 |
| 3734 // Async revalidation to different URLs should not be treated as duplicates. |
| 3735 TEST_F(ResourceDispatcherHostAsyncRevalidationTest, |
| 3736 AsyncRevalidationsToSeparateURLsAreSeparate) { |
| 3737 // Create two requests to two URLs. |
| 3738 MakeTestRequest(0, 1, GURL("http://example.com/baz")); |
| 3739 MakeTestRequest(0, 2, GURL("http://example.com/far")); |
| 3740 |
| 3741 net::URLRequest* initial_request = NextRequest(); |
| 3742 ASSERT_TRUE(initial_request); |
| 3743 net::URLRequest* initial_async_revalidation = NextRequest(); |
| 3744 ASSERT_TRUE(initial_async_revalidation); |
| 3745 net::URLRequest* second_request = NextRequest(); |
| 3746 ASSERT_TRUE(second_request); |
| 3747 net::URLRequest* second_async_revalidation = NextRequest(); |
| 3748 ASSERT_TRUE(second_async_revalidation); |
| 3749 |
| 3750 EXPECT_EQ("http://example.com/baz", initial_request->url().spec()); |
| 3751 EXPECT_EQ("http://example.com/baz", initial_async_revalidation->url().spec()); |
| 3752 EXPECT_EQ("http://example.com/far", second_request->url().spec()); |
| 3753 EXPECT_EQ("http://example.com/far", second_async_revalidation->url().spec()); |
| 3754 } |
| 3755 |
| 3756 // A stale-while-revalidate applicable redirect response should not result in an |
| 3757 // async revalidation. |
| 3758 TEST_F(ResourceDispatcherHostAsyncRevalidationTest, RedirectNotApplicable) { |
| 3759 // Use the appropriate URLRequestJob for the test. |
| 3760 SetCustomURLRequestJobCreateCallback( |
| 3761 base::Bind(&RedirectAndRevalidateURLRequestTestJob::Create)); |
| 3762 MakeTestRequest(0, 1, GURL("http://example.com/redirect")); |
| 3763 |
| 3764 net::URLRequest* initial_request = NextRequest(); |
| 3765 EXPECT_TRUE(initial_request); |
| 3766 |
| 3767 // There should not be an async revalidation request. |
| 3768 EXPECT_TRUE(IsEmpty()); |
| 3769 } |
| 3770 |
3446 } // namespace content | 3771 } // namespace content |
OLD | NEW |