| Index: content/browser/frame_host/navigation_request.cc
|
| diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
|
| index 84cc93f4ccf585d896080434989b8b100eee7c3f..7e2fad9b1f1ad11978c2232864b33f889ff70e02 100644
|
| --- a/content/browser/frame_host/navigation_request.cc
|
| +++ b/content/browser/frame_host/navigation_request.cc
|
| @@ -13,6 +13,7 @@
|
| #include "content/browser/frame_host/navigation_handle_impl.h"
|
| #include "content/browser/frame_host/navigation_request_info.h"
|
| #include "content/browser/frame_host/navigator.h"
|
| +#include "content/browser/frame_host/navigator_impl.h"
|
| #include "content/browser/loader/navigation_url_loader.h"
|
| #include "content/browser/service_worker/service_worker_context_wrapper.h"
|
| #include "content/browser/service_worker/service_worker_navigation_handle.h"
|
| @@ -224,8 +225,17 @@ void NavigationRequest::BeginNavigation() {
|
| // There is no need to make a network request for this navigation, so commit
|
| // it immediately.
|
| state_ = RESPONSE_STARTED;
|
| - frame_tree_node_->navigator()->CommitNavigation(
|
| - this, nullptr, scoped_ptr<StreamHandle>());
|
| +
|
| + // Select an appropriate RenderFrameHost.
|
| + RenderFrameHostImpl* render_frame_host =
|
| + frame_tree_node_->render_manager()->GetFrameHostForNavigation(*this);
|
| + NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL(render_frame_host,
|
| + common_params_.url);
|
| +
|
| + // Inform the NavigationHandle that the navigation will commit.
|
| + navigation_handle_->ReadyToCommitNavigation(render_frame_host);
|
| +
|
| + CommitNavigation();
|
| }
|
|
|
| void NavigationRequest::CreateNavigationHandle(int pending_nav_entry_id) {
|
| @@ -269,6 +279,16 @@ void NavigationRequest::OnResponseStarted(
|
| DCHECK(state_ == STARTED);
|
| state_ = RESPONSE_STARTED;
|
|
|
| + // HTTP 204 (No Content) and HTTP 205 (Reset Content) responses should not
|
| + // commit; they leave the frame showing the previous page.
|
| + DCHECK(response);
|
| + if (response->head.headers.get() &&
|
| + (response->head.headers->response_code() == 204 ||
|
| + response->head.headers->response_code() == 205)) {
|
| + frame_tree_node_->ResetNavigationRequest(false);
|
| + return;
|
| + }
|
| +
|
| // Update the service worker params of the request params.
|
| request_params_.should_create_service_worker =
|
| (frame_tree_node_->pending_sandbox_flags() &
|
| @@ -285,8 +305,21 @@ void NavigationRequest::OnResponseStarted(
|
| else
|
| common_params_.lofi_state = LOFI_OFF;
|
|
|
| - frame_tree_node_->navigator()->CommitNavigation(
|
| - this, response.get(), std::move(body));
|
| + // Select an appropriate renderer to commit the navigation.
|
| + RenderFrameHostImpl* render_frame_host =
|
| + frame_tree_node_->render_manager()->GetFrameHostForNavigation(*this);
|
| + NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL(render_frame_host,
|
| + common_params_.url);
|
| +
|
| + // Store the response and the StreamHandle until checks have been processed.
|
| + response_ = response;
|
| + body_ = std::move(body);
|
| +
|
| + // Check if the navigation should be allowed to proceed.
|
| + navigation_handle_->WillProcessResponse(
|
| + render_frame_host, response->head.headers.get(),
|
| + base::Bind(&NavigationRequest::OnWillProcessResponseChecksComplete,
|
| + base::Unretained(this)));
|
| }
|
|
|
| void NavigationRequest::OnRequestFailed(bool has_stale_copy_in_cache,
|
| @@ -342,6 +375,50 @@ void NavigationRequest::OnRedirectChecksComplete(
|
| loader_->FollowRedirect();
|
| }
|
|
|
| +void NavigationRequest::OnWillProcessResponseChecksComplete(
|
| + NavigationThrottle::ThrottleCheckResult result) {
|
| + CHECK(result != NavigationThrottle::DEFER);
|
| +
|
| + // Abort the request if needed. This will destroy the NavigationRequest.
|
| + if (result == NavigationThrottle::CANCEL_AND_IGNORE ||
|
| + result == NavigationThrottle::CANCEL) {
|
| + // TODO(clamy): distinguish between CANCEL and CANCEL_AND_IGNORE.
|
| + frame_tree_node_->ResetNavigationRequest(false);
|
| + return;
|
| + }
|
| +
|
| + // Have the processing of the response resume in the network stack.
|
| + loader_->ProceedWithResponse();
|
| +
|
| + CommitNavigation();
|
| +
|
| + // DO NOT ADD CODE after this. The previous call to CommitNavigation caused
|
| + // the destruction of the NavigationRequest.
|
| +}
|
| +
|
| +void NavigationRequest::CommitNavigation() {
|
| + DCHECK(response_ || !ShouldMakeNetworkRequestForURL(common_params_.url));
|
| +
|
| + // Retrieve the RenderFrameHost that needs to commit the navigation.
|
| + RenderFrameHostImpl* render_frame_host =
|
| + navigation_handle_->GetRenderFrameHost();
|
| + DCHECK(render_frame_host ==
|
| + frame_tree_node_->render_manager()->current_frame_host() ||
|
| + render_frame_host ==
|
| + frame_tree_node_->render_manager()->speculative_frame_host());
|
| +
|
| + TransferNavigationHandleOwnership(render_frame_host);
|
| + render_frame_host->CommitNavigation(response_.get(), std::move(body_),
|
| + common_params_, request_params_,
|
| + is_view_source_);
|
| +
|
| + // When navigating to a Javascript url, the NavigationRequest is not stored
|
| + // in the FrameTreeNode. Therefore do not reset it, as this could cancel an
|
| + // existing pending navigation.
|
| + if (!common_params_.url.SchemeIs(url::kJavaScriptScheme))
|
| + frame_tree_node_->ResetNavigationRequest(true);
|
| +}
|
| +
|
| void NavigationRequest::InitializeServiceWorkerHandleIfNeeded() {
|
| // Only initialize the ServiceWorkerNavigationHandle if it can be created for
|
| // this frame.
|
|
|