Commit message: None
CVE: CVE-2016-1670
CWE: CWE-362
Vulnerability description: Race condition in the ResourceDispatcherHostImpl::BeginRequest function in content/browser/loader/resource_dispatcher_host_impl.cc in Google Chrome before 50.0.2661.102 allows remote attackers to make arbitrary HTTP requests by leveraging access to a renderer process and reusing a request ID.

Project: Chrome

void AbortRequestBeforeItStarts(ResourceMessageFilter* filter,
                                IPC::Message* sync_result,
                                int request_id) {
  if (sync_result) {
    SyncLoadResult result;
    result.error_code = net::ERR_ABORTED;
    ResourceHostMsg_SyncLoad::WriteReplyParams(sync_result, result);
    filter->Send(sync_result);
  } else {
    ResourceMsg_RequestCompleteData request_complete_data;
    request_complete_data.error_code = net::ERR_ABORTED;
    request_complete_data.was_ignored_by_handler = false;
    request_complete_data.exists_in_cache = false;
    request_complete_data.completion_time = base::TimeTicks();
    request_complete_data.encoded_data_length = 0;
    filter->Send(new ResourceMsg_RequestComplete(
        request_id, request_complete_data));
  }
}

Project: Chrome

void ResourceDispatcherHostImpl::AddResourceContext(ResourceContext* context) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  active_resource_contexts_.insert(context);
}

Project: Chrome

scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::AddStandardHandlers(
    net::URLRequest* request,
    ResourceType resource_type,
    ResourceContext* resource_context,
    AppCacheService* appcache_service,
    int child_id,
    int route_id,
    scoped_ptr<ResourceHandler> handler) {
  if (IsBrowserSideNavigationEnabled() && IsResourceTypeFrame(resource_type) &&
      child_id != -1) {
    DCHECK(request->url().SchemeIs(url::kBlobScheme));
    return handler;
  }

  PluginService* plugin_service = nullptr;
#if defined(ENABLE_PLUGINS)
  plugin_service = PluginService::GetInstance();
#endif
  handler.reset(new MimeTypeResourceHandler(std::move(handler), this,
                                            plugin_service, request));

  ScopedVector<ResourceThrottle> throttles;

  if (!IsBrowserSideNavigationEnabled() && IsResourceTypeFrame(resource_type))
    throttles.push_back(new NavigationResourceThrottle(request));

  if (delegate_) {
    delegate_->RequestBeginning(request,
                                resource_context,
                                appcache_service,
                                resource_type,
                                &throttles);
  }

  if (request->has_upload()) {
    throttles.push_back(
        new PowerSaveBlockResourceThrottle(request->url().host()));
  }

  ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request);
  throttles.push_back(scheduler_->ScheduleRequest(child_id, route_id,
                                                  info->IsAsync(), request));

  handler.reset(new ThrottlingResourceHandler(std::move(handler), request,
                                              std::move(throttles)));

  return handler;
}

Project: Chrome

void AttachRequestBodyBlobDataHandles(
    ResourceRequestBody* body,
    storage::BlobStorageContext* blob_context) {
  DCHECK(blob_context);
  for (size_t i = 0; i < body->elements()->size(); ++i) {
    const ResourceRequestBody::Element& element = (*body->elements())[i];
    if (element.type() != ResourceRequestBody::Element::TYPE_BLOB)
      continue;
    scoped_ptr<storage::BlobDataHandle> handle =
        blob_context->GetBlobDataFromUUID(element.blob_uuid());
    DCHECK(handle);
    if (!handle)
      continue;
    const void* key = handle.get();
    body->SetUserData(key, handle.release());
  }
}

Project: Chrome

DownloadInterruptReason ResourceDispatcherHostImpl::BeginDownload(
    scoped_ptr<net::URLRequest> request,
    const Referrer& referrer,
    bool is_content_initiated,
    ResourceContext* context,
    int child_id,
    int render_view_route_id,
    int render_frame_route_id,
    bool prefer_cache,
    bool do_not_prompt_for_login,
    scoped_ptr<DownloadSaveInfo> save_info,
    uint32_t download_id,
    const DownloadStartedCallback& started_callback) {
  if (is_shutdown_)
    return CallbackAndReturn(started_callback,
                             DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN);

  const GURL& url = request->original_url();

  char url_buf[128];
  base::strlcpy(url_buf, url.spec().c_str(), arraysize(url_buf));
  base::debug::Alias(url_buf);
  CHECK(ContainsKey(active_resource_contexts_, context));

  SetReferrerForRequest(request.get(), referrer);

  int extra_load_flags = net::LOAD_NORMAL;
  if (prefer_cache) {
    if (request->get_upload() != NULL)
      extra_load_flags |= net::LOAD_ONLY_FROM_CACHE;
    else
      extra_load_flags |= net::LOAD_PREFERRING_CACHE;
  } else {
    extra_load_flags |= net::LOAD_DISABLE_CACHE;
  }
  request->SetLoadFlags(request->load_flags() | extra_load_flags);

  request->set_first_party_url_policy(
      net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT);

  if (!ChildProcessSecurityPolicyImpl::GetInstance()->
          CanRequestURL(child_id, url)) {
    VLOG(1) << "Denied unauthorized download request for "
            << url.possibly_invalid_spec();
    return CallbackAndReturn(started_callback,
                             DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST);
  }

  request_id_--;

  const net::URLRequestContext* request_context = context->GetRequestContext();
  if (!request_context->job_factory()->IsHandledURL(url)) {
    VLOG(1) << "Download request for unsupported protocol: "
            << url.possibly_invalid_spec();
    return CallbackAndReturn(started_callback,
                             DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST);
  }

  ResourceRequestInfoImpl* extra_info =
      CreateRequestInfo(child_id, render_view_route_id,
                        render_frame_route_id, true, context);
  extra_info->set_do_not_prompt_for_login(do_not_prompt_for_login);
  extra_info->AssociateWithRequest(request.get());  // Request takes ownership.

  if (request->url().SchemeIs(url::kBlobScheme)) {
    ChromeBlobStorageContext* blob_context =
        GetChromeBlobStorageContextForResourceContext(context);
    storage::BlobProtocolHandler::SetRequestedBlobDataHandle(
        request.get(),
        blob_context->context()->GetBlobDataFromPublicURL(request->url()));
  }

  scoped_ptr<ResourceHandler> handler(CreateResourceHandlerForDownload(
      request.get(), is_content_initiated, true, download_id,
      std::move(save_info), started_callback));

  BeginRequestInternal(std::move(request), std::move(handler));

  return DOWNLOAD_INTERRUPT_REASON_NONE;
}

Project: Chrome

