Commit message: None
CVE: CVE-2018-18351
CWE: CWE-20
Vulnerability description: Lack of proper validation of ancestor frames site when sending lax cookies in Navigation in Google Chrome prior to 71.0.3578.80 allowed a remote attacker to bypass SameSite cookie policy via a crafted HTML page.

Project: Chrome

void AddAdditionalRequestHeaders(
    net::HttpRequestHeaders* headers,
    std::unique_ptr<net::HttpRequestHeaders> embedder_additional_headers,
    const GURL& url,
    FrameMsg_Navigate_Type::Value navigation_type,
    BrowserContext* browser_context,
    const std::string& method,
    const std::string user_agent_override,
    FrameTreeNode* frame_tree_node) {
  if (!url.SchemeIsHTTPOrHTTPS())
    return;

  if (!base::FeatureList::IsEnabled(features::kDataSaverHoldback)) {
    bool is_reload =
        navigation_type == FrameMsg_Navigate_Type::RELOAD ||
        navigation_type == FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE ||
        navigation_type == FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL;
    if (is_reload)
      headers->RemoveHeader("Save-Data");

    if (GetContentClient()->browser()->IsDataSaverEnabled(browser_context))
      headers->SetHeaderIfMissing("Save-Data", "on");
  }

  if (embedder_additional_headers)
    headers->MergeFrom(*(embedder_additional_headers.get()));

  headers->SetHeaderIfMissing("Upgrade-Insecure-Requests", "1");

  headers->SetHeaderIfMissing(net::HttpRequestHeaders::kUserAgent,
                              user_agent_override.empty()
                                  ? GetContentClient()->GetUserAgent()
                                  : user_agent_override);

  if (!NeedsHTTPOrigin(headers, method))
    return;

  url::Origin origin;
  if (frame_tree_node->IsMainFrame()) {
    origin = url::Origin::Create(url);
  } else if ((frame_tree_node->active_sandbox_flags() &
              blink::WebSandboxFlags::kOrigin) ==
             blink::WebSandboxFlags::kNone) {
    origin = frame_tree_node->frame_tree()->root()->current_origin();
  }

  headers->SetHeader(net::HttpRequestHeaders::kOrigin, origin.Serialize());
}

Project: Chrome

NavigationRequest::CheckContentSecurityPolicyFrameSrc(bool is_redirect) {
  if (common_params_.url.SchemeIs(url::kAboutScheme))
    return CONTENT_SECURITY_POLICY_CHECK_PASSED;

  if (common_params_.should_check_main_world_csp ==
      CSPDisposition::DO_NOT_CHECK) {
    return CONTENT_SECURITY_POLICY_CHECK_PASSED;
  }

  if (frame_tree_node()->IsMainFrame())
    return CONTENT_SECURITY_POLICY_CHECK_PASSED;

  FrameTreeNode* parent_ftn = frame_tree_node()->parent();
  DCHECK(parent_ftn);
  RenderFrameHostImpl* parent = parent_ftn->current_frame_host();
  DCHECK(parent);


  bool allowed = parent->IsAllowedByCsp(
      CSPDirective::FrameSrc, common_params_.url, is_redirect,
      common_params_.source_location.value_or(SourceLocation()),
      CSPContext::CHECK_REPORT_ONLY_CSP);

  DCHECK(allowed);

  if (!is_redirect) {
    GURL new_url;
    if (parent->ShouldModifyRequestUrlForCsp(
            common_params_.url, true /* is subresource */, &new_url)) {
      common_params_.url = new_url;
      request_params_.original_url = new_url;
    }
  }

  if (parent->IsAllowedByCsp(
          CSPDirective::FrameSrc, common_params_.url, is_redirect,
          common_params_.source_location.value_or(SourceLocation()),
          CSPContext::CHECK_ENFORCED_CSP)) {
    return CONTENT_SECURITY_POLICY_CHECK_PASSED;
  }

  return CONTENT_SECURITY_POLICY_CHECK_FAILED;
}

Project: Chrome

