Index: content/browser/loader/resource_dispatcher_host_unittest.cc |
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc |
index 606da908983b7fd356c7afc2caec9a55746d0e14..736bd7717f4c1588db04ae4f39a439107a46437e 100644 |
--- a/content/browser/loader/resource_dispatcher_host_unittest.cc |
+++ b/content/browser/loader/resource_dispatcher_host_unittest.cc |
@@ -23,14 +23,17 @@ |
#include "content/browser/browser_thread_impl.h" |
#include "content/browser/cert_store_impl.h" |
#include "content/browser/child_process_security_policy_impl.h" |
+#include "content/browser/frame_host/navigation_request_info.h" |
#include "content/browser/loader/cross_site_resource_handler.h" |
#include "content/browser/loader/detachable_resource_handler.h" |
+#include "content/browser/loader/navigation_url_loader.h" |
#include "content/browser/loader/resource_dispatcher_host_impl.h" |
#include "content/browser/loader/resource_loader.h" |
#include "content/browser/loader/resource_message_filter.h" |
#include "content/browser/loader/resource_request_info_impl.h" |
#include "content/common/appcache_interfaces.h" |
#include "content/common/child_process_host_impl.h" |
+#include "content/common/navigation_params.h" |
#include "content/common/resource_messages.h" |
#include "content/common/ssl_status_serialization.h" |
#include "content/common/view_messages.h" |
@@ -51,7 +54,9 @@ |
#include "content/public/test/test_browser_thread_bundle.h" |
#include "content/public/test/test_renderer_host.h" |
#include "content/test/test_content_browser_client.h" |
+#include "content/test/test_navigation_url_loader_delegate.h" |
#include "net/base/elements_upload_data_stream.h" |
+#include "net/base/load_flags.h" |
#include "net/base/net_errors.h" |
#include "net/base/request_priority.h" |
#include "net/base/test_data_directory.h" |
@@ -865,6 +870,20 @@ class MockCertStore : public content::CertStore { |
int default_cert_id_; |
}; |
+void CheckRequestCompleteErrorCode(const IPC::Message& message, |
+ int expected_error_code) { |
+ // Verify the expected error code was received. |
+ int request_id; |
+ int error_code; |
+ |
+ ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type()); |
+ |
+ base::PickleIterator iter(message); |
+ ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id)); |
+ ASSERT_TRUE(IPC::ReadParam(&message, &iter, &error_code)); |
+ ASSERT_EQ(expected_error_code, error_code); |
+} |
+ |
class ResourceDispatcherHostTest : public testing::TestWithParam<TestConfig>, |
public IPC::Sender { |
public: |
@@ -875,7 +894,8 @@ class ResourceDispatcherHostTest : public testing::TestWithParam<TestConfig>, |
: thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), |
use_test_ssl_certificate_(false), |
old_factory_(NULL), |
- send_data_received_acks_(false) { |
+ send_data_received_acks_(false), |
+ auto_advance_(false) { |
browser_context_.reset(new TestBrowserContext()); |
BrowserContext::EnsureResourceContextInitialized(browser_context_.get()); |
base::RunLoop().RunUntilIdle(); |
@@ -1106,6 +1126,52 @@ class ResourceDispatcherHostTest : public testing::TestWithParam<TestConfig>, |
host_.OnRenderFrameDeleted(global_routing_id); |
} |
+ // Creates and drives a main resource request until completion. Then asserts |
+ // that the expected_error_code has been emitted for the request. |
+ void CompleteFailingMainResourceRequest(const GURL& url, |
+ int expected_error_code) { |
+ if (IsBrowserSideNavigationEnabled()) { |
+ auto_advance_ = true; |
+ |
+ // Make a navigation request. |
+ TestNavigationURLLoaderDelegate delegate; |
+ BeginNavigationParams begin_params(std::string(), net::LOAD_NORMAL, false, |
+ false, REQUEST_CONTEXT_TYPE_LOCATION); |
+ CommonNavigationParams common_params; |
+ common_params.url = url; |
+ scoped_ptr<NavigationRequestInfo> request_info(new NavigationRequestInfo( |
+ common_params, begin_params, url, url::Origin(url), true, false, -1, |
+ scoped_refptr<ResourceRequestBody>())); |
+ scoped_ptr<NavigationURLLoader> test_loader = NavigationURLLoader::Create( |
+ browser_context_.get(), std::move(request_info), nullptr, &delegate); |
+ |
+ // The navigation should fail with the expected error code. |
+ delegate.WaitForRequestFailed(); |
+ ASSERT_EQ(expected_error_code, delegate.net_error()); |
+ return; |
+ } |
+ |
+ MakeTestRequestWithResourceType(filter_.get(), 0, 1, url, |
+ RESOURCE_TYPE_MAIN_FRAME); |
+ |
+ // Flush all pending requests. |
+ while (net::URLRequestTestJob::ProcessOnePendingMessage()) { |
+ } |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ |
+ // Sorts out all the messages we saw by request. |
+ ResourceIPCAccumulator::ClassifiedMessages msgs; |
+ accum_.GetClassifiedMessages(&msgs); |
+ |
+ // We should have gotten one RequestComplete message. |
+ ASSERT_EQ(1U, msgs.size()); |
+ ASSERT_EQ(1U, msgs[0].size()); |
+ EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type()); |
+ |
+ // The RequestComplete message should have had the expected error code. |
+ CheckRequestCompleteErrorCode(msgs[0][0], expected_error_code); |
+ } |
+ |
std::unique_ptr<LoadInfoTestRequestInfo> loader_test_request_info_; |
std::unique_ptr<base::RunLoop> wait_for_request_create_loop_; |
@@ -1129,6 +1195,7 @@ class ResourceDispatcherHostTest : public testing::TestWithParam<TestConfig>, |
std::unique_ptr<base::RunLoop> wait_for_request_complete_loop_; |
RenderViewHostTestEnabler render_view_host_test_enabler_; |
MockCertStore mock_cert_store_; |
+ bool auto_advance_; |
}; |
void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id, |
@@ -1238,20 +1305,6 @@ void ResourceDispatcherHostTest::CompleteStartRequest( |
URLRequestTestDelayedStartJob::CompleteStart(req); |
} |
-void CheckRequestCompleteErrorCode(const IPC::Message& message, |
- int expected_error_code) { |
- // Verify the expected error code was received. |
- int request_id; |
- int error_code; |
- |
- ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type()); |
- |
- base::PickleIterator iter(message); |
- ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id)); |
- ASSERT_TRUE(IPC::ReadParam(&message, &iter, &error_code)); |
- ASSERT_EQ(expected_error_code, error_code); |
-} |
- |
testing::AssertionResult ExtractInlinedChunkData( |
const IPC::Message& message, |
std::string* leading_chunk_data) { |
@@ -2468,32 +2521,25 @@ TEST_P(ResourceDispatcherHostTest, ForbiddenDownload) { |
HandleScheme("http"); |
- // Only MAIN_FRAMEs can trigger a download. |
- MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("http:bla"), |
- RESOURCE_TYPE_MAIN_FRAME); |
- |
- // Flush all pending requests. |
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
- base::MessageLoop::current()->RunUntilIdle(); |
- |
- // Sorts out all the messages we saw by request. |
- ResourceIPCAccumulator::ClassifiedMessages msgs; |
- accum_.GetClassifiedMessages(&msgs); |
+ int expected_error_code = net::ERR_INVALID_RESPONSE; |
+ GURL forbidden_download_url = GURL("http:bla"); |
- // We should have gotten one RequestComplete message. |
- ASSERT_EQ(1U, msgs.size()); |
- ASSERT_EQ(1U, msgs[0].size()); |
- EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type()); |
- |
- // The RequestComplete message should have had the error code of |
- // ERR_INVALID_RESPONSE. |
- CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_INVALID_RESPONSE); |
+ CompleteFailingMainResourceRequest(forbidden_download_url, |
+ expected_error_code); |
} |
// Test for http://crbug.com/76202 . We don't want to destroy a |
// download request prematurely when processing a cancellation from |
// the renderer. |
TEST_P(ResourceDispatcherHostTest, IgnoreCancelForDownloads) { |
+ // PlzNavigate: A request that ends up being a download is a main resource |
+ // request. Hence, it has been initiated by the browser and is not associated |
+ // with a renderer. Therefore, it cannot be canceled by a renderer IPC. |
+ if (IsBrowserSideNavigationEnabled()) { |
+ SUCCEED() << "Not applicable with --enable-browser-side-navigation."; |
+ return; |
+ } |
+ |
EXPECT_EQ(0, host_.pending_requests()); |
int render_view_id = 0; |
@@ -2549,29 +2595,66 @@ TEST_P(ResourceDispatcherHostTest, CancelRequestsForContext) { |
job_factory_->SetDelayedCompleteJobGeneration(true); |
HandleScheme("http"); |
- MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
- GURL("http://example.com/blah"), |
- RESOURCE_TYPE_MAIN_FRAME); |
- // Return some data so that the request is identified as a download |
- // and the proper resource handlers are created. |
- EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); |
+ const GURL download_url = GURL("http://example.com/blah"); |
- // And now simulate a cancellation coming from the renderer. |
- ResourceHostMsg_CancelRequest msg(request_id); |
- host_.OnMessageReceived(msg, filter_.get()); |
+ if (IsBrowserSideNavigationEnabled()) { |
+ // Create a NavigationRequest. |
+ TestNavigationURLLoaderDelegate delegate; |
+ BeginNavigationParams begin_params(std::string(), net::LOAD_NORMAL, false, |
+ false, REQUEST_CONTEXT_TYPE_LOCATION); |
+ CommonNavigationParams common_params; |
+ common_params.url = download_url; |
+ scoped_ptr<NavigationRequestInfo> request_info(new NavigationRequestInfo( |
+ common_params, begin_params, download_url, url::Origin(download_url), |
+ true, false, -1, scoped_refptr<ResourceRequestBody>())); |
+ scoped_ptr<NavigationURLLoader> loader = NavigationURLLoader::Create( |
+ browser_context_.get(), std::move(request_info), nullptr, &delegate); |
+ |
+ // Wait until a response has been received and proceed with the response. |
+ KickOffRequest(); |
+ |
+ // Return some data so that the request is identified as a download |
+ // and the proper resource handlers are created. |
+ EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); |
+ base::MessageLoop::current()->RunUntilIdle(); |
- // Since the request had already started processing as a download, |
- // the cancellation above should have been ignored and the request |
- // should still be alive. |
- EXPECT_EQ(1, host_.pending_requests()); |
+ // The UI thread will be informed that the navigation failed with an error |
+ // code of ERR_ABORTED because the navigation turns out to be a download. |
+ // The navigation is aborted, but the request goes on as a download. |
+ EXPECT_EQ(delegate.net_error(), net::ERR_ABORTED); |
+ EXPECT_EQ(1, host_.pending_requests()); |
- // Cancelling by other methods shouldn't work either. |
- host_.CancelRequestsForProcess(render_view_id); |
- EXPECT_EQ(1, host_.pending_requests()); |
+ // In PlzNavigate, the renderer cannot cancel the request directly. |
+ // However, cancelling by context should work. |
+ host_.CancelRequestsForContext(browser_context_->GetResourceContext()); |
+ EXPECT_EQ(0, host_.pending_requests()); |
- // Cancelling by context should work. |
- host_.CancelRequestsForContext(filter_->resource_context()); |
- EXPECT_EQ(0, host_.pending_requests()); |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ } else { |
+ MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
+ download_url, RESOURCE_TYPE_MAIN_FRAME); |
+ |
+ // Return some data so that the request is identified as a download |
+ // and the proper resource handlers are created. |
+ EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); |
+ |
+ // And now simulate a cancellation coming from the renderer. |
+ ResourceHostMsg_CancelRequest msg(request_id); |
+ host_.OnMessageReceived(msg, filter_.get()); |
+ |
+ // Since the request had already started processing as a download, |
+ // the cancellation above should have been ignored and the request |
+ // should still be alive. |
+ EXPECT_EQ(1, host_.pending_requests()); |
+ |
+ // Cancelling by other methods shouldn't work either. |
+ host_.CancelRequestsForProcess(render_view_id); |
+ EXPECT_EQ(1, host_.pending_requests()); |
+ |
+ // Cancelling by context should work. |
+ host_.CancelRequestsForContext(filter_->resource_context()); |
+ EXPECT_EQ(0, host_.pending_requests()); |
+ } |
} |
TEST_P(ResourceDispatcherHostTest, CancelRequestsForContextDetached) { |
@@ -3164,23 +3247,10 @@ TEST_P(ResourceDispatcherHostTest, UnknownURLScheme) { |
HandleScheme("http"); |
- MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("foo://bar"), |
- RESOURCE_TYPE_MAIN_FRAME); |
+ const GURL invalid_sheme_url = GURL("foo://bar"); |
+ const int expected_error_code = net::ERR_UNKNOWN_URL_SCHEME; |
- // Flush all pending requests. |
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
- |
- // Sort all the messages we saw by request. |
- ResourceIPCAccumulator::ClassifiedMessages msgs; |
- accum_.GetClassifiedMessages(&msgs); |
- |
- // We should have gotten one RequestComplete message. |
- ASSERT_EQ(1U, msgs[0].size()); |
- EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type()); |
- |
- // The RequestComplete message should have the error code of |
- // ERR_UNKNOWN_URL_SCHEME. |
- CheckRequestCompleteErrorCode(msgs[0][0], net::ERR_UNKNOWN_URL_SCHEME); |
+ CompleteFailingMainResourceRequest(invalid_sheme_url, expected_error_code); |
} |
TEST_P(ResourceDispatcherHostTest, DataReceivedACKs) { |
@@ -3791,7 +3861,8 @@ net::URLRequestJob* TestURLRequestJobFactory::MaybeCreateJobWithProtocolHandler( |
} else if (scheme == "big-job") { |
return new URLRequestBigJob(request, network_delegate); |
} else { |
- return new net::URLRequestTestJob(request, network_delegate); |
+ return new net::URLRequestTestJob(request, network_delegate, |
+ test_fixture_->auto_advance_); |
} |
} else { |
if (delay_start_) { |
@@ -3810,9 +3881,8 @@ net::URLRequestJob* TestURLRequestJobFactory::MaybeCreateJobWithProtocolHandler( |
test_fixture_->response_data_, false); |
} else { |
return new net::URLRequestTestJob( |
- request, network_delegate, |
- test_fixture_->response_headers_, test_fixture_->response_data_, |
- false); |
+ request, network_delegate, test_fixture_->response_headers_, |
+ test_fixture_->response_data_, test_fixture_->auto_advance_); |
} |
} |
} |