void ResourceDispatcherHostImpl::BeginNavigationRequest(
    ResourceContext* resource_context,
    const NavigationRequestInfo& info,
    NavigationURLLoaderImplCore* loader,
    ServiceWorkerNavigationHandleCore* service_worker_handle_core) {
  CHECK(IsBrowserSideNavigationEnabled());

  ResourceType resource_type = info.is_main_frame ?
      RESOURCE_TYPE_MAIN_FRAME : RESOURCE_TYPE_SUB_FRAME;

  if (is_shutdown_ ||
      (delegate_ && !delegate_->ShouldBeginRequest(
          info.begin_params.method,
          info.common_params.url,
          resource_type,
          resource_context))) {
    loader->NotifyRequestFailed(false, net::ERR_ABORTED);
    return;
  }

  char url_buf[128];
  base::strlcpy(
      url_buf, info.common_params.url.spec().c_str(), arraysize(url_buf));
  base::debug::Alias(url_buf);
  CHECK(ContainsKey(active_resource_contexts_, resource_context));

  const net::URLRequestContext* request_context =
      resource_context->GetRequestContext();

  int load_flags = info.begin_params.load_flags;
  load_flags |= net::LOAD_VERIFY_EV_CERT;
  if (info.is_main_frame)
    load_flags |= net::LOAD_MAIN_FRAME;


  DCHECK(!(load_flags & net::LOAD_IGNORE_LIMITS));

  scoped_ptr<net::URLRequest> new_request;
  new_request = request_context->CreateRequest(
      info.common_params.url, net::HIGHEST, nullptr);

  new_request->set_method(info.begin_params.method);
  new_request->set_first_party_for_cookies(
      info.first_party_for_cookies);
  new_request->set_initiator(info.request_initiator);
  if (info.is_main_frame) {
    new_request->set_first_party_url_policy(
        net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT);
  }

  SetReferrerForRequest(new_request.get(), info.common_params.referrer);

  net::HttpRequestHeaders headers;
  headers.AddHeadersFromString(info.begin_params.headers);
  new_request->SetExtraRequestHeaders(headers);

  new_request->SetLoadFlags(load_flags);

  storage::BlobStorageContext* blob_context = GetBlobStorageContext(
      GetChromeBlobStorageContextForResourceContext(resource_context));

  if (info.request_body.get()) {
    AttachRequestBodyBlobDataHandles(
        info.request_body.get(),
        blob_context);
    new_request->set_upload(UploadDataStreamBuilder::Build(
        info.request_body.get(),
        blob_context,
        nullptr,  // file_system_context
        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)
            .get()));
  }

  request_id_--;

  ResourceRequestInfoImpl* extra_info = new ResourceRequestInfoImpl(
      PROCESS_TYPE_BROWSER,
      -1,  // child_id
      -1,  // route_id
      info.frame_tree_node_id,
      -1,  // request_data.origin_pid,
      request_id_,
      -1,  // request_data.render_frame_id,
      info.is_main_frame, info.parent_is_main_frame, resource_type,
      info.common_params.transition,
      false,
      false,  // is download
      false,  // is stream
      info.common_params.allow_download, info.begin_params.has_user_gesture,
      true,   // enable_load_timing
      false,  // enable_upload_progress
      false,  // do_not_prompt_for_login
      info.common_params.referrer.policy,
      blink::WebPageVisibilityStateVisible, resource_context,
      base::WeakPtr<ResourceMessageFilter>(),  // filter
      false,  // request_data.report_raw_headers
      true,   // is_async
      IsUsingLoFi(info.common_params.lofi_state, delegate_, *new_request,
                  resource_context, info.is_main_frame),
      std::string());  // original_headers
  extra_info->AssociateWithRequest(new_request.get());

  if (new_request->url().SchemeIs(url::kBlobScheme)) {
    storage::BlobProtocolHandler::SetRequestedBlobDataHandle(
        new_request.get(),
        blob_context->GetBlobDataFromPublicURL(new_request->url()));
  }

  RequestContextFrameType frame_type =
      info.is_main_frame ? REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL
                         : REQUEST_CONTEXT_FRAME_TYPE_NESTED;
  ServiceWorkerRequestHandler::InitializeForNavigation(
      new_request.get(), service_worker_handle_core, blob_context,
      info.begin_params.skip_service_worker, resource_type,
      info.begin_params.request_context_type, frame_type, info.request_body);


  scoped_ptr<ResourceHandler> handler(new NavigationResourceHandler(
      new_request.get(), loader));

  handler =
      AddStandardHandlers(new_request.get(), resource_type, resource_context,
                          nullptr,  // appcache_service
                          -1,       // child_id
                          -1,       // route_id
                          std::move(handler));

  BeginRequestInternal(std::move(new_request), std::move(handler));
}

Project: Chrome

void ResourceDispatcherHostImpl::BeginRequestInternal(
    scoped_ptr<net::URLRequest> request,
    scoped_ptr<ResourceHandler> handler) {
  DCHECK(!request->is_pending());
  ResourceRequestInfoImpl* info =
      ResourceRequestInfoImpl::ForRequest(request.get());

  if ((TimeTicks::Now() - last_user_gesture_time_) <
      TimeDelta::FromMilliseconds(kUserGestureWindowMs)) {
    request->SetLoadFlags(
        request->load_flags() | net::LOAD_MAYBE_USER_GESTURE);
  }

  info->set_memory_cost(CalculateApproximateMemoryCost(request.get()));

  OustandingRequestsStats stats = IncrementOutstandingRequestsMemory(1, *info);
  if (stats.memory_cost > max_outstanding_requests_cost_per_process_) {
    request->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES);

    bool defer = false;
    handler->OnResponseCompleted(request->status(), std::string(), &defer);
    if (defer) {
      NOTREACHED();
    }

    IncrementOutstandingRequestsMemory(-1, *info);

    handler.reset();
    return;
  }

  scoped_ptr<ResourceLoader> loader(
      new ResourceLoader(std::move(request), std::move(handler), this));

  GlobalRoutingID id(info->GetGlobalRoutingID());
  BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(id);
  if (iter != blocked_loaders_map_.end()) {
    iter->second->push_back(std::move(loader));
    return;
  }

  StartLoading(info, std::move(loader));
}

Project: Chrome

void ResourceDispatcherHostImpl::BlockRequestsForRoute(int child_id,
                                                       int route_id) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  GlobalRoutingID key(child_id, route_id);
  DCHECK(blocked_loaders_map_.find(key) == blocked_loaders_map_.end()) <<
      "BlockRequestsForRoute called  multiple time for the same RVH";
  blocked_loaders_map_[key] = make_scoped_ptr(new BlockedLoadersList());
}

Project: Chrome

DownloadInterruptReason CallbackAndReturn(
    const DownloadUrlParameters::OnStartedCallback& started_cb,
    DownloadInterruptReason interrupt_reason) {
  if (started_cb.is_null())
    return interrupt_reason;
  BrowserThread::PostTask(
      BrowserThread::UI,
      FROM_HERE,
      base::Bind(
          started_cb, static_cast<DownloadItem*>(NULL), interrupt_reason));

  return interrupt_reason;
}

Project: Chrome

void ResourceDispatcherHostImpl::CancelRequest(int child_id,
                                               int request_id) {
  ResourceLoader* loader = GetLoader(child_id, request_id);
  if (!loader) {
    DVLOG(1) << "Canceling a request that wasn't found";
    return;
  }

  RemovePendingRequest(child_id, request_id);
}