void NavigationRequest::CommitErrorPage(
    RenderFrameHostImpl* render_frame_host,
    const base::Optional<std::string>& error_page_content) {
  UpdateRequestNavigationParamsHistory();
  frame_tree_node_->TransferNavigationRequestOwnership(render_frame_host);
  navigation_handle_->ReadyToCommitNavigation(render_frame_host, true);
  render_frame_host->FailedNavigation(common_params_, request_params_,
                                      has_stale_copy_in_cache_, net_error_,
                                      error_page_content);
}

Project: Chrome

void NavigationRequest::CommitNavigation() {
  UpdateRequestNavigationParamsHistory();
  DCHECK(response_ || !IsURLHandledByNetworkStack(common_params_.url) ||
         navigation_handle_->IsSameDocument());
  DCHECK(!common_params_.url.SchemeIs(url::kJavaScriptScheme));

  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());

  frame_tree_node_->TransferNavigationRequestOwnership(render_frame_host);
  render_frame_host->CommitNavigation(
      response_.get(), std::move(url_loader_client_endpoints_), common_params_,
      request_params_, is_view_source_, std::move(subresource_loader_params_),
      std::move(subresource_overrides_), devtools_navigation_token_);

  RenderProcessHostImpl::NotifySpareManagerAboutRecentlyUsedBrowserContext(
      render_frame_host->GetSiteInstance()->GetBrowserContext());
}

Project: Chrome

std::unique_ptr<NavigationRequest> NavigationRequest::CreateBrowserInitiated(
    FrameTreeNode* frame_tree_node,
    const GURL& dest_url,
    const Referrer& dest_referrer,
    const FrameNavigationEntry& frame_entry,
    const NavigationEntryImpl& entry,
    FrameMsg_Navigate_Type::Value navigation_type,
    PreviewsState previews_state,
    bool is_same_document_history_load,
    bool is_history_navigation_in_new_child,
    const scoped_refptr<network::ResourceRequestBody>& post_body,
    const base::TimeTicks& navigation_start,
    NavigationControllerImpl* controller,
    std::unique_ptr<NavigationUIData> navigation_ui_data) {
  scoped_refptr<network::ResourceRequestBody> request_body;
  std::string post_content_type;
  if (post_body) {
    request_body = post_body;
  } else if (frame_entry.method() == "POST") {
    request_body = frame_entry.GetPostData(&post_content_type);
    post_content_type =
        base::TrimWhitespaceASCII(post_content_type, base::TRIM_ALL)
            .as_string();
  }
  bool is_form_submission = !!request_body;

  base::Optional<url::Origin> initiator =
      frame_tree_node->IsMainFrame()
          ? base::Optional<url::Origin>()
          : base::Optional<url::Origin>(
                frame_tree_node->frame_tree()->root()->current_origin());

  bool browser_initiated = !entry.is_renderer_initiated();

  CommonNavigationParams common_params = entry.ConstructCommonNavigationParams(
      frame_entry, request_body, dest_url, dest_referrer, navigation_type,
      previews_state, navigation_start);

  RequestNavigationParams request_params =
      entry.ConstructRequestNavigationParams(
          frame_entry, common_params.url, common_params.method,
          is_history_navigation_in_new_child,
          entry.GetSubframeUniqueNames(frame_tree_node),
          controller->GetPendingEntryIndex() == -1,
          controller->GetIndexOfEntry(&entry),
          controller->GetLastCommittedEntryIndex(),
          controller->GetEntryCount());
  request_params.post_content_type = post_content_type;

  std::unique_ptr<NavigationRequest> navigation_request(new NavigationRequest(
      frame_tree_node, common_params,
      mojom::BeginNavigationParams::New(
          entry.extra_headers(), net::LOAD_NORMAL,
          false /* skip_service_worker */, REQUEST_CONTEXT_TYPE_LOCATION,
          blink::WebMixedContentContextType::kBlockable, is_form_submission,
          GURL() /* searchable_form_url */,
          std::string() /* searchable_form_encoding */, initiator,
          GURL() /* client_side_redirect_url */,
          base::nullopt /* devtools_initiator_info */),
      request_params, browser_initiated, false /* from_begin_navigation */,
      &frame_entry, &entry, std::move(navigation_ui_data)));
  return navigation_request;
}

