| 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 c3cbb35379087937d7481a931ec2ab5045e865f5..93c59d0f9f29a3515898623100bdfcc5b4134c49 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"
|
| @@ -866,6 +871,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:
|
| @@ -876,7 +895,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);
|
| + }
|
| +
|
| scoped_ptr<LoadInfoTestRequestInfo> loader_test_request_info_;
|
| scoped_ptr<base::RunLoop> wait_for_request_create_loop_;
|
|
|
| @@ -1129,6 +1195,7 @@ class ResourceDispatcherHostTest : public testing::TestWithParam<TestConfig>,
|
| scoped_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) {
|
| @@ -2467,32 +2520,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;
|
| @@ -2548,29 +2594,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) {
|
| @@ -3163,23 +3246,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) {
|
| @@ -3790,7 +3860,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_) {
|
| @@ -3809,9 +3880,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_);
|
| }
|
| }
|
| }
|
|
|