Project: Chrome

void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id,
                                                        int route_id) {

  bool any_requests_transferring = false;
  std::vector<GlobalRequestID> matching_requests;
  for (const auto& loader : pending_loaders_) {
    if (loader.first.child_id != child_id)
      continue;

    ResourceRequestInfoImpl* info = loader.second->GetRequestInfo();

    GlobalRequestID id(child_id, loader.first.request_id);
    DCHECK(id == loader.first);
    if (IsTransferredNavigation(id))
      any_requests_transferring = true;
    if (info->detachable_handler()) {
      info->detachable_handler()->Detach();
    } else if (!info->IsDownload() && !info->is_stream() &&
               !IsTransferredNavigation(id) &&
               (route_id == -1 || route_id == info->GetRouteID())) {
      matching_requests.push_back(id);
    }
  }

  for (size_t i = 0; i < matching_requests.size(); ++i) {
    LoaderMap::iterator iter = pending_loaders_.find(matching_requests[i]);
    if (iter != pending_loaders_.end())
      RemovePendingLoader(iter);
  }

  if (any_requests_transferring)
    return;

  if (route_id != -1) {
    if (blocked_loaders_map_.find(GlobalRoutingID(child_id, route_id)) !=
        blocked_loaders_map_.end()) {
      CancelBlockedRequestsForRoute(child_id, route_id);
    }
  } else {
    std::set<int> route_ids;
    for (const auto& blocked_loaders : blocked_loaders_map_) {
      if (blocked_loaders.first.child_id == child_id)
        route_ids.insert(blocked_loaders.first.route_id);
    }
    for (int route_id : route_ids) {
      CancelBlockedRequestsForRoute(child_id, route_id);
    }
  }
}

Project: Chrome

void ResourceDispatcherHostImpl::CancelTransferringNavigation(
    const GlobalRequestID& id) {
  DCHECK(IsTransferredNavigation(id));
  RemovePendingRequest(id.child_id, id.request_id);
}

Project: Chrome

ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
    int child_id,
    int render_view_route_id,
    int render_frame_route_id,
    bool download,
    ResourceContext* context) {
  return new ResourceRequestInfoImpl(
      PROCESS_TYPE_RENDERER,
      child_id,
      render_view_route_id,
      -1,  // frame_tree_node_id
      0,
      request_id_,
      render_frame_route_id,
      false,             // is_main_frame
      false,             // parent_is_main_frame
      RESOURCE_TYPE_SUB_RESOURCE,
      ui::PAGE_TRANSITION_LINK,
      false,     // should_replace_current_entry
      download,  // is_download
      false,     // is_stream
      download,  // allow_download
      false,     // has_user_gesture
      false,     // enable_load_timing
      false,     // enable_upload_progress
      false,     // do_not_prompt_for_login
      blink::WebReferrerPolicyDefault,
      blink::WebPageVisibilityStateVisible,
      context,
      base::WeakPtr<ResourceMessageFilter>(),  // filter
      false,                                   // report_raw_headers
      true,                                    // is_async
      false,                                   // is_using_lofi
      std::string());                          // original_headers
}

Project: Chrome

scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::CreateResourceHandler(
    net::URLRequest* request,
    const ResourceHostMsg_Request& request_data,
    IPC::Message* sync_result,
    int route_id,
    int process_type,
    int child_id,
    ResourceContext* resource_context) {
  tracked_objects::ScopedTracker tracking_profile(
      FROM_HERE_WITH_EXPLICIT_FUNCTION(
          "456331 ResourceDispatcherHostImpl::CreateResourceHandler"));
  scoped_ptr<ResourceHandler> handler;
  if (sync_result) {
    if (request_data.download_to_file) {
      bad_message::ReceivedBadMessage(filter_, bad_message::RDH_BAD_DOWNLOAD);
      return scoped_ptr<ResourceHandler>();
    }

    handler.reset(new SyncResourceHandler(request, sync_result, this));
  } else {
    handler.reset(new AsyncResourceHandler(request, this));

    if (request_data.download_to_file) {
      handler.reset(
          new RedirectToFileResourceHandler(std::move(handler), request));
    }
  }

  if (!sync_result && IsDetachableResourceType(request_data.resource_type)) {
    handler.reset(new DetachableResourceHandler(
        request,
        base::TimeDelta::FromMilliseconds(kDefaultDetachableCancelDelayMs),
        std::move(handler)));
  }

  if (!IsBrowserSideNavigationEnabled()) {
    bool is_swappable_navigation =
        request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME;
    if (!is_swappable_navigation &&
        SiteIsolationPolicy::AreCrossProcessFramesPossible()) {
      is_swappable_navigation =
          request_data.resource_type == RESOURCE_TYPE_SUB_FRAME;
    }
    if (is_swappable_navigation && process_type == PROCESS_TYPE_RENDERER)
      handler.reset(new CrossSiteResourceHandler(std::move(handler), request));
  }

  return AddStandardHandlers(request, request_data.resource_type,
                             resource_context, filter_->appcache_service(),
                             child_id, route_id, std::move(handler));
}

Project: Chrome