Project: Chrome

void NavigationRequest::CreateNavigationHandle() {
  DCHECK_EQ(frame_tree_node_->navigation_request(), this);
  FrameTreeNode* frame_tree_node = frame_tree_node_;

  std::vector<GURL> redirect_chain;
  if (!begin_params_->client_side_redirect_url.is_empty())
    redirect_chain.push_back(begin_params_->client_side_redirect_url);
  redirect_chain.push_back(common_params_.url);

  bool is_external_protocol =
      !GetContentClient()->browser()->IsHandledURL(common_params_.url);

  net::HttpRequestHeaders headers;
  headers.AddHeadersFromString(begin_params_->headers);

  std::unique_ptr<NavigationHandleImpl> navigation_handle =
      NavigationHandleImpl::Create(
          common_params_.url, redirect_chain, frame_tree_node_,
          !browser_initiated_,
          FrameMsg_Navigate_Type::IsSameDocument(
              common_params_.navigation_type),
          common_params_.navigation_start, nav_entry_id_,
          common_params_.started_from_context_menu,
          common_params_.should_check_main_world_csp,
          begin_params_->is_form_submission, common_params_.suggested_filename,
          std::move(navigation_ui_data_), common_params_.method,
          std::move(headers), common_params_.post_data,
          Referrer::SanitizeForRequest(common_params_.url,
                                       common_params_.referrer),
          common_params_.has_user_gesture, common_params_.transition,
          is_external_protocol, begin_params_->request_context_type,
          begin_params_->mixed_content_context_type);

  if (!frame_tree_node->navigation_request()) {
    return;
  }

  navigation_handle_ = std::move(navigation_handle);

  if (!begin_params_->searchable_form_url.is_empty()) {
    navigation_handle_->set_searchable_form_url(
        begin_params_->searchable_form_url);
    navigation_handle_->set_searchable_form_encoding(
        begin_params_->searchable_form_encoding);
  }

  if (common_params_.source_location) {
    navigation_handle_->set_source_location(
        common_params_.source_location.value());
  }
}

Project: Chrome

