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 449b5158166fe03bf4425638f3565319da97d284..57bb8768c479b9443bec42b247d5d38f690a09c0 100644 |
--- a/content/browser/loader/resource_dispatcher_host_unittest.cc |
+++ b/content/browser/loader/resource_dispatcher_host_unittest.cc |
@@ -9,6 +9,7 @@ |
#include "base/memory/scoped_vector.h" |
#include "base/message_loop/message_loop.h" |
#include "base/pickle.h" |
+#include "base/run_loop.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/strings/string_split.h" |
#include "content/browser/browser_thread_impl.h" |
@@ -1698,7 +1699,9 @@ TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) { |
EXPECT_EQ(0, host_.pending_requests()); |
} |
-TEST_F(ResourceDispatcherHostTest, TransferNavigation) { |
+// Test transferred navigations with text/html, which doesn't trigger any |
+// content sniffing. |
+TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) { |
EXPECT_EQ(0, host_.pending_requests()); |
int render_view_id = 0; |
@@ -1718,7 +1721,22 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigation) { |
MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); |
- // Restore. |
+ // Now that we're blocked on the redirect, update the response and unblock by |
+ // telling the AsyncResourceHandler to follow the redirect. |
+ const std::string kResponseBody = "hello world"; |
+ SetResponse("HTTP/1.1 200 OK\n" |
+ "Content-Type: text/html\n\n", |
+ kResponseBody); |
+ ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); |
+ bool msg_was_ok; |
+ host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok); |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ |
+ // Flush all the pending requests to get the response through the |
+ // BufferedResourceHandler. |
+ while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
+ |
+ // Restore, now that we've set up a transfer. |
SetBrowserClientForTesting(old_client); |
// This second filter is used to emulate a second process. |
@@ -1728,10 +1746,78 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigation) { |
int new_render_view_id = 1; |
int new_request_id = 2; |
+ ResourceHostMsg_Request request = |
+ CreateResourceRequest("GET", ResourceType::MAIN_FRAME, |
+ GURL("http://other.com/blech")); |
+ request.transferred_request_child_id = filter_->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); |
+ host_.OnMessageReceived( |
+ transfer_request_msg, second_filter.get(), &msg_was_ok); |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ |
+ // Check generated messages. |
+ ResourceIPCAccumulator::ClassifiedMessages msgs; |
+ accum_.GetClassifiedMessages(&msgs); |
+ |
+ ASSERT_EQ(2U, msgs.size()); |
+ EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type()); |
+ CheckSuccessfulRequest(msgs[1], kResponseBody); |
+} |
+ |
+// Test transferred navigations with text/plain, which causes |
+// BufferedResourceHandler to buffer the response to sniff the content |
+// before the transfer occurs. |
+TEST_F(ResourceDispatcherHostTest, TransferNavigationText) { |
+ EXPECT_EQ(0, host_.pending_requests()); |
+ |
+ int render_view_id = 0; |
+ int request_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); |
+ |
+ MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); |
+ |
+ // Now that we're blocked on the redirect, update the response and unblock by |
+ // telling the AsyncResourceHandler to follow the redirect. Use a text/plain |
+ // MIME type, which causes BufferedResourceHandler to buffer it before the |
+ // transfer occurs. |
const std::string kResponseBody = "hello world"; |
SetResponse("HTTP/1.1 200 OK\n" |
"Content-Type: text/plain\n\n", |
kResponseBody); |
+ ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); |
+ bool msg_was_ok; |
+ host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok); |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ |
+ // Flush all the pending requests to get the response through the |
+ // BufferedResourceHandler. |
+ while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
+ |
+ // Restore, now that we've set up a transfer. |
+ SetBrowserClientForTesting(old_client); |
+ |
+ // 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; |
ResourceHostMsg_Request request = |
CreateResourceRequest("GET", ResourceType::MAIN_FRAME, |
@@ -1743,20 +1829,17 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigation) { |
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); |
+ ASSERT_EQ(2U, msgs.size()); |
+ EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type()); |
+ CheckSuccessfulRequest(msgs[1], kResponseBody); |
} |
TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) { |
@@ -1769,6 +1852,7 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) { |
// Configure initial request. |
SetResponse("HTTP/1.1 302 Found\n" |
"Location: http://other.com/blech\n\n"); |
+ const std::string kResponseBody = "hello world"; |
SetResourceType(ResourceType::MAIN_FRAME); |
HandleScheme("http"); |
@@ -1796,6 +1880,19 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) { |
host_.OnMessageReceived( |
first_request_msg, first_filter.get(), &msg_was_ok); |
base::MessageLoop::current()->RunUntilIdle(); |
+ |
+ // Now that we're blocked on the redirect, update the response and unblock |
+ // by telling the AsyncResourceHandler to follow the redirect. |
+ SetResponse("HTTP/1.1 200 OK\n" |
+ "Content-Type: text/html\n\n", |
+ kResponseBody); |
+ ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); |
+ host_.OnMessageReceived(redirect_msg, first_filter.get(), &msg_was_ok); |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ |
+ // Flush all the pending requests to get the response through the |
+ // BufferedResourceHandler. |
+ while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
} |
// The first filter is now deleted, as if the child process died. |
@@ -1815,11 +1912,6 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) { |
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")); |
@@ -1835,18 +1927,16 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) { |
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); |
+ ASSERT_EQ(2U, msgs.size()); |
+ EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type()); |
+ CheckSuccessfulRequest(msgs[1], kResponseBody); |
} |
-TEST_F(ResourceDispatcherHostTest, TransferNavigationAndThenRedirect) { |
+TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) { |
EXPECT_EQ(0, host_.pending_requests()); |
int render_view_id = 0; |
@@ -1866,6 +1956,30 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationAndThenRedirect) { |
MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); |
+ // Now that we're blocked on the redirect, simulate hitting another redirect. |
+ SetResponse("HTTP/1.1 302 Found\n" |
+ "Location: http://other.com/blerg\n\n"); |
+ ResourceHostMsg_FollowRedirect redirect_msg(request_id, false, GURL()); |
+ bool msg_was_ok; |
+ host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok); |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ |
+ // Now that we're blocked on the second redirect, update the response and |
+ // unblock by telling the AsyncResourceHandler to follow the redirect. |
+ // Again, use text/plain to force BufferedResourceHandler to buffer before |
+ // the transfer. |
+ const std::string kResponseBody = "hello world"; |
+ SetResponse("HTTP/1.1 200 OK\n" |
+ "Content-Type: text/plain\n\n", |
+ kResponseBody); |
+ ResourceHostMsg_FollowRedirect redirect_msg2(request_id, false, GURL()); |
+ host_.OnMessageReceived(redirect_msg2, filter_.get(), &msg_was_ok); |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ |
+ // Flush all the pending requests to get the response through the |
+ // BufferedResourceHandler. |
+ while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
+ |
// Restore. |
SetBrowserClientForTesting(old_client); |
@@ -1876,13 +1990,6 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationAndThenRedirect) { |
int new_render_view_id = 1; |
int new_request_id = 2; |
- // Delay the start of the next request so that we can setup the response for |
- // the next URL. |
- SetDelayedStartJobGeneration(true); |
- |
- SetResponse("HTTP/1.1 302 Found\n" |
- "Location: http://other.com/blerg\n\n"); |
- |
ResourceHostMsg_Request request = |
CreateResourceRequest("GET", ResourceType::MAIN_FRAME, |
GURL("http://other.com/blech")); |
@@ -1893,24 +2000,8 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationAndThenRedirect) { |
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(); |
- |
- // Response data for "http://other.com/blerg": |
- const std::string kResponseBody = "hello world"; |
- SetResponse("HTTP/1.1 200 OK\n" |
- "Content-Type: text/plain\n\n", |
- kResponseBody); |
- |
- // OK, let the redirect happen. |
- SetDelayedStartJobGeneration(false); |
- CompleteStartRequest(second_filter.get(), new_request_id); |
- base::MessageLoop::current()->RunUntilIdle(); |
- |
- // 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); |
@@ -1921,25 +2012,16 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationAndThenRedirect) { |
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()); |
- host_.OnMessageReceived(redirect_msg, second_filter.get(), &msg_was_ok); |
+ // Let request complete. |
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()); |
- |
- // We should have received a redirect followed by a "normal" payload. |
+ ASSERT_EQ(2U, msgs.size()); |
EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type()); |
- msgs[0].erase(msgs[0].begin()); |
- CheckSuccessfulRequest(msgs[0], kResponseBody); |
+ CheckSuccessfulRequest(msgs[1], kResponseBody); |
} |
TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) { |