void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) {
  ResourceRequestInfoImpl* info = loader->GetRequestInfo();

  if (info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME) {
    UMA_HISTOGRAM_SPARSE_SLOWLY(
        "Net.ErrorCodesForMainFrame3",
        -loader->request()->status().error());

    base::TimeDelta request_loading_time(
        base::TimeTicks::Now() - loader->request()->creation_time());
    switch (loader->request()->status().error()) {
      case net::OK:
        UMA_HISTOGRAM_LONG_TIMES(
            "Net.RequestTime2.Success", request_loading_time);
        break;
      case net::ERR_ABORTED:
        UMA_HISTOGRAM_CUSTOM_COUNTS("Net.ErrAborted.SentBytes",
                                    loader->request()->GetTotalSentBytes(), 1,
                                    50000000, 50);
        UMA_HISTOGRAM_CUSTOM_COUNTS("Net.ErrAborted.ReceivedBytes",
                                    loader->request()->GetTotalReceivedBytes(),
                                    1, 50000000, 50);
        UMA_HISTOGRAM_LONG_TIMES(
            "Net.RequestTime2.ErrAborted", request_loading_time);

        if (loader->request()->url().SchemeIsHTTPOrHTTPS()) {
          UMA_HISTOGRAM_LONG_TIMES("Net.RequestTime2.ErrAborted.HttpScheme",
                                   request_loading_time);
        } else {
          UMA_HISTOGRAM_LONG_TIMES("Net.RequestTime2.ErrAborted.NonHttpScheme",
                                   request_loading_time);
        }

        if (loader->request()->GetTotalReceivedBytes() > 0) {
          UMA_HISTOGRAM_LONG_TIMES("Net.RequestTime2.ErrAborted.NetworkContent",
                                   request_loading_time);
        } else if (loader->request()->received_response_content_length() > 0) {
          UMA_HISTOGRAM_LONG_TIMES(
              "Net.RequestTime2.ErrAborted.NoNetworkContent.CachedContent",
              request_loading_time);
        } else {
          UMA_HISTOGRAM_LONG_TIMES(
              "Net.RequestTime2.ErrAborted.NoBytesRead",
              request_loading_time);
        }

        BrowserThread::PostTask(
            BrowserThread::UI, FROM_HERE,
            base::Bind(&RecordAbortRapporOnUI, loader->request()->url(),
                       request_loading_time));
        break;
      case net::ERR_CONNECTION_RESET:
        UMA_HISTOGRAM_LONG_TIMES(
            "Net.RequestTime2.ErrConnectionReset", request_loading_time);
        break;
      case net::ERR_CONNECTION_TIMED_OUT:
        UMA_HISTOGRAM_LONG_TIMES(
            "Net.RequestTime2.ErrConnectionTimedOut", request_loading_time);
        break;
      case net::ERR_INTERNET_DISCONNECTED:
        UMA_HISTOGRAM_LONG_TIMES(
            "Net.RequestTime2.ErrInternetDisconnected", request_loading_time);
        break;
      case net::ERR_NAME_NOT_RESOLVED:
        UMA_HISTOGRAM_LONG_TIMES(
            "Net.RequestTime2.ErrNameNotResolved", request_loading_time);
        break;
      case net::ERR_TIMED_OUT:
        UMA_HISTOGRAM_LONG_TIMES(
            "Net.RequestTime2.ErrTimedOut", request_loading_time);
        break;
      default:
        UMA_HISTOGRAM_LONG_TIMES(
            "Net.RequestTime2.MiscError", request_loading_time);
        break;
    }

    if (loader->request()->url().SchemeIsCryptographic()) {
      if (loader->request()->url().host() == "www.google.com") {
        UMA_HISTOGRAM_SPARSE_SLOWLY("Net.ErrorCodesForHTTPSGoogleMainFrame2",
                                    -loader->request()->status().error());
      }

      int num_valid_scts = std::count_if(
          loader->request()->ssl_info().signed_certificate_timestamps.begin(),
          loader->request()->ssl_info().signed_certificate_timestamps.end(),
          IsValidatedSCT);
      UMA_HISTOGRAM_COUNTS_100(
          "Net.CertificateTransparency.MainFrameValidSCTCount", num_valid_scts);
    }
  } else {
    if (info->GetResourceType() == RESOURCE_TYPE_IMAGE) {
      UMA_HISTOGRAM_SPARSE_SLOWLY(
          "Net.ErrorCodesForImages",
          -loader->request()->status().error());
    }
    UMA_HISTOGRAM_SPARSE_SLOWLY(
        "Net.ErrorCodesForSubresources2",
        -loader->request()->status().error());
  }

  if (loader->request()->url().SchemeIsCryptographic()) {
    RecordCertificateHistograms(loader->request()->ssl_info(),
                                info->GetResourceType());
  }

  if (delegate_)
    delegate_->RequestComplete(loader->request());

  RemovePendingRequest(info->GetChildID(), info->GetRequestID());
}

Project: Chrome

void ResourceDispatcherHostImpl::DidReceiveRedirect(ResourceLoader* loader,
                                                    const GURL& new_url) {
  ResourceRequestInfoImpl* info = loader->GetRequestInfo();

  int render_process_id, render_frame_host;
  if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host))
    return;

  net::URLRequest* request = loader->request();
  if (request->response_info().async_revalidation_required) {
    DCHECK_EQ(request->url_chain().size(), 1u);
    DCHECK(async_revalidation_manager_);

    async_revalidation_manager_->BeginAsyncRevalidation(*request,
                                                        scheduler_.get());
  }

  if (request->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION) {
    int new_load_flags =
        request->load_flags() & ~net::LOAD_SUPPORT_ASYNC_REVALIDATION;
    request->SetLoadFlags(new_load_flags);
  }

  if (info->IsDownload())
    return;

  scoped_ptr<ResourceRedirectDetails> detail(new ResourceRedirectDetails(
      loader->request(),
      GetCertID(loader->request(), info->GetChildID()),
      new_url));
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(
          &NotifyRedirectOnUI,
          render_process_id, render_frame_host, base::Passed(&detail)));
}

Project: Chrome

void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) {
  if (!update_load_states_timer_->IsRunning() &&
      scheduler_->HasLoadingClients()) {
    update_load_states_timer_->Start(
        FROM_HERE, TimeDelta::FromMilliseconds(kUpdateLoadStatesIntervalMsec),
        this, &ResourceDispatcherHostImpl::UpdateLoadInfo);
  }
}

Project: Chrome

void ResourceDispatcherHostImpl::EnableStaleWhileRevalidateForTesting() {
  if (!async_revalidation_manager_)
    async_revalidation_manager_.reset(new AsyncRevalidationManager);
}

Project: Chrome

storage::BlobStorageContext* GetBlobStorageContext(
    ChromeBlobStorageContext* blob_storage_context) {
  if (!blob_storage_context)
    return NULL;
  return blob_storage_context->context();
}

Project: Chrome

ResourceLoader* ResourceDispatcherHostImpl::GetLoader(
    const GlobalRequestID& id) const {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  LoaderMap::const_iterator i = pending_loaders_.find(id);
  if (i == pending_loaders_.end())
    return NULL;

  return i->second.get();
}

Project: Chrome

ResourceDispatcherHostImpl::GetOutstandingRequestsStats(
    const ResourceRequestInfoImpl& info) {
  OutstandingRequestsStatsMap::iterator entry =
      outstanding_requests_stats_map_.find(info.GetChildID());
  OustandingRequestsStats stats = { 0, 0 };
  if (entry != outstanding_requests_stats_map_.end())
    stats = entry->second;
  return stats;
}

Project: Chrome

bool ResourceDispatcherHostImpl::HandleExternalProtocol(ResourceLoader* loader,
                                                        const GURL& url) {
  if (!delegate_)
    return false;

  ResourceRequestInfoImpl* info = loader->GetRequestInfo();

  if (!IsResourceTypeFrame(info->GetResourceType()))
    return false;

  const net::URLRequestJobFactory* job_factory =
      info->GetContext()->GetRequestContext()->job_factory();
  if (job_factory->IsHandledURL(url))
    return false;

  return delegate_->HandleExternalProtocol(
      url, info->GetChildID(), info->GetWebContentsGetterForRequest(),
      info->IsMainFrame(), info->GetPageTransition(), info->HasUserGesture());
}

Project: Chrome

bool ResourceDispatcherHostImpl::HasSufficientResourcesForRequest(
    net::URLRequest* request) {
  ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request);
  OustandingRequestsStats stats = IncrementOutstandingRequestsCount(1, info);

  if (stats.num_requests > max_num_in_flight_requests_per_process_)
    return false;
  if (num_in_flight_requests_ > max_num_in_flight_requests_)
    return false;

  return true;
}

Project: Chrome