NavigationRequest::NavigationRequest(
    FrameTreeNode* frame_tree_node,
    const CommonNavigationParams& common_params,
    mojom::BeginNavigationParamsPtr begin_params,
    const RequestNavigationParams& request_params,
    bool browser_initiated,
    bool from_begin_navigation,
    const FrameNavigationEntry* frame_entry,
    const NavigationEntryImpl* entry,
    std::unique_ptr<NavigationUIData> navigation_ui_data)
    : frame_tree_node_(frame_tree_node),
      common_params_(common_params),
      begin_params_(std::move(begin_params)),
      request_params_(request_params),
      browser_initiated_(browser_initiated),
      navigation_ui_data_(std::move(navigation_ui_data)),
      state_(NOT_STARTED),
      restore_type_(RestoreType::NONE),
      is_view_source_(false),
      bindings_(NavigationEntryImpl::kInvalidBindings),
      response_should_be_rendered_(true),
      associated_site_instance_type_(AssociatedSiteInstanceType::NONE),
      from_begin_navigation_(from_begin_navigation),
      has_stale_copy_in_cache_(false),
      net_error_(net::OK),
      devtools_navigation_token_(base::UnguessableToken::Create()),
      weak_factory_(this) {
  DCHECK(!browser_initiated || (entry != nullptr && frame_entry != nullptr));
  DCHECK(!IsRendererDebugURL(common_params_.url));
  TRACE_EVENT_ASYNC_BEGIN2("navigation", "NavigationRequest", this,
                           "frame_tree_node",
                           frame_tree_node_->frame_tree_node_id(), "url",
                           common_params_.url.possibly_invalid_spec());

  common_params_.referrer =
      Referrer::SanitizeForRequest(common_params_.url, common_params_.referrer);

  if (from_begin_navigation_) {
    source_site_instance_ =
        frame_tree_node->current_frame_host()->GetSiteInstance();
  } else {
    FrameNavigationEntry* frame_navigation_entry =
        entry->GetFrameEntry(frame_tree_node);
    if (frame_navigation_entry) {
      source_site_instance_ = frame_navigation_entry->source_site_instance();
      dest_site_instance_ = frame_navigation_entry->site_instance();
    }
    restore_type_ = entry->restore_type();
    is_view_source_ = entry->IsViewSourceMode();
    bindings_ = entry->bindings();
  }

  UpdateLoadFlagsWithCacheFlags(&begin_params_->load_flags,
                                common_params_.navigation_type,
                                common_params_.method == "POST");

  if (entry)
    nav_entry_id_ = entry->GetUniqueID();

  std::string user_agent_override;
  if (request_params.is_overriding_user_agent ||
      (entry && entry->GetIsOverridingUserAgent())) {
    user_agent_override =
        frame_tree_node_->navigator()->GetDelegate()->GetUserAgentOverride();
  }

  std::unique_ptr<net::HttpRequestHeaders> embedder_additional_headers;
  int additional_load_flags = 0;
  GetContentClient()->browser()->NavigationRequestStarted(
      frame_tree_node->frame_tree_node_id(), common_params_.url,
      &embedder_additional_headers, &additional_load_flags);
  begin_params_->load_flags |= additional_load_flags;

  net::HttpRequestHeaders headers;
  headers.AddHeadersFromString(begin_params_->headers);
  AddAdditionalRequestHeaders(
      &headers, std::move(embedder_additional_headers), common_params_.url,
      common_params_.navigation_type,
      frame_tree_node_->navigator()->GetController()->GetBrowserContext(),
      common_params.method, user_agent_override, frame_tree_node);

  if (begin_params_->is_form_submission) {
    if (browser_initiated && !request_params.post_content_type.empty()) {
      headers.SetHeaderIfMissing(net::HttpRequestHeaders::kContentType,
                                 request_params.post_content_type);
    } else if (!browser_initiated) {
      headers.GetHeader(net::HttpRequestHeaders::kContentType,
                        &request_params_.post_content_type);
    }
  }

  BrowserContext* browser_context =
      frame_tree_node_->navigator()->GetController()->GetBrowserContext();
  RendererPreferences render_prefs = frame_tree_node_->render_manager()
                                         ->current_host()
                                         ->GetDelegate()
                                         ->GetRendererPrefs(browser_context);
  if (render_prefs.enable_do_not_track)
    headers.SetHeader(kDoNotTrackHeader, "1");

  begin_params_->headers = headers.ToString();
}

Project: Chrome

void NavigationRequest::OnFailureChecksComplete(
    RenderFrameHostImpl* render_frame_host,
    NavigationThrottle::ThrottleCheckResult result) {
  DCHECK(result.action() != NavigationThrottle::DEFER);

  net_error_ = result.net_error_code();
  navigation_handle_->set_net_error_code(static_cast<net::Error>(net_error_));

  if (net::ERR_ABORTED == net_error_) {
    frame_tree_node_->ResetNavigationRequest(false, true);
    return;
  }

  CommitErrorPage(render_frame_host, result.error_page_content());
}

Project: Chrome

void NavigationRequest::OnRedirectChecksComplete(
    NavigationThrottle::ThrottleCheckResult result) {
  DCHECK(result.action() != NavigationThrottle::DEFER);
  DCHECK(result.action() != NavigationThrottle::BLOCK_RESPONSE);

  if (result.action() == NavigationThrottle::CANCEL_AND_IGNORE ||
      result.action() == NavigationThrottle::CANCEL) {
    DCHECK(result.action() == NavigationThrottle::CANCEL ||
           result.net_error_code() == net::ERR_ABORTED);
    OnRequestFailedInternal(false, result.net_error_code(), base::nullopt, true,
                            result.error_page_content());

    return;
  }

  if (result.action() == NavigationThrottle::BLOCK_REQUEST ||
      result.action() == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE) {
    DCHECK(result.net_error_code() == net::ERR_BLOCKED_BY_CLIENT ||
           result.net_error_code() == net::ERR_BLOCKED_BY_ADMINISTRATOR);
    OnRequestFailedInternal(false, result.net_error_code(), base::nullopt, true,
                            result.error_page_content());
    return;
  }

  RenderFrameDevToolsAgentHost::OnNavigationRequestWillBeSent(*this);

  loader_->FollowRedirect();
}

