summaryrefslogtreecommitdiffstats
path: root/content/browser/loader/resource_dispatcher_host_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'content/browser/loader/resource_dispatcher_host_unittest.cc')
-rw-r--r--content/browser/loader/resource_dispatcher_host_unittest.cc99
1 files changed, 98 insertions, 1 deletions
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc
index 89b17c4..449b515 100644
--- a/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -15,6 +15,7 @@
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_message_filter.h"
+#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/worker_host/worker_service_impl.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/resource_messages.h"
@@ -22,6 +23,7 @@
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/resource_dispatcher_host_delegate.h"
+#include "content/public/browser/resource_request_info.h"
#include "content/public/browser/resource_throttle.h"
#include "content/public/common/process_type.h"
#include "content/public/common/resource_response.h"
@@ -489,7 +491,6 @@ class TestResourceDispatcherHostDelegate
ResourceType::Type resource_type,
int child_id,
int route_id,
- bool is_continuation_of_transferred_request,
ScopedVector<ResourceThrottle>* throttles) OVERRIDE {
if (user_data_) {
const void* key = user_data_.get();
@@ -1758,6 +1759,93 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigation) {
CheckSuccessfulRequest(msgs[0], kResponseBody);
}
+TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) {
+ EXPECT_EQ(0, host_.pending_requests());
+
+ int render_view_id = 0;
+ int request_id = 1;
+ int first_child_id = -1;
+
+ // Configure initial request.
+ SetResponse("HTTP/1.1 302 Found\n"
+ "Location: http://other.com/blech\n\n");
+
+ SetResourceType(ResourceType::MAIN_FRAME);
+ HandleScheme("http");
+
+ // Temporarily replace ContentBrowserClient with one that will trigger the
+ // transfer navigation code paths.
+ TransfersAllNavigationsContentBrowserClient new_client;
+ ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
+
+ // Create a first filter that can be deleted before the second one starts.
+ {
+ scoped_refptr<ForwardingFilter> first_filter = new ForwardingFilter(
+ this, browser_context_->GetResourceContext());
+ first_child_id = first_filter->child_id();
+
+ ResourceHostMsg_Request first_request =
+ CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
+ GURL("http://example.com/blah"));
+
+ // For cleanup.
+ child_ids_.insert(first_child_id);
+ ResourceHostMsg_RequestResource first_request_msg(
+ render_view_id, request_id, first_request);
+ bool msg_was_ok;
+ host_.OnMessageReceived(
+ first_request_msg, first_filter.get(), &msg_was_ok);
+ base::MessageLoop::current()->RunUntilIdle();
+ }
+ // The first filter is now deleted, as if the child process died.
+
+ // Restore.
+ SetBrowserClientForTesting(old_client);
+
+ // Make sure we don't hold onto the ResourceMessageFilter after it is deleted.
+ GlobalRequestID first_global_request_id(first_child_id, request_id);
+ const ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
+ host_.GetURLRequest(first_global_request_id));
+ EXPECT_FALSE(info->filter());
+
+ // This second filter is used to emulate a second process.
+ scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
+ this, browser_context_->GetResourceContext());
+
+ int new_render_view_id = 1;
+ int new_request_id = 2;
+
+ const std::string kResponseBody = "hello world";
+ SetResponse("HTTP/1.1 200 OK\n"
+ "Content-Type: text/plain\n\n",
+ kResponseBody);
+
+ ResourceHostMsg_Request request =
+ CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
+ GURL("http://other.com/blech"));
+ request.transferred_request_child_id = first_child_id;
+ request.transferred_request_request_id = request_id;
+
+ // For cleanup.
+ child_ids_.insert(second_filter->child_id());
+ ResourceHostMsg_RequestResource transfer_request_msg(
+ new_render_view_id, new_request_id, request);
+ bool msg_was_ok;
+ host_.OnMessageReceived(
+ transfer_request_msg, second_filter.get(), &msg_was_ok);
+ base::MessageLoop::current()->RunUntilIdle();
+
+ // Flush all the pending requests.
+ while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
+
+ // Check generated messages.
+ ResourceIPCAccumulator::ClassifiedMessages msgs;
+ accum_.GetClassifiedMessages(&msgs);
+
+ ASSERT_EQ(1U, msgs.size());
+ CheckSuccessfulRequest(msgs[0], kResponseBody);
+}
+
TEST_F(ResourceDispatcherHostTest, TransferNavigationAndThenRedirect) {
EXPECT_EQ(0, host_.pending_requests());
@@ -1824,6 +1912,15 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationAndThenRedirect) {
// Flush all the pending requests.
while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
+ // Verify that we update the ResourceRequestInfo.
+ GlobalRequestID global_request_id(second_filter->child_id(), new_request_id);
+ const ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
+ host_.GetURLRequest(global_request_id));
+ EXPECT_EQ(second_filter->child_id(), info->GetChildID());
+ EXPECT_EQ(new_render_view_id, info->GetRouteID());
+ EXPECT_EQ(new_request_id, info->GetRequestID());
+ EXPECT_EQ(second_filter, info->filter());
+
// Now, simulate the renderer choosing to follow the redirect.
ResourceHostMsg_FollowRedirect redirect_msg(
new_request_id, false, GURL());