ResourceDispatcherHostImpl::HttpAuthRelationTypeOf(
    const GURL& request_url,
    const GURL& first_party) {
  if (!first_party.is_valid())
    return HTTP_AUTH_RELATION_TOP;

  if (net::registry_controlled_domains::SameDomainOrHost(
          first_party, request_url,
          net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES))
    return HTTP_AUTH_RELATION_SAME_DOMAIN;

  if (allow_cross_origin_auth_prompt())
    return HTTP_AUTH_RELATION_ALLOWED_CROSS;

  return HTTP_AUTH_RELATION_BLOCKED_CROSS;
}

Project: Chrome

ResourceDispatcherHostImpl::IncrementOutstandingRequestsCount(
    int count,
    ResourceRequestInfoImpl* info) {
  DCHECK_EQ(1, abs(count));
  num_in_flight_requests_ += count;

  DCHECK_NE(info->counted_as_in_flight_request(), count > 0);
  info->set_counted_as_in_flight_request(count > 0);

  OustandingRequestsStats stats = GetOutstandingRequestsStats(*info);
  stats.num_requests += count;
  DCHECK_GE(stats.num_requests, 0);
  UpdateOutstandingRequestsStats(*info, stats);

  return stats;
}

Project: Chrome

ResourceDispatcherHostImpl::IncrementOutstandingRequestsMemory(
    int count,
    const ResourceRequestInfoImpl& info) {
  DCHECK_EQ(1, abs(count));

  OustandingRequestsStats stats = GetOutstandingRequestsStats(info);

  stats.memory_cost += count * info.memory_cost();
  DCHECK_GE(stats.memory_cost, 0);
  UpdateOutstandingRequestsStats(info, stats);

  return stats;
}

Project: Chrome

bool IsDetachableResourceType(ResourceType type) {
  switch (type) {
    case RESOURCE_TYPE_PREFETCH:
    case RESOURCE_TYPE_PING:
    case RESOURCE_TYPE_CSP_REPORT:
      return true;
    default:
      return false;
  }
}

Project: Chrome

bool IsUsingLoFi(LoFiState lofi_state,
                 ResourceDispatcherHostDelegate* delegate,
                 const net::URLRequest& request,
                 ResourceContext* resource_context,
                 bool is_main_frame) {
  if (lofi_state == LOFI_UNSPECIFIED && delegate && is_main_frame)
    return delegate->ShouldEnableLoFiMode(request, resource_context);
  return lofi_state == LOFI_ON;
}

Project: Chrome

bool IsValidatedSCT(
    const net::SignedCertificateTimestampAndStatus& sct_status) {
  return sct_status.status == net::ct::SCT_STATUS_OK;
}

Project: Chrome

bool ResourceDispatcherHostImpl::LoadInfoIsMoreInteresting(const LoadInfo& a,
                                                           const LoadInfo& b) {

  uint64_t a_uploading_size = 0;
  if (a.load_state.state == net::LOAD_STATE_SENDING_REQUEST)
    a_uploading_size = a.upload_size;

  uint64_t b_uploading_size = 0;
  if (b.load_state.state == net::LOAD_STATE_SENDING_REQUEST)
    b_uploading_size = b.upload_size;

  if (a_uploading_size != b_uploading_size)
    return a_uploading_size > b_uploading_size;

  return a.load_state.state > b.load_state.state;
}

Project: Chrome

void LogResourceRequestTimeOnUI(
    base::TimeTicks timestamp,
    int render_process_id,
    int render_frame_id,
    const GURL& url) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  RenderFrameHostImpl* host =
      RenderFrameHostImpl::FromID(render_process_id, render_frame_id);
  if (host != nullptr) {
    DCHECK(host->frame_tree_node()->IsMainFrame());
    host->frame_tree_node()->navigator()->LogResourceRequestTime(
        timestamp, url);
  }
}

Project: Chrome

scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::MaybeInterceptAsStream(
    const base::FilePath& plugin_path,
    net::URLRequest* request,
    ResourceResponse* response,
    std::string* payload) {
  payload->clear();
  ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request);
  const std::string& mime_type = response->head.mime_type;

  GURL origin;
  if (!delegate_ ||
      !delegate_->ShouldInterceptResourceAsStream(
          request, plugin_path, mime_type, &origin, payload)) {
    return scoped_ptr<ResourceHandler>();
  }

  StreamContext* stream_context =
      GetStreamContextForResourceContext(info->GetContext());

  scoped_ptr<StreamResourceHandler> handler(
      new StreamResourceHandler(request,
                                stream_context->registry(),
                                origin));

  info->set_is_stream(true);
  scoped_ptr<StreamInfo> stream_info(new StreamInfo);
  stream_info->handle = handler->stream()->CreateHandle();
  stream_info->original_url = request->url();
  stream_info->mime_type = mime_type;
  if (response->head.headers.get()) {
    stream_info->response_headers =
        new net::HttpResponseHeaders(response->head.headers->raw_headers());
  }
  delegate_->OnStreamCreated(request, std::move(stream_info));
  return std::move(handler);
}

Project: Chrome

void NotifyRedirectOnUI(int render_process_id,
                        int render_frame_host,
                        scoped_ptr<ResourceRedirectDetails> details) {
  RenderFrameHostImpl* host =
      RenderFrameHostImpl::FromID(render_process_id, render_frame_host);
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(host));
  if (!web_contents)
    return;
  web_contents->DidGetRedirectForResourceRequest(host, *details.get());
}

Project: Chrome

void NotifyResponseOnUI(int render_process_id,
                        int render_frame_host,
                        scoped_ptr<ResourceRequestDetails> details) {
  RenderFrameHostImpl* host =
      RenderFrameHostImpl::FromID(render_process_id, render_frame_host);
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(host));
  if (!web_contents)
    return;
  web_contents->DidGetResourceResponseStart(*details.get());
}

Project: Chrome

void ResourceDispatcherHostImpl::OnCancelRequest(int request_id) {
  int child_id = filter_->child_id();

  if (IsTransferredNavigation(GlobalRequestID(child_id, request_id)))
    return;

  ResourceLoader* loader = GetLoader(child_id, request_id);
  if (!loader) {
    DVLOG(1) << "Canceling a request that wasn't found";
    return;
  }

  loader->CancelRequest(true);
}

Project: Chrome

void ResourceDispatcherHostImpl::OnDidChangePriority(
    int request_id,
    net::RequestPriority new_priority,
    int intra_priority_value) {
  ResourceLoader* loader = GetLoader(filter_->child_id(), request_id);
  if (!loader)
    return;

  scheduler_->ReprioritizeRequest(loader->request(), new_priority,
                                  intra_priority_value);
}

Project: Chrome

void ResourceDispatcherHostImpl::OnInit() {
  scheduler_.reset(new ResourceScheduler);
}

Project: Chrome