Project: Chrome

void NavigationRequest::OnRequestFailed(
    bool has_stale_copy_in_cache,
    int net_error,
    const base::Optional<net::SSLInfo>& ssl_info) {
  RenderFrameDevToolsAgentHost::OnNavigationRequestFailed(*this, net_error);

  NavigationRequest::OnRequestFailedInternal(has_stale_copy_in_cache, net_error,
                                             ssl_info, false, base::nullopt);
}

Project: Chrome

void NavigationRequest::OnRequestFailedInternal(
    bool has_stale_copy_in_cache,
    int net_error,
    const base::Optional<net::SSLInfo>& ssl_info,
    bool skip_throttles,
    const base::Optional<std::string>& error_page_content) {
  DCHECK(state_ == STARTED || state_ == RESPONSE_STARTED);
  DCHECK(!(net_error == net::ERR_ABORTED && error_page_content.has_value()));

  TRACE_EVENT_ASYNC_STEP_INTO1("navigation", "NavigationRequest", this,
                               "OnRequestFailed", "error", net_error);
  state_ = FAILED;
  if (navigation_handle_.get())
    navigation_handle_->set_net_error_code(static_cast<net::Error>(net_error));

  int expected_pending_entry_id = nav_entry_id_;
  bool is_download = false;
  if (navigation_handle_.get()) {
    expected_pending_entry_id = navigation_handle_->pending_nav_entry_id();
    is_download = navigation_handle_->IsDownload();
  }

  frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded(
      expected_pending_entry_id, is_download);

  if (net_error == net::ERR_ABORTED) {
    frame_tree_node_->ResetNavigationRequest(false, true);
    return;
  }

  RenderFrameHostImpl* render_frame_host = nullptr;
  if (net_error == net::ERR_BLOCKED_BY_CLIENT && !browser_initiated()) {
    render_frame_host = frame_tree_node_->current_frame_host();
  } else {
    render_frame_host =
        frame_tree_node_->render_manager()->GetFrameHostForNavigation(*this);
  }
  DCHECK(render_frame_host);

  DCHECK(render_frame_host->CanCommitURL(common_params_.url));

  NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL(render_frame_host,
                                                           common_params_.url);

  has_stale_copy_in_cache_ = has_stale_copy_in_cache;
  net_error_ = net_error;

  if (skip_throttles) {
    CommitErrorPage(render_frame_host, error_page_content);
  } else {
    navigation_handle_->WillFailRequest(
        ssl_info, base::Bind(&NavigationRequest::OnFailureChecksComplete,
                             base::Unretained(this), render_frame_host));
  }
}

Project: Chrome

