summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcreis@chromium.org <creis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-01 20:52:26 +0000
committercreis@chromium.org <creis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-01 20:52:26 +0000
commitf70fe9218f1f3bb44e7c7c0b9b20aabbf4420d4b (patch)
tree572440765686472d7b064de9b3ad820cf0af6b3b
parent716db0f70a724707946e625fa8d450d42a0deaf7 (diff)
downloadchromium_src-f70fe9218f1f3bb44e7c7c0b9b20aabbf4420d4b.zip
chromium_src-f70fe9218f1f3bb44e7c7c0b9b20aabbf4420d4b.tar.gz
chromium_src-f70fe9218f1f3bb44e7c7c0b9b20aabbf4420d4b.tar.bz2
Revert 226284 "Move TransferNavigationResourceThrottle into Cros..."
Memory errors in TransferNavigation unit tests. > Move TransferNavigationResourceThrottle into CrossSiteResourceHandler. > > We now transfer requests to a new process when they are ready to commit, rather than each time a redirect occurs. This simplifies the ResourceDispatcherHost logic, and it prepares for a future CL to intercept all navigations in the browser process. > > BUG=238331 > TEST=No more than one process swap for repeated redirects. > > Review URL: https://codereview.chromium.org/15476003 TBR=creis@chromium.org Review URL: https://codereview.chromium.org/25372005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@226293 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/loader/cross_site_resource_handler.cc92
-rw-r--r--content/browser/loader/cross_site_resource_handler.h6
-rw-r--r--content/browser/loader/resource_dispatcher_host_impl.cc25
-rw-r--r--content/browser/loader/resource_dispatcher_host_unittest.cc190
-rw-r--r--content/browser/loader/resource_loader.cc5
-rw-r--r--content/browser/loader/transfer_navigation_resource_throttle.cc93
-rw-r--r--content/browser/loader/transfer_navigation_resource_throttle.h38
-rw-r--r--content/browser/renderer_host/render_view_host_delegate.h9
-rw-r--r--content/browser/web_contents/render_view_host_manager.cc85
-rw-r--r--content/browser/web_contents/render_view_host_manager.h39
-rw-r--r--content/browser/web_contents/web_contents_impl.cc39
-rw-r--r--content/browser/web_contents/web_contents_impl_unittest.cc2
-rw-r--r--content/content_browser.gypi2
13 files changed, 280 insertions, 345 deletions
diff --git a/content/browser/loader/cross_site_resource_handler.cc b/content/browser/loader/cross_site_resource_handler.cc
index 6bac75a..90fe84a 100644
--- a/content/browser/loader/cross_site_resource_handler.cc
+++ b/content/browser/loader/cross_site_resource_handler.cc
@@ -9,17 +9,14 @@
#include "base/bind.h"
#include "base/logging.h"
#include "content/browser/cross_site_request_manager.h"
-#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/resource_controller.h"
#include "content/public/common/resource_response.h"
#include "net/http/http_response_headers.h"
-#include "net/url_request/url_request.h"
namespace content {
@@ -27,21 +24,13 @@ namespace {
void OnCrossSiteResponseHelper(int render_process_id,
int render_view_id,
- const GlobalRequestID& global_request_id,
- bool is_transfer,
- const GURL& transfer_url,
- const Referrer& referrer,
- int64 frame_id) {
+ int request_id) {
RenderViewHostImpl* rvh = RenderViewHostImpl::FromID(render_process_id,
render_view_id);
- if (!rvh)
- return;
- RenderViewHostDelegate* delegate = rvh->GetDelegate();
- if (!delegate || !delegate->GetRendererManagementDelegate())
- return;
-
- delegate->GetRendererManagementDelegate()->OnCrossSiteResponse(
- rvh, global_request_id, is_transfer, transfer_url, referrer, frame_id);
+ if (rvh && rvh->GetDelegate()->GetRendererManagementDelegate()) {
+ rvh->GetDelegate()->GetRendererManagementDelegate()->OnCrossSiteResponse(
+ rvh, GlobalRequestID(render_process_id, request_id));
+ }
}
} // namespace
@@ -88,16 +77,10 @@ bool CrossSiteResourceHandler::OnResponseStarted(
ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request_);
- // We will need to swap processes if either (1) a redirect that requires a
- // transfer occurred before we got here, or (2) a pending cross-site request
- // was already in progress. Note that a swap may no longer be needed if we
- // transferred back into the original process due to a redirect.
- bool should_transfer =
- GetContentClient()->browser()->ShouldSwapProcessesForRedirect(
- info->GetContext(), request_->original_url(), request_->url());
- bool swap_needed = should_transfer ||
- CrossSiteRequestManager::GetInstance()->
- HasPendingCrossSiteRequest(info->GetChildID(), info->GetRouteID());
+ // A swap may no longer be needed if we transferred back into the original
+ // process due to a redirect.
+ bool swap_needed = CrossSiteRequestManager::GetInstance()->
+ HasPendingCrossSiteRequest(info->GetChildID(), info->GetRouteID());
// If this is a download, just pass the response through without doing a
// cross-site check. The renderer will see it is a download and abort the
@@ -107,9 +90,8 @@ bool CrossSiteResourceHandler::OnResponseStarted(
// page. We should allow the navigation to finish without running the unload
// handler or swapping in the pending RenderViewHost.
//
- // In both cases, any pending RenderViewHost (if one was created for this
- // navigation) will stick around until the next cross-site navigation, since
- // we are unable to tell when to destroy it.
+ // In both cases, the pending RenderViewHost will stick around until the next
+ // cross-site navigation, since we are unable to tell when to destroy it.
// See RenderViewHostManager::RendererAbortedProvisionalLoad.
if (!swap_needed || info->is_download() ||
(response->head.headers.get() &&
@@ -117,10 +99,8 @@ bool CrossSiteResourceHandler::OnResponseStarted(
return next_handler_->OnResponseStarted(request_id, response, defer);
}
- // Now that we know a swap is needed and we have something to commit, we
- // pause to let the UI thread run the unload handler of the previous page
- // and set up a transfer if needed.
- StartCrossSiteTransition(request_id, response, should_transfer);
+ // Tell the renderer to run the onunload event handler.
+ StartCrossSiteTransition(request_id, response);
// Defer loading until after the onunload event handler has run.
did_defer_ = *defer = true;
@@ -139,24 +119,19 @@ bool CrossSiteResourceHandler::OnResponseCompleted(
const net::URLRequestStatus& status,
const std::string& security_info) {
if (!in_cross_site_transition_) {
- ResourceRequestInfoImpl* info =
- ResourceRequestInfoImpl::ForRequest(request_);
- // If we've already completed the transition, or we're canceling the
- // request, or an error occurred with no cross-process navigation in
- // progress, then we should just pass this through.
if (has_started_response_ ||
- status.status() != net::URLRequestStatus::FAILED ||
- !CrossSiteRequestManager::GetInstance()->HasPendingCrossSiteRequest(
- info->GetChildID(), info->GetRouteID())) {
+ status.status() != net::URLRequestStatus::FAILED) {
+ // We've already completed the transition or we're canceling the request,
+ // so just pass it through.
return next_handler_->OnResponseCompleted(request_id, status,
security_info);
}
- // An error occurred. We should wait now for the cross-process transition,
+ // An error occured, we should wait now for the cross-site transition,
// so that the error message (e.g., 404) can be displayed to the user.
// Also continue with the logic below to remember that we completed
// during the cross-site transition.
- StartCrossSiteTransition(request_id, NULL, false);
+ StartCrossSiteTransition(request_id, NULL);
}
// We have to buffer the call until after the transition completes.
@@ -211,35 +186,19 @@ void CrossSiteResourceHandler::ResumeResponse() {
// telling the old RenderViewHost to run its onunload handler.
void CrossSiteResourceHandler::StartCrossSiteTransition(
int request_id,
- ResourceResponse* response,
- bool should_transfer) {
+ ResourceResponse* response) {
in_cross_site_transition_ = true;
response_ = response;
// Store this handler on the ExtraRequestInfo, so that RDH can call our
- // ResumeResponse method when we are ready to resume.
+ // ResumeResponse method when the close ACK is received.
ResourceRequestInfoImpl* info =
ResourceRequestInfoImpl::ForRequest(request_);
info->set_cross_site_handler(this);
- DCHECK_EQ(request_id, info->GetRequestID());
- GlobalRequestID global_id(info->GetChildID(), info->GetRequestID());
-
// Tell the contents responsible for this request that a cross-site response
// is starting, so that it can tell its old renderer to run its onunload
- // handler now. We will wait until the unload is finished and (if a transfer
- // is needed) for the new renderer's request to arrive.
- GURL transfer_url;
- Referrer referrer;
- int frame_id = -1;
- if (should_transfer) {
- transfer_url = request_->url();
- referrer = Referrer(GURL(request_->referrer()), info->GetReferrerPolicy());
- frame_id = info->GetFrameID();
-
- ResourceDispatcherHostImpl::Get()->MarkAsTransferredNavigation(
- global_id, transfer_url);
- }
+ // handler now. We will wait to hear the corresponding ClosePage_ACK.
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
@@ -247,11 +206,10 @@ void CrossSiteResourceHandler::StartCrossSiteTransition(
&OnCrossSiteResponseHelper,
info->GetChildID(),
info->GetRouteID(),
- global_id,
- should_transfer,
- transfer_url,
- referrer,
- frame_id));
+ request_id));
+
+ // TODO(creis): If the above call should fail, then we need to notify the IO
+ // thread to proceed anyway, using ResourceDispatcherHost::OnClosePageACK.
}
void CrossSiteResourceHandler::ResumeIfDeferred() {
diff --git a/content/browser/loader/cross_site_resource_handler.h b/content/browser/loader/cross_site_resource_handler.h
index 5c08f7e..39c3a14 100644
--- a/content/browser/loader/cross_site_resource_handler.h
+++ b/content/browser/loader/cross_site_resource_handler.h
@@ -47,9 +47,9 @@ class CrossSiteResourceHandler : public LayeredResourceHandler {
private:
// Prepare to render the cross-site response in a new RenderViewHost, by
// telling the old RenderViewHost to run its onunload handler.
- void StartCrossSiteTransition(int request_id,
- ResourceResponse* response,
- bool should_transfer);
+ void StartCrossSiteTransition(
+ int request_id,
+ ResourceResponse* response);
void ResumeIfDeferred();
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 839678e..a44715d 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -40,6 +40,7 @@
#include "content/browser/loader/stream_resource_handler.h"
#include "content/browser/loader/sync_resource_handler.h"
#include "content/browser/loader/throttling_resource_handler.h"
+#include "content/browser/loader/transfer_navigation_resource_throttle.h"
#include "content/browser/loader/upload_data_stream_builder.h"
#include "content/browser/plugin_service_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
@@ -937,9 +938,6 @@ void ResourceDispatcherHostImpl::UpdateRequestForTransfer(
route_id,
request_id);
}
-
- // We should have a CrossSiteResourceHandler to finish the transfer.
- DCHECK(info->cross_site_handler());
}
void ResourceDispatcherHostImpl::BeginRequest(
@@ -1109,11 +1107,16 @@ void ResourceDispatcherHostImpl::BeginRequest(
new RedirectToFileResourceHandler(handler.Pass(), request, this));
}
- // Install a CrossSiteResourceHandler for all main frame requests. This will
- // let us check whether a transfer is required and pause for the unload
- // handler either if so or if a cross-process navigation is already under way.
- if (request_data.resource_type == ResourceType::MAIN_FRAME &&
- process_type == PROCESS_TYPE_RENDERER) {
+ // Install a CrossSiteResourceHandler if this request is coming from a
+ // RenderViewHost with a pending cross-site request. We only check this for
+ // MAIN_FRAME requests. Unblock requests only come from a blocked page, do
+ // not count as cross-site, otherwise it gets blocked indefinitely.
+ if (request_data.resource_type == ResourceType::MAIN_FRAME &&
+ process_type == PROCESS_TYPE_RENDERER &&
+ CrossSiteRequestManager::GetInstance()->
+ HasPendingCrossSiteRequest(child_id, route_id)) {
+ // Wrap the event handler to be sure the current page's onunload handler
+ // has a chance to run before we render the new page.
handler.reset(new CrossSiteResourceHandler(handler.Pass(), request));
}
@@ -1137,6 +1140,12 @@ void ResourceDispatcherHostImpl::BeginRequest(
throttles.push_back(new PowerSaveBlockResourceThrottle());
}
+ if (request_data.resource_type == ResourceType::MAIN_FRAME) {
+ throttles.insert(
+ throttles.begin(),
+ new TransferNavigationResourceThrottle(request));
+ }
+
throttles.push_back(
scheduler_->ScheduleRequest(child_id, route_id, request).release());
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc
index 4a9e275..75f3c7b 100644
--- a/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -9,7 +9,6 @@
#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"
@@ -1699,9 +1698,7 @@ TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) {
EXPECT_EQ(0, host_.pending_requests());
}
-// Test transferred navigations with text/html, which doesn't trigger any
-// content sniffing.
-TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) {
+TEST_F(ResourceDispatcherHostTest, TransferNavigation) {
EXPECT_EQ(0, host_.pending_requests());
int render_view_id = 0;
@@ -1721,22 +1718,7 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) {
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.
- 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.
+ // Restore.
SetBrowserClientForTesting(old_client);
// This second filter is used to emulate a second process.
@@ -1746,78 +1728,10 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) {
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,
@@ -1829,17 +1743,20 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationText) {
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(2U, msgs.size());
- EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
- CheckSuccessfulRequest(msgs[1], kResponseBody);
+ ASSERT_EQ(1U, msgs.size());
+ CheckSuccessfulRequest(msgs[0], kResponseBody);
}
TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) {
@@ -1852,7 +1769,6 @@ 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");
@@ -1880,19 +1796,6 @@ 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.
@@ -1909,6 +1812,11 @@ 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"));
@@ -1924,16 +1832,18 @@ 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(2U, msgs.size());
- EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
- CheckSuccessfulRequest(msgs[1], kResponseBody);
+ ASSERT_EQ(1U, msgs.size());
+ CheckSuccessfulRequest(msgs[0], kResponseBody);
}
-TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) {
+TEST_F(ResourceDispatcherHostTest, TransferNavigationAndThenRedirect) {
EXPECT_EQ(0, host_.pending_requests());
int render_view_id = 0;
@@ -1953,30 +1863,6 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) {
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);
@@ -1987,6 +1873,13 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) {
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"));
@@ -1997,8 +1890,24 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) {
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);
@@ -2009,16 +1918,25 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) {
EXPECT_EQ(new_request_id, info->GetRequestID());
EXPECT_EQ(second_filter, info->filter());
- // Let request complete.
+ // 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);
base::MessageLoop::current()->RunUntilIdle();
+ // Flush all the pending requests.
+ while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
+
// Check generated messages.
ResourceIPCAccumulator::ClassifiedMessages msgs;
accum_.GetClassifiedMessages(&msgs);
- ASSERT_EQ(2U, msgs.size());
+ ASSERT_EQ(1U, msgs.size());
+
+ // We should have received a redirect followed by a "normal" payload.
EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
- CheckSuccessfulRequest(msgs[1], kResponseBody);
+ msgs[0].erase(msgs[0].begin());
+ CheckSuccessfulRequest(msgs[0], kResponseBody);
}
TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) {
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc
index 8f70ab5..c99fe5b 100644
--- a/content/browser/loader/resource_loader.cc
+++ b/content/browser/loader/resource_loader.cc
@@ -9,7 +9,6 @@
#include "base/metrics/histogram.h"
#include "base/time/time.h"
#include "content/browser/child_process_security_policy_impl.h"
-#include "content/browser/loader/cross_site_resource_handler.h"
#include "content/browser/loader/resource_loader_delegate.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/ssl/ssl_client_auth_handler.h"
@@ -166,10 +165,10 @@ void ResourceLoader::MarkAsTransferring(const GURL& target_url) {
}
void ResourceLoader::CompleteTransfer() {
- DCHECK_EQ(DEFERRED_READ, deferred_stage_);
+ DCHECK_EQ(DEFERRED_REDIRECT, deferred_stage_);
is_transferring_ = false;
- GetRequestInfo()->cross_site_handler()->ResumeResponse();
+ Resume();
}
ResourceRequestInfoImpl* ResourceLoader::GetRequestInfo() {
diff --git a/content/browser/loader/transfer_navigation_resource_throttle.cc b/content/browser/loader/transfer_navigation_resource_throttle.cc
new file mode 100644
index 0000000..8021bce
--- /dev/null
+++ b/content/browser/loader/transfer_navigation_resource_throttle.cc
@@ -0,0 +1,93 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/loader/transfer_navigation_resource_throttle.h"
+
+#include "base/bind.h"
+#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/renderer_host/render_view_host_delegate.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/global_request_id.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/resource_request_info.h"
+#include "content/public/common/referrer.h"
+#include "net/url_request/url_request.h"
+
+namespace content {
+
+namespace {
+
+void RequestTransferURLOnUIThread(int render_process_id,
+ int render_view_id,
+ const GURL& new_url,
+ const Referrer& referrer,
+ WindowOpenDisposition window_open_disposition,
+ int64 frame_id,
+ const GlobalRequestID& global_request_id) {
+ RenderViewHost* rvh =
+ RenderViewHost::FromID(render_process_id, render_view_id);
+ if (!rvh)
+ return;
+
+ RenderViewHostDelegate* delegate = rvh->GetDelegate();
+ if (!delegate)
+ return;
+
+ // We don't know whether the original request had |user_action| set to true.
+ // However, since we force the navigation to be in the current tab, it doesn't
+ // matter.
+ delegate->RequestTransferURL(
+ new_url, referrer, window_open_disposition,
+ frame_id, global_request_id, false, true);
+}
+
+} // namespace
+
+TransferNavigationResourceThrottle::TransferNavigationResourceThrottle(
+ net::URLRequest* request)
+ : request_(request) {
+}
+
+TransferNavigationResourceThrottle::~TransferNavigationResourceThrottle() {
+}
+
+void TransferNavigationResourceThrottle::WillRedirectRequest(
+ const GURL& new_url,
+ bool* defer) {
+ const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
+
+ // If a toplevel request is redirecting across extension extents, we want to
+ // switch processes. We do this by deferring the redirect and resuming the
+ // request once the navigation controller properly assigns the right process
+ // to host the new URL.
+ // TODO(mpcomplete): handle for cases other than extensions (e.g. WebUI).
+ ResourceContext* resource_context = info->GetContext();
+ if (GetContentClient()->browser()->ShouldSwapProcessesForRedirect(
+ resource_context, request_->url(), new_url)) {
+ int render_process_id, render_view_id;
+ if (info->GetAssociatedRenderView(&render_process_id, &render_view_id)) {
+ GlobalRequestID global_id(info->GetChildID(), info->GetRequestID());
+
+ ResourceDispatcherHostImpl::Get()->MarkAsTransferredNavigation(global_id,
+ new_url);
+
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&RequestTransferURLOnUIThread,
+ render_process_id,
+ render_view_id,
+ new_url,
+ Referrer(GURL(request_->referrer()), info->GetReferrerPolicy()),
+ CURRENT_TAB,
+ info->GetFrameID(),
+ global_id));
+
+ *defer = true;
+ }
+ }
+}
+
+} // namespace content
diff --git a/content/browser/loader/transfer_navigation_resource_throttle.h b/content/browser/loader/transfer_navigation_resource_throttle.h
new file mode 100644
index 0000000..6d08c2a
--- /dev/null
+++ b/content/browser/loader/transfer_navigation_resource_throttle.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_LOADER_TRANSFER_NAVIGATION_RESOURCE_THROTTLE_H_
+#define CONTENT_BROWSER_LOADER_TRANSFER_NAVIGATION_RESOURCE_THROTTLE_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "content/public/browser/resource_throttle.h"
+
+namespace net {
+class URLRequest;
+}
+
+namespace content {
+
+// This ResourceThrottle checks whether a navigation redirect will cause a
+// renderer process swap. When that happens, we remember the request so
+// that we can transfer it to be handled by the new renderer. This fixes
+// http://crbug.com/79520
+class TransferNavigationResourceThrottle : public ResourceThrottle {
+ public:
+ explicit TransferNavigationResourceThrottle(net::URLRequest* request);
+ virtual ~TransferNavigationResourceThrottle();
+
+ // ResourceThrottle implementation:
+ virtual void WillRedirectRequest(const GURL& new_url, bool* defer) OVERRIDE;
+
+ private:
+ net::URLRequest* request_;
+
+ DISALLOW_COPY_AND_ASSIGN(TransferNavigationResourceThrottle);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_LOADER_TRANSFER_NAVIGATION_RESOURCE_THROTTLE_H_
diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h
index aac79cf..997452a 100644
--- a/content/browser/renderer_host/render_view_host_delegate.h
+++ b/content/browser/renderer_host/render_view_host_delegate.h
@@ -93,15 +93,10 @@ class CONTENT_EXPORT RenderViewHostDelegate {
const base::TimeTicks& proceed_time) = 0;
// The |pending_render_view_host| is ready to commit a page. The delegate
- // should ensure that the old RenderViewHost runs its unload handler first
- // and determine whether a RenderViewHost transfer is needed.
+ // should ensure that the old RenderViewHost runs its unload handler first.
virtual void OnCrossSiteResponse(
RenderViewHost* pending_render_view_host,
- const GlobalRequestID& global_request_id,
- bool is_transfer,
- const GURL& transfer_url,
- const Referrer& referrer,
- int64 frame_id) = 0;
+ const GlobalRequestID& global_request_id) = 0;
protected:
virtual ~RendererManagement() {}
diff --git a/content/browser/web_contents/render_view_host_manager.cc b/content/browser/web_contents/render_view_host_manager.cc
index 53d7681..c72e165 100644
--- a/content/browser/web_contents/render_view_host_manager.cc
+++ b/content/browser/web_contents/render_view_host_manager.cc
@@ -33,21 +33,12 @@
namespace content {
-RenderViewHostManager::PendingNavigationParams::PendingNavigationParams()
- : is_transfer(false), frame_id(-1) {
+RenderViewHostManager::PendingNavigationParams::PendingNavigationParams() {
}
RenderViewHostManager::PendingNavigationParams::PendingNavigationParams(
- const GlobalRequestID& global_request_id,
- bool is_transfer,
- const GURL& transfer_url,
- Referrer referrer,
- int64 frame_id)
- : global_request_id(global_request_id),
- is_transfer(is_transfer),
- transfer_url(transfer_url),
- referrer(referrer),
- frame_id(frame_id) {
+ const GlobalRequestID& global_request_id)
+ : global_request_id(global_request_id) {
}
RenderViewHostManager::RenderViewHostManager(
@@ -248,24 +239,8 @@ void RenderViewHostManager::SwappedOut(RenderViewHost* render_view_host) {
return;
}
- // Now that the unload handler has run, we need to either initiate the
- // pending transfer (if there is one) or resume the paused response (if not).
- // TODO(creis): The blank swapped out page is visible during this time, but
- // we can shorten this by delivering the response directly, rather than
- // forcing an identical request to be made.
- if (pending_nav_params_->is_transfer) {
- // We don't know whether the original request had |user_action| set to true.
- // However, since we force the navigation to be in the current tab, it
- // doesn't matter.
- render_view_host->GetDelegate()->RequestTransferURL(
- pending_nav_params_->transfer_url,
- pending_nav_params_->referrer,
- CURRENT_TAB,
- pending_nav_params_->frame_id,
- pending_nav_params_->global_request_id,
- false,
- true);
- } else if (pending_render_view_host_) {
+ // Now that the unload handler has run, we need to resume the paused response.
+ if (pending_render_view_host_) {
RenderProcessHostImpl* pending_process =
static_cast<RenderProcessHostImpl*>(
pending_render_view_host_->GetProcess());
@@ -403,32 +378,22 @@ void RenderViewHostManager::ShouldClosePage(
void RenderViewHostManager::OnCrossSiteResponse(
RenderViewHost* pending_render_view_host,
- const GlobalRequestID& global_request_id,
- bool is_transfer,
- const GURL& transfer_url,
- const Referrer& referrer,
- int64 frame_id) {
- // This should be called either when the pending RVH is ready to commit or
- // when we realize that the current RVH's request requires a transfer.
- DCHECK(
- pending_render_view_host == pending_render_view_host_ ||
- pending_render_view_host == render_view_host_);
-
- // TODO(creis): Eventually we will want to check all navigation responses
- // here, but currently we pass information for a transfer if
- // ShouldSwapProcessesForRedirect returned true in the network stack.
- // In that case, we should set up a transfer after the unload handler runs.
- // If is_transfer is false, we will just run the unload handler and resume.
- pending_nav_params_.reset(new PendingNavigationParams(
- global_request_id, is_transfer, transfer_url, referrer, frame_id));
+ const GlobalRequestID& global_request_id) {
+ // This should be called when the pending RVH is ready to commit.
+ DCHECK_EQ(pending_render_view_host_, pending_render_view_host);
+
+ // Remember the request ID until the unload handler has run.
+ pending_nav_params_.reset(new PendingNavigationParams(global_request_id));
// Run the unload handler of the current page.
SwapOutOldPage();
}
void RenderViewHostManager::SwapOutOldPage() {
- // Should only see this while we have a pending renderer or transfer.
- CHECK(cross_navigation_pending_ || pending_nav_params_.get());
+ // Should only see this while we have a pending renderer.
+ if (!cross_navigation_pending_)
+ return;
+ DCHECK(pending_render_view_host_);
// Tell the old renderer it is being swapped out. This will fire the unload
// handler (without firing the beforeunload handler a second time). When the
@@ -441,8 +406,7 @@ void RenderViewHostManager::SwapOutOldPage() {
// means it is not a download or unsafe page, and we are going to perform the
// navigation. Thus, we no longer need to remember that the RenderViewHost
// is part of a pending cross-site request.
- if (pending_render_view_host_)
- pending_render_view_host_->SetHasPendingCrossSiteRequest(false);
+ pending_render_view_host_->SetHasPendingCrossSiteRequest(false);
}
void RenderViewHostManager::Observe(
@@ -960,12 +924,7 @@ RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate(
DCHECK(!pending_render_view_host_->are_navigations_suspended());
bool is_transfer =
entry.transferred_global_request_id() != GlobalRequestID();
- if (is_transfer) {
- // We don't need to stop the old renderer or run beforeunload/unload
- // handlers, because those have already been done.
- DCHECK(pending_nav_params_->global_request_id ==
- entry.transferred_global_request_id());
- } else {
+ if (!is_transfer) {
// Also make sure the old render view stops, in case a load is in
// progress. (We don't want to do this for transfers, since it will
// interrupt the transfer with an unexpected DidStopLoading.)
@@ -974,13 +933,13 @@ RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate(
pending_render_view_host_->SetNavigationsSuspended(true,
base::TimeTicks());
-
- // Tell the CrossSiteRequestManager that this RVH has a pending cross-site
- // request, so that ResourceDispatcherHost will know to tell us to run the
- // old page's unload handler before it sends the response.
- pending_render_view_host_->SetHasPendingCrossSiteRequest(true);
}
+ // Tell the CrossSiteRequestManager that this RVH has a pending cross-site
+ // request, so that ResourceDispatcherHost will know to tell us to run the
+ // old page's unload handler before it sends the response.
+ pending_render_view_host_->SetHasPendingCrossSiteRequest(true);
+
// We now have a pending RVH.
DCHECK(!cross_navigation_pending_);
cross_navigation_pending_ = true;
diff --git a/content/browser/web_contents/render_view_host_manager.h b/content/browser/web_contents/render_view_host_manager.h
index aef6383..aacc90b 100644
--- a/content/browser/web_contents/render_view_host_manager.h
+++ b/content/browser/web_contents/render_view_host_manager.h
@@ -14,7 +14,6 @@
#include "content/common/content_export.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
-#include "content/public/common/referrer.h"
namespace content {
@@ -218,11 +217,7 @@ class CONTENT_EXPORT RenderViewHostManager
const base::TimeTicks& proceed_time) OVERRIDE;
virtual void OnCrossSiteResponse(
RenderViewHost* pending_render_view_host,
- const GlobalRequestID& global_request_id,
- bool is_transfer,
- const GURL& transfer_url,
- const Referrer& referrer,
- int64 frame_id) OVERRIDE;
+ const GlobalRequestID& global_request_id) OVERRIDE;
// NotificationObserver implementation.
virtual void Observe(int type,
@@ -240,8 +235,7 @@ class CONTENT_EXPORT RenderViewHostManager
RenderViewHostImpl* GetSwappedOutRenderViewHost(SiteInstance* instance);
// Runs the unload handler in the current page, when we know that a pending
- // cross-process navigation is going to commit. We may initiate a transfer
- // to a new process after this completes or times out.
+ // cross-process navigation is going to commit.
void SwapOutOldPage();
private:
@@ -249,34 +243,13 @@ class CONTENT_EXPORT RenderViewHostManager
friend class TestWebContents;
// Tracks information about a navigation while a cross-process transition is
- // in progress, in case we need to transfer it to a new RenderViewHost.
+ // in progress.
+ // TODO(creis): Add transfer navigation params for http://crbug.com/238331.
struct PendingNavigationParams {
PendingNavigationParams();
- PendingNavigationParams(const GlobalRequestID& global_request_id,
- bool is_transfer,
- const GURL& transfer_url,
- Referrer referrer,
- int64 frame_id);
-
- // The child ID and request ID for the pending navigation. Present whether
- // |is_transfer| is true or false.
- GlobalRequestID global_request_id;
-
- // Whether this pending navigation needs to be transferred to another
- // process than the one it was going to commit in. If so, the
- // |transfer_url|, |referrer|, and |frame_id| parameters will be set.
- bool is_transfer;
-
- // If |is_transfer|, this is the destination URL to request in the new
- // process.
- GURL transfer_url;
+ explicit PendingNavigationParams(const GlobalRequestID& global_request_id);
- // If |is_transfer|, this is the referrer to use for the request in the new
- // process.
- Referrer referrer;
-
- // If |is_transfer|, this is the frame ID to use in RequestTransferURL.
- int64 frame_id;
+ GlobalRequestID global_request_id;
};
// Returns whether this tab should transition to a new renderer for
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index e0c955f..2ebe303 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -113,43 +113,34 @@
// a new RenderViewHost dedicated to the new SiteInstance. This works as
// follows:
//
-// - RVHM::Navigate determines whether the destination is cross-site, and if so,
+// - Navigate determines whether the destination is cross-site, and if so,
// it creates a pending_render_view_host_.
// - The pending RVH is "suspended," so that no navigation messages are sent to
-// its renderer until the beforeunload JavaScript handler has a chance to
+// its renderer until the onbeforeunload JavaScript handler has a chance to
// run in the current RVH.
// - The pending RVH tells CrossSiteRequestManager (a thread-safe singleton)
-// that it has a pending cross-site request. We will check this on the IO
-// thread when deciding how to handle the response.
-// - The current RVH runs its beforeunload handler. If it returns false, we
+// that it has a pending cross-site request. ResourceDispatcherHost will
+// check for this when the response arrives.
+// - The current RVH runs its onbeforeunload handler. If it returns false, we
// cancel all the pending logic. Otherwise we allow the pending RVH to send
// the navigation request to its renderer.
// - ResourceDispatcherHost receives a ResourceRequest on the IO thread for the
-// main resource load on the pending RVH. It creates a
-// CrossSiteResourceHandler to check whether a process swap is needed when
-// the request is ready to commit.
+// main resource load on the pending RVH. It checks CrossSiteRequestManager
+// to see that it is a cross-site request, and installs a
+// CrossSiteResourceHandler.
// - When RDH receives a response, the BufferedResourceHandler determines
// whether it is a download. If so, it sends a message to the new renderer
// causing it to cancel the request, and the download proceeds. For now, the
// pending RVH remains until the next DidNavigate event for this
// WebContentsImpl. This isn't ideal, but it doesn't affect any functionality.
// - After RDH receives a response and determines that it is safe and not a
-// download, the CrossSiteResourceHandler checks whether a process swap is
-// needed (either because CrossSiteRequestManager has state for it or because
-// a transfer was needed for a redirect).
-// - If so, CrossSiteResourceHandler pauses the response to first run the old
-// page's unload handler. It does this by asynchronously calling the
-// OnCrossSiteResponse method of RenderViewHostManager on the UI thread, which
-// sends a SwapOut message to the current RVH.
-// - Once the unload handler is finished, RVHM::SwappedOut checks if a transfer
-// to a new process is needed, based on the stored pending_nav_params_. (This
-// is independent of whether we started out with a cross-process navigation.)
-// - If not, it just tells the ResourceDispatcherHost to resume the response
-// to its current RenderViewHost.
-// - If so, it cancels the current pending RenderViewHost and sets up a new
-// navigation using RequestTransferURL. When the transferred request
-// arrives in the ResourceDispatcherHost, we transfer the response and
-// resume it.
+// download, it pauses the response to first run the old page's onunload
+// handler. It does this by asynchronously calling the OnCrossSiteResponse
+// method of WebContentsImpl on the UI thread, which sends a SwapOut message
+// to the current RVH.
+// - Once the onunload handler is finished, a SwapOut_ACK message is sent to
+// the ResourceDispatcherHost, who unpauses the response. Data is then sent
+// to the pending RVH.
// - The pending renderer sends a FrameNavigate message that invokes the
// DidNavigate method. This replaces the current RVH with the
// pending RVH.
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc
index c11cb51..aded7ae 100644
--- a/content/browser/web_contents/web_contents_impl_unittest.cc
+++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -1062,7 +1062,7 @@ TEST_F(WebContentsImplTest, CrossSiteCantPreemptAfterUnload) {
// Simulate the pending renderer's response, which leads to an unload request
// being sent to orig_rvh.
contents()->GetRenderManagerForTesting()->OnCrossSiteResponse(
- pending_rvh, GlobalRequestID(0, 0), false, GURL(), Referrer(), 1);
+ pending_rvh, GlobalRequestID(0, 0));
// Suppose the original renderer navigates now, while the unload request is in
// flight. We should ignore it, wait for the unload ack, and let the pending
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 7835950..29e22da 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -690,6 +690,8 @@
'browser/loader/sync_resource_handler.h',
'browser/loader/throttling_resource_handler.cc',
'browser/loader/throttling_resource_handler.h',
+ 'browser/loader/transfer_navigation_resource_throttle.cc',
+ 'browser/loader/transfer_navigation_resource_throttle.h',
'browser/loader/upload_data_stream_builder.cc',
'browser/loader/upload_data_stream_builder.h',
'browser/mach_broker_mac.h',