bool ResourceDispatcherHostImpl::OnMessageReceived(
    const IPC::Message& message,
    ResourceMessageFilter* filter) {
  filter_ = filter;
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(ResourceDispatcherHostImpl, message)
    IPC_MESSAGE_HANDLER(ResourceHostMsg_RequestResource, OnRequestResource)
    IPC_MESSAGE_HANDLER_DELAY_REPLY(ResourceHostMsg_SyncLoad, OnSyncLoad)
    IPC_MESSAGE_HANDLER(ResourceHostMsg_ReleaseDownloadedFile,
                        OnReleaseDownloadedFile)
    IPC_MESSAGE_HANDLER(ResourceHostMsg_DataDownloaded_ACK, OnDataDownloadedACK)
    IPC_MESSAGE_HANDLER(ResourceHostMsg_CancelRequest, OnCancelRequest)
    IPC_MESSAGE_HANDLER(ResourceHostMsg_DidChangePriority, OnDidChangePriority)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  if (!handled && IPC_MESSAGE_ID_CLASS(message.type()) == ResourceMsgStart) {
    base::PickleIterator iter(message);
    int request_id = -1;
    bool ok = iter.ReadInt(&request_id);
    DCHECK(ok);
    GlobalRequestID id(filter_->child_id(), request_id);
    DelegateMap::iterator it = delegate_map_.find(id);
    if (it != delegate_map_.end()) {
      base::ObserverList<ResourceMessageDelegate>::Iterator del_it(it->second);
      ResourceMessageDelegate* delegate;
      while (!handled && (delegate = del_it.GetNext()) != NULL) {
        handled = delegate->OnMessageReceived(message);
      }
    }

    handled = true;
  }

  filter_ = NULL;
  return handled;
}

Project: Chrome

void ResourceDispatcherHostImpl::OnRenderViewHostCreated(int child_id,
                                                         int route_id) {
  scheduler_->OnClientCreated(child_id, route_id);
}

Project: Chrome

void ResourceDispatcherHostImpl::OnRenderViewHostDeleted(
    int child_id,
    int route_id) {
  scheduler_->OnClientDeleted(child_id, route_id);
  CancelRequestsForRoute(child_id, route_id);
}

Project: Chrome

void ResourceDispatcherHostImpl::OnRenderViewHostSetIsLoading(int child_id,
                                                              int route_id,
                                                              bool is_loading) {
  scheduler_->OnLoadingStateChanged(child_id, route_id, !is_loading);
}

Project: Chrome

void ResourceDispatcherHostImpl::OnRequestResource(
    int routing_id,
    int request_id,
    const ResourceHostMsg_Request& request_data) {
  tracked_objects::ScopedTracker tracking_profile(
      FROM_HERE_WITH_EXPLICIT_FUNCTION(
          "477117 ResourceDispatcherHostImpl::OnRequestResource"));
  if (request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME &&
      request_data.transferred_request_request_id == -1 &&
      !IsBrowserSideNavigationEnabled()) {
    BrowserThread::PostTask(
        BrowserThread::UI,
        FROM_HERE,
        base::Bind(&LogResourceRequestTimeOnUI,
                   TimeTicks::Now(),
                   filter_->child_id(),
                   request_data.render_frame_id,
                   request_data.url));
  }
  BeginRequest(request_id, request_data, NULL, routing_id);
}

Project: Chrome

void ResourceDispatcherHostImpl::OnShutdown() {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  is_shutdown_ = true;
  pending_loaders_.clear();

  update_load_states_timer_.reset();

  std::set<GlobalRoutingID> ids;
  for (const auto& blocked_loaders : blocked_loaders_map_) {
    std::pair<std::set<GlobalRoutingID>::iterator, bool> result =
        ids.insert(blocked_loaders.first);
    DCHECK(result.second);
  }
  for (const auto& routing_id : ids) {
    CancelBlockedRequestsForRoute(routing_id.child_id, routing_id.route_id);
  }

  scheduler_.reset();
}

Project: Chrome

void ResourceDispatcherHostImpl::OnSyncLoad(
    int request_id,
    const ResourceHostMsg_Request& request_data,
    IPC::Message* sync_result) {
  BeginRequest(request_id, request_data, sync_result,
                sync_result->routing_id());
 }

Project: Chrome

void ResourceDispatcherHostImpl::ProcessBlockedRequestsForRoute(
    int child_id,
    int route_id,
    bool cancel_requests) {
  BlockedLoadersMap::iterator iter = blocked_loaders_map_.find(
      GlobalRoutingID(child_id, route_id));
  if (iter == blocked_loaders_map_.end()) {
    return;
  }

  BlockedLoadersList* loaders = iter->second.get();
  scoped_ptr<BlockedLoadersList> deleter(std::move(iter->second));

  blocked_loaders_map_.erase(iter);

  for (scoped_ptr<ResourceLoader>& loader : *loaders) {
    ResourceRequestInfoImpl* info = loader->GetRequestInfo();
    if (cancel_requests) {
      IncrementOutstandingRequestsMemory(-1, *info);
    } else {
      StartLoading(info, std::move(loader));
    }
  }
}

Project: Chrome

void RecordAbortRapporOnUI(const GURL& url,
                           base::TimeDelta request_loading_time) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (request_loading_time.InMilliseconds() < 100)
    GetContentClient()->browser()->RecordURLMetric("Net.ErrAborted.Fast", url);
  else
    GetContentClient()->browser()->RecordURLMetric("Net.ErrAborted.Slow", url);
}

Project: Chrome

void RecordCertificateHistograms(const net::SSLInfo& ssl_info,
                                 ResourceType resource_type) {
  static const int64_t kJanuary2017 = INT64_C(13127702400000000);
  static const int64_t kJune2016 = INT64_C(13109213000000000);
  static const int64_t kJanuary2016 = INT64_C(13096080000000000);

  SHA1HistogramTypes sha1_histogram = SHA1_NOT_PRESENT;
  if (ssl_info.cert_status & net::CERT_STATUS_SHA1_SIGNATURE_PRESENT) {
    DCHECK(ssl_info.cert.get());
    if (ssl_info.cert->valid_expiry() >=
        base::Time::FromInternalValue(kJanuary2017)) {
      sha1_histogram = SHA1_EXPIRES_AFTER_JANUARY_2017;
    } else if (ssl_info.cert->valid_expiry() >=
               base::Time::FromInternalValue(kJune2016)) {
      sha1_histogram = SHA1_EXPIRES_AFTER_JUNE_2016;
    } else if (ssl_info.cert->valid_expiry() >=
               base::Time::FromInternalValue(kJanuary2016)) {
      sha1_histogram = SHA1_EXPIRES_AFTER_JANUARY_2016;
    } else {
      sha1_histogram = SHA1_PRESENT;
    }
  }
  if (resource_type == RESOURCE_TYPE_MAIN_FRAME) {
    UMA_HISTOGRAM_ENUMERATION("Net.Certificate.SHA1.MainFrame",
                              sha1_histogram,
                              SHA1_HISTOGRAM_TYPES_MAX);
  } else {
    UMA_HISTOGRAM_ENUMERATION("Net.Certificate.SHA1.Subresource",
                              sha1_histogram,
                              SHA1_HISTOGRAM_TYPES_MAX);
  }
}