void NavigationRequest::OnRequestRedirected(
    const net::RedirectInfo& redirect_info,
    const scoped_refptr<network::ResourceResponse>& response) {
#if defined(OS_ANDROID)
  base::WeakPtr<NavigationRequest> this_ptr(weak_factory_.GetWeakPtr());

  bool should_override_url_loading = false;
  if (!GetContentClient()->browser()->ShouldOverrideUrlLoading(
          frame_tree_node_->frame_tree_node_id(), browser_initiated_,
          redirect_info.new_url, redirect_info.new_method,
          false, true, frame_tree_node_->IsMainFrame(),
          common_params_.transition, &should_override_url_loading)) {
    return;
  }

  if (!this_ptr)
    return;

  if (should_override_url_loading) {
    bool is_external_protocol =
        !GetContentClient()->browser()->IsHandledURL(common_params_.url);
    navigation_handle_->set_net_error_code(net::ERR_ABORTED);
    navigation_handle_->UpdateStateFollowingRedirect(
        redirect_info.new_url, redirect_info.new_method,
        GURL(redirect_info.new_referrer), is_external_protocol,
        response->head.headers, response->head.connection_info,
        base::Bind(&NavigationRequest::OnRedirectChecksComplete,
                   base::Unretained(this)));
    frame_tree_node_->ResetNavigationRequest(false, true);
    return;
  }
#endif

  if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRedirectToURL(
          redirect_info.new_url)) {
    DVLOG(1) << "Denied redirect for "
             << redirect_info.new_url.possibly_invalid_spec();
    navigation_handle_->set_net_error_code(net::ERR_ABORTED);
    frame_tree_node_->ResetNavigationRequest(false, true);
    return;
  }

  if (!browser_initiated_ && source_site_instance() &&
      !ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL(
          source_site_instance()->GetProcess()->GetID(),
          redirect_info.new_url)) {
    DVLOG(1) << "Denied unauthorized redirect for "
             << redirect_info.new_url.possibly_invalid_spec();
    navigation_handle_->set_net_error_code(net::ERR_ABORTED);
    frame_tree_node_->ResetNavigationRequest(false, true);
    return;
  }

  dest_site_instance_ = nullptr;

  if (redirect_info.new_method != "POST")
    common_params_.post_data = nullptr;

  if (request_params_.navigation_timing.redirect_start.is_null()) {
    request_params_.navigation_timing.redirect_start =
        request_params_.navigation_timing.fetch_start;
  }
  request_params_.navigation_timing.redirect_end = base::TimeTicks::Now();
  request_params_.navigation_timing.fetch_start = base::TimeTicks::Now();

  request_params_.redirect_response.push_back(response->head);
  request_params_.redirect_infos.push_back(redirect_info);

  request_params_.redirects.push_back(common_params_.url);
  common_params_.url = redirect_info.new_url;
  common_params_.method = redirect_info.new_method;
  common_params_.referrer.url = GURL(redirect_info.new_referrer);
  common_params_.referrer =
      Referrer::SanitizeForRequest(common_params_.url, common_params_.referrer);

  if (CheckContentSecurityPolicyFrameSrc(true /* is redirect */) ==
      CONTENT_SECURITY_POLICY_CHECK_FAILED) {
    OnRequestFailed(false, net::ERR_BLOCKED_BY_CLIENT, base::nullopt);

    return;
  }

  if (CheckCredentialedSubresource() ==
          CredentialedSubresourceCheckResult::BLOCK_REQUEST ||
      CheckLegacyProtocolInSubresource() ==
          LegacyProtocolInSubresourceCheckResult::BLOCK_REQUEST) {
    OnRequestFailed(false, net::ERR_ABORTED, base::nullopt);

    return;
  }

  scoped_refptr<SiteInstance> site_instance =
      frame_tree_node_->render_manager()->GetSiteInstanceForNavigationRequest(
          *this);
  speculative_site_instance_ =
      site_instance->HasProcess() ? site_instance : nullptr;

  if (!site_instance->HasProcess()) {
    RenderProcessHostImpl::NotifySpareManagerAboutRecentlyUsedBrowserContext(
        site_instance->GetBrowserContext());
  }

  RenderProcessHost* expected_process =
      site_instance->HasProcess() ? site_instance->GetProcess() : nullptr;

  bool is_external_protocol =
      !GetContentClient()->browser()->IsHandledURL(common_params_.url);
  navigation_handle_->WillRedirectRequest(
      common_params_.url, common_params_.method, common_params_.referrer.url,
      is_external_protocol, response->head.headers,
      response->head.connection_info, expected_process,
      base::Bind(&NavigationRequest::OnRedirectChecksComplete,
                 base::Unretained(this)));
}

Project: Chrome

void NavigationRequest::OnResponseStarted(
    const scoped_refptr<network::ResourceResponse>& response,
    network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
    std::unique_ptr<NavigationData> navigation_data,
    const GlobalRequestID& request_id,
    bool is_download,
    bool is_stream,
    base::Optional<SubresourceLoaderParams> subresource_loader_params) {
  DCHECK(state_ == STARTED);
  DCHECK(response);
  TRACE_EVENT_ASYNC_STEP_INTO0("navigation", "NavigationRequest", this,
                               "OnResponseStarted");
  state_ = RESPONSE_STARTED;

  response_should_be_rendered_ =
      !is_download && (!response->head.headers.get() ||
                       (response->head.headers->response_code() != 204 &&
                        response->head.headers->response_code() != 205));

  if (!response_should_be_rendered_) {
    navigation_handle_->set_net_error_code(net::ERR_ABORTED);
    net_error_ = net::ERR_ABORTED;
  }

  request_params_.service_worker_provider_id =
      navigation_handle_->service_worker_handle()
          ? navigation_handle_->service_worker_handle()
                ->service_worker_provider_host_id()
          : kInvalidServiceWorkerProviderId;
  request_params_.appcache_host_id =
      navigation_handle_->appcache_handle()
          ? navigation_handle_->appcache_handle()->appcache_host_id()
          : kAppCacheNoHostId;

  request_params_.was_activated = false;
  if (navigation_handle_->IsRendererInitiated() &&
      frame_tree_node_->has_received_user_gesture() &&
      ShouldPropagateUserActivation(
          frame_tree_node_->current_origin(),
          url::Origin::Create(navigation_handle_->GetURL()))) {
    request_params_.was_activated = true;
  } else if (((navigation_handle_->HasUserGesture() &&
               navigation_handle_->IsRendererInitiated()) ||
              navigation_handle_->WasStartedFromContextMenu()) &&
             ShouldPropagateUserActivation(
                 url::Origin::Create(navigation_handle_->GetReferrer().url),
                 url::Origin::Create(navigation_handle_->GetURL()))) {
    request_params_.was_activated = true;
  }

  common_params_.previews_state =
      static_cast<PreviewsState>(response->head.previews_state);

  RenderFrameHostImpl* render_frame_host = nullptr;
  if (response_should_be_rendered_) {
    render_frame_host =
        frame_tree_node_->render_manager()->GetFrameHostForNavigation(*this);
    NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL(
        render_frame_host, common_params_.url);
  }
  DCHECK(render_frame_host || !response_should_be_rendered_);

  if (!browser_initiated_ && render_frame_host &&
      render_frame_host != frame_tree_node_->current_frame_host()) {
    common_params_.source_location.reset();

    if (!frame_tree_node_->navigator()->GetDelegate()->ShouldTransferNavigation(
            frame_tree_node_->IsMainFrame())) {
      navigation_handle_->set_net_error_code(net::ERR_ABORTED);
      frame_tree_node_->ResetNavigationRequest(false, true);
      return;
    }
  }

  if (navigation_data)
    navigation_handle_->set_navigation_data(std::move(navigation_data));

  response_ = response;
  url_loader_client_endpoints_ = std::move(url_loader_client_endpoints);
  ssl_info_ = response->head.ssl_info.has_value() ? *response->head.ssl_info
                                                  : net::SSLInfo();
  is_download_ = is_download;

  subresource_loader_params_ = std::move(subresource_loader_params);

  if (render_frame_host &&
      SiteInstanceImpl::ShouldAssignSiteForURL(common_params_.url)) {
    render_frame_host->GetProcess()->SetIsUsed();

    SiteInstanceImpl* instance = render_frame_host->GetSiteInstance();
    if (!instance->HasSite() &&
        SiteInstanceImpl::DoesSiteRequireDedicatedProcess(
            instance->GetBrowserContext(), common_params_.url)) {
      instance->SetSite(common_params_.url);
    }
  }

  RenderFrameDevToolsAgentHost::OnNavigationResponseReceived(*this, *response);

  if (is_download && (response->head.headers.get() &&
                      (response->head.headers->response_code() / 100 != 2))) {
    navigation_handle_->set_net_error_code(net::ERR_INVALID_RESPONSE);
    frame_tree_node_->ResetNavigationRequest(false, true);
    return;
  }

  navigation_handle_->WillProcessResponse(
      render_frame_host, response->head.headers.get(),
      response->head.connection_info, response->head.socket_address, ssl_info_,
      request_id, common_params_.should_replace_current_entry, is_download,
      is_stream,
      base::Bind(&NavigationRequest::OnWillProcessResponseChecksComplete,
                 base::Unretained(this)));
}