Project: Chrome

void ResourceDispatcherHostImpl::RegisterDownloadedTempFile(
    int child_id, int request_id, const base::FilePath& file_path) {
  scoped_refptr<ShareableFileReference> reference =
      ShareableFileReference::Get(file_path);
  DCHECK(reference.get());

  registered_temp_files_[child_id][request_id] = reference;
  ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
      child_id, reference->path());

  reference->AddFinalReleaseCallback(
      base::Bind(&RemoveDownloadFileFromChildSecurityPolicy,
                 child_id));
}

Project: Chrome

void ResourceDispatcherHostImpl::RegisterResourceMessageDelegate(
    const GlobalRequestID& id, ResourceMessageDelegate* delegate) {
  DelegateMap::iterator it = delegate_map_.find(id);
  if (it == delegate_map_.end()) {
    it = delegate_map_.insert(
                           std::make_pair(
                               id,
                               new base::ObserverList<ResourceMessageDelegate>))
             .first;
  }
  it->second->AddObserver(delegate);
}

Project: Chrome

void RemoveDownloadFileFromChildSecurityPolicy(int child_id,
                                               const base::FilePath& path) {
  ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile(
      child_id, path);
}

Project: Chrome

void ResourceDispatcherHostImpl::ResumeDeferredNavigation(
    const GlobalRequestID& id) {
  ResourceLoader* loader = GetLoader(id);
  if (loader)
    loader->CompleteTransfer();
}

Project: Chrome

void SetReferrerForRequest(net::URLRequest* request, const Referrer& referrer) {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (!referrer.url.is_valid() ||
      command_line->HasSwitch(switches::kNoReferrers)) {
    request->SetReferrer(std::string());
  } else {
    request->SetReferrer(referrer.url.spec());
  }

  net::URLRequest::ReferrerPolicy net_referrer_policy =
      net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE;
  switch (referrer.policy) {
    case blink::WebReferrerPolicyAlways:
    case blink::WebReferrerPolicyNever:
    case blink::WebReferrerPolicyOrigin:
      net_referrer_policy = net::URLRequest::NEVER_CLEAR_REFERRER;
      break;
    case blink::WebReferrerPolicyNoReferrerWhenDowngrade:
      net_referrer_policy =
          net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE;
      break;
    case blink::WebReferrerPolicyOriginWhenCrossOrigin:
      net_referrer_policy =
          net::URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN;
      break;
    case blink::WebReferrerPolicyDefault:
    default:
      net_referrer_policy =
          command_line->HasSwitch(switches::kReducedReferrerGranularity)
              ? net::URLRequest::
                    REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN
              : net::URLRequest::
                    CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE;
      break;
  }
  request->set_referrer_policy(net_referrer_policy);
}

Project: Chrome

bool ShouldServiceRequest(int process_type,
                          int child_id,
                          const ResourceHostMsg_Request& request_data,
                          const net::HttpRequestHeaders& headers,
                          ResourceMessageFilter* filter,
                          ResourceContext* resource_context) {
  if (process_type == PROCESS_TYPE_PLUGIN)
    return true;

  ChildProcessSecurityPolicyImpl* policy =
      ChildProcessSecurityPolicyImpl::GetInstance();

  if (!policy->CanRequestURL(child_id, request_data.url)) {
    VLOG(1) << "Denied unauthorized request for "
            << request_data.url.possibly_invalid_spec();
    return false;
  }

  std::string origin_string;
  bool has_origin = headers.GetHeader("Origin", &origin_string) &&
                    origin_string != "null";
  if (has_origin) {
    GURL origin(origin_string);
    if (!policy->CanCommitURL(child_id, origin) ||
        GetContentClient()->browser()->IsIllegalOrigin(resource_context,
                                                       child_id, origin)) {
      VLOG(1) << "Killed renderer for illegal origin: " << origin_string;
      bad_message::ReceivedBadMessage(filter, bad_message::RDH_ILLEGAL_ORIGIN);
      return false;
    }
  }

  if (request_data.request_body.get()) {
    const std::vector<ResourceRequestBody::Element>* uploads =
        request_data.request_body->elements();
    std::vector<ResourceRequestBody::Element>::const_iterator iter;
    for (iter = uploads->begin(); iter != uploads->end(); ++iter) {
      if (iter->type() == ResourceRequestBody::Element::TYPE_FILE &&
          !policy->CanReadFile(child_id, iter->path())) {
        NOTREACHED() << "Denied unauthorized upload of "
                     << iter->path().value();
        return false;
      }
      if (iter->type() == ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM) {
        storage::FileSystemURL url =
            filter->file_system_context()->CrackURL(iter->filesystem_url());
        if (!policy->CanReadFileSystemFile(child_id, url)) {
          NOTREACHED() << "Denied unauthorized upload of "
                       << iter->filesystem_url().spec();
          return false;
        }
      }
    }
  }

  return true;
}

Project: Chrome

void ResourceDispatcherHostImpl::Shutdown() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  BrowserThread::PostTask(BrowserThread::IO,
                          FROM_HERE,
                          base::Bind(&ResourceDispatcherHostImpl::OnShutdown,
                                     base::Unretained(this)));
}

Project: Chrome

void ResourceDispatcherHostImpl::StartLoading(
    ResourceRequestInfoImpl* info,
    scoped_ptr<ResourceLoader> loader) {
  tracked_objects::ScopedTracker tracking_profile(
      FROM_HERE_WITH_EXPLICIT_FUNCTION(
          "456331 ResourceDispatcherHostImpl::StartLoading"));

  ResourceLoader* loader_ptr = loader.get();
  pending_loaders_[info->GetGlobalRequestID()] = std::move(loader);

  loader_ptr->StartRequest();
}

Project: Chrome

void ResourceDispatcherHostImpl::UnregisterResourceMessageDelegate(
    const GlobalRequestID& id, ResourceMessageDelegate* delegate) {
  DCHECK(ContainsKey(delegate_map_, id));
  DelegateMap::iterator it = delegate_map_.find(id);
  DCHECK(it->second->HasObserver(delegate));
  it->second->RemoveObserver(delegate);
  if (!it->second->might_have_observers()) {
    delete it->second;
    delegate_map_.erase(it);
  }
}

Project: Chrome

void ResourceDispatcherHostImpl::UpdateLoadInfo() {
  scoped_ptr<LoadInfoMap> info_map(GetLoadInfoForAllRoutes());

  if (info_map->empty() || !scheduler_->HasLoadingClients()) {
    update_load_states_timer_->Stop();
    return;
  }

  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread,
                 base::Passed(&info_map)));
}

Project: Chrome

void ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread(
    scoped_ptr<LoadInfoMap> info_map) {
  tracked_objects::ScopedTracker tracking_profile(
      FROM_HERE_WITH_EXPLICIT_FUNCTION(
          "466285 ResourceDispatcherHostImpl::UpdateLoadInfoOnUIThread"));
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  for (const auto& load_info : *info_map) {
    RenderViewHostImpl* view = RenderViewHostImpl::FromID(
        load_info.first.child_id, load_info.first.route_id);
    if (view) {
      view->LoadStateChanged(load_info.second.url, load_info.second.load_state,
                             load_info.second.upload_position,
                             load_info.second.upload_size);
    }
  }
}

Project: Chrome

void ResourceDispatcherHostImpl::UpdateOutstandingRequestsStats(
    const ResourceRequestInfoImpl& info,
    const OustandingRequestsStats& stats) {
  if (stats.memory_cost == 0 && stats.num_requests == 0)
    outstanding_requests_stats_map_.erase(info.GetChildID());
  else
    outstanding_requests_stats_map_[info.GetChildID()] = stats;
}

Project: Chrome

 void ResourceDispatcherHostImpl::UpdateRequestForTransfer(
     int child_id,
     int route_id,
    int request_id,
    const ResourceHostMsg_Request& request_data,
    LoaderMap::iterator iter) {
  ResourceRequestInfoImpl* info = iter->second->GetRequestInfo();
  GlobalRoutingID old_routing_id(
      request_data.transferred_request_child_id, info->GetRouteID());
  GlobalRequestID old_request_id(request_data.transferred_request_child_id,
                                 request_data.transferred_request_request_id);
  GlobalRoutingID new_routing_id(child_id, route_id);
  GlobalRequestID new_request_id(child_id, request_id);

  IncrementOutstandingRequestsMemory(-1, *info);
  bool should_update_count = info->counted_as_in_flight_request();
  if (should_update_count)
    IncrementOutstandingRequestsCount(-1, info);

  DCHECK(pending_loaders_.find(old_request_id) == iter);
  scoped_ptr<ResourceLoader> loader = std::move(iter->second);
  ResourceLoader* loader_ptr = loader.get();
  pending_loaders_.erase(iter);

  info->UpdateForTransfer(child_id, route_id, request_data.render_frame_id,
                          request_data.origin_pid, request_id,
                          filter_->GetWeakPtr());

  pending_loaders_[new_request_id] = std::move(loader);
  IncrementOutstandingRequestsMemory(1, *info);
  if (should_update_count)
    IncrementOutstandingRequestsCount(1, info);
  if (old_routing_id != new_routing_id) {
    if (blocked_loaders_map_.find(old_routing_id) !=
            blocked_loaders_map_.end()) {
      blocked_loaders_map_[new_routing_id] =
          std::move(blocked_loaders_map_[old_routing_id]);
      blocked_loaders_map_.erase(old_routing_id);
    }
  }
  if (old_request_id != new_request_id) {
    DelegateMap::iterator it = delegate_map_.find(old_request_id);
    if (it != delegate_map_.end()) {
      base::ObserverList<ResourceMessageDelegate>::Iterator del_it(it->second);
      ResourceMessageDelegate* delegate;
      while ((delegate = del_it.GetNext()) != NULL) {
        delegate->set_request_id(new_request_id);
      }
      delegate_map_[new_request_id] = delegate_map_[old_request_id];
      delegate_map_.erase(old_request_id);
    }
  }

  AppCacheInterceptor::CompleteCrossSiteTransfer(
      loader_ptr->request(),
      child_id,
      request_data.appcache_host_id,
      filter_);

  ServiceWorkerRequestHandler* handler =
      ServiceWorkerRequestHandler::GetHandler(loader_ptr->request());
  if (handler) {
    if (!handler->SanityCheckIsSameContext(filter_->service_worker_context())) {
      bad_message::ReceivedBadMessage(
          filter_, bad_message::RDHI_WRONG_STORAGE_PARTITION);
    } else {
      handler->CompleteCrossSiteTransfer(
          child_id, request_data.service_worker_provider_id);
    }
  }

  DCHECK(info->cross_site_handler());
}

Project: Chrome

ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() {
  DCHECK(outstanding_requests_stats_map_.empty());
  DCHECK(g_resource_dispatcher_host);
  g_resource_dispatcher_host = NULL;
}

Project: Chrome

RenderViewHostImpl* PrepareToDuplicateHosts(Shell* shell,
                                            int* target_routing_id) {
  GURL foo("http://foo.com/simple_page.html");

  NavigateToURL(shell, foo);
  EXPECT_EQ(base::ASCIIToUTF16("OK"), shell->web_contents()->GetTitle());

  ShellAddedObserver shell2_observer;
  EXPECT_TRUE(ExecuteScript(
      shell->web_contents(), "window.open(document.URL + '#2');"));
  Shell* shell2 = shell2_observer.GetShell();

  EXPECT_EQ(shell->web_contents()->GetRenderViewHost()->GetProcess()->GetID(),
            shell2->web_contents()->GetRenderViewHost()->GetProcess()->GetID());
  *target_routing_id =
      shell2->web_contents()->GetRenderViewHost()->GetRoutingID();
  EXPECT_NE(*target_routing_id,
            shell->web_contents()->GetRenderViewHost()->GetRoutingID());

  GURL extension_url("https://bar.com/simple_page.html");
  WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell->web_contents());
  wc->GetFrameTree()->root()->navigator()->RequestOpenURL(
      wc->GetFrameTree()->root()->current_frame_host(), extension_url, nullptr,
      Referrer(), CURRENT_TAB, false, true);

  RenderFrameHostImpl* next_rfh;
  if (IsBrowserSideNavigationEnabled())
    next_rfh = wc->GetRenderManagerForTesting()->speculative_frame_host();
  else
    next_rfh = wc->GetRenderManagerForTesting()->pending_frame_host();

  EXPECT_TRUE(next_rfh);
  EXPECT_NE(shell->web_contents()->GetRenderProcessHost()->GetID(),
            next_rfh->GetProcess()->GetID());

   return next_rfh->render_view_host();
 }

Project: Chrome

  SecurityExploitBrowserTest() {}

Project: Chrome

  explicit SecurityExploitTestInterstitialPage(WebContents* contents) {
    InterstitialPage* interstitial = InterstitialPage::Create(
        contents, true, contents->GetLastCommittedURL(), this);
    interstitial->Show();
  }

Project: Chrome

void SecurityExploitBrowserTest::TestFileChooserWithPath(
    const base::FilePath& path) {
  GURL foo("http://foo.com/simple_page.html");
  NavigateToURL(shell(), foo);
  EXPECT_EQ(base::ASCIIToUTF16("OK"), shell()->web_contents()->GetTitle());

  RenderViewHost* compromised_renderer =
      shell()->web_contents()->GetRenderViewHost();
  RenderProcessHostWatcher terminated(
      shell()->web_contents(),
      RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

  FileChooserParams params;
  params.default_file_name = path;

  ViewHostMsg_RunFileChooser evil(compromised_renderer->GetRoutingID(), params);

  IpcSecurityTestUtil::PwnMessageReceived(
      compromised_renderer->GetProcess()->GetChannel(), evil);
  terminated.Wait();
}

Project: Chrome

  std::string last_command() { return last_command_; }