Project: Chrome

void NavigationRequest::OnWillProcessResponseChecksComplete(
    NavigationThrottle::ThrottleCheckResult result) {
  DCHECK(result.action() != NavigationThrottle::DEFER);

  if (result.action() == NavigationThrottle::PROCEED) {
    if (is_download_ &&
        base::FeatureList::IsEnabled(network::features::kNetworkService)) {
      auto resource_request = std::make_unique<network::ResourceRequest>();
      resource_request->url = common_params_.url;
      resource_request->method = common_params_.method;
      resource_request->request_initiator = begin_params_->initiator_origin;
      resource_request->referrer = common_params_.referrer.url;

      BrowserContext* browser_context =
          frame_tree_node_->navigator()->GetController()->GetBrowserContext();
      DownloadManagerImpl* download_manager = static_cast<DownloadManagerImpl*>(
          BrowserContext::GetDownloadManager(browser_context));
      download_manager->InterceptNavigation(
          std::move(resource_request), navigation_handle_->GetRedirectChain(),
          common_params_.suggested_filename, response_,
          std::move(url_loader_client_endpoints_), ssl_info_.cert_status,
          frame_tree_node_->frame_tree_node_id());

      OnRequestFailed(false, net::ERR_ABORTED, base::nullopt);
      return;
    }

    if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
      if (url_loader_client_endpoints_) {
        network::mojom::URLLoaderPtr url_loader(
            std::move(url_loader_client_endpoints_->url_loader));
        url_loader->ProceedWithResponse();
        url_loader_client_endpoints_->url_loader = url_loader.PassInterface();
      } else {
        loader_->ProceedWithResponse();
      }
    }
  }

  if (result.action() == NavigationThrottle::CANCEL_AND_IGNORE ||
      result.action() == NavigationThrottle::CANCEL ||
      !response_should_be_rendered_) {
    if (!response_should_be_rendered_) {
      OnRequestFailedInternal(false, net::ERR_ABORTED, base::nullopt, true,
                              base::nullopt);
      return;
    }

    DCHECK(result.action() == NavigationThrottle::CANCEL ||
           result.net_error_code() == net::ERR_ABORTED);
    OnRequestFailedInternal(false, result.net_error_code(), base::nullopt, true,
                            result.error_page_content());

    return;
  }

  if (result.action() == NavigationThrottle::BLOCK_RESPONSE) {
    DCHECK_EQ(net::ERR_BLOCKED_BY_RESPONSE, result.net_error_code());
    OnRequestFailedInternal(false, result.net_error_code(), base::nullopt, true,
                            result.error_page_content());
    return;
  }

  CommitNavigation();

}

Project: Chrome

void NavigationRequest::ResetForCrossDocumentRestart() {
  DCHECK(
      FrameMsg_Navigate_Type::IsSameDocument(common_params_.navigation_type));

  navigation_handle_.reset();

  if (common_params_.navigation_type ==
      FrameMsg_Navigate_Type::HISTORY_SAME_DOCUMENT) {
    common_params_.navigation_type =
        FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT;
  } else {
    DCHECK(common_params_.navigation_type ==
           FrameMsg_Navigate_Type::SAME_DOCUMENT);
    common_params_.navigation_type = FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
  }

  state_ = NOT_STARTED;
}

Project: Chrome

NavigationRequest::~NavigationRequest() {
  TRACE_EVENT_ASYNC_END0("navigation", "NavigationRequest", this);
  if (state_ == STARTED) {
    RenderFrameDevToolsAgentHost::OnNavigationRequestFailed(*this,
                                                            net::ERR_ABORTED);
  }
}