美文网首页
Cronet代码解析

Cronet代码解析

作者: 孙龙波 | 来源:发表于2021-01-06 16:44 被阅读0次

从Cronet.mm开始

1. CRNHTTPProtocolHandler来处理拦截的请求

CRNHTTPProtocolHandler拦截请求

2. CRNHTTPProtocolHandler 中startLoading开始发送请求

startLoading

3. url_request Start

url_request Start

4. URLRequestHttpJob StartJob

URLRequestHttpJob

5. 接着进入HttpNetworkTransaction::Start 这个比较重要,里面调用DoLoop

HttpNetworkTransaction

6. DoCreateStream 可能会创建出三种Stream HttpBasicStream, SpdyHttpStream, QuicHttpStream ,而我们只需要QuicHttpStream, 创建stream的流程大致如下:

http_stream_factory::RequestStreamInternal 

http_stream_factory_job_controller::Start

http_stream_factory_job_controller::Start 又开始了一个新的loop 

http_stream_factory_job_controller

7. http_stream_factory_job_controller::DoCreateJobs 这一步最为关键,全部源码贴出来,

在QUIC的情况下会创建一个mainjob , 一个alternative_job_ ,优先alternative_job_执行,mainjob会执行DoWait,alternative_job_是否能创建取决于proxy(网络代理)的判断和 之前我们添加的QuicHints

int HttpStreamFactory::JobController::DoCreateJobs() {

  DCHECK(!main_job_);

  DCHECK(!alternative_job_);

  HostPortPair destination(HostPortPair::FromURL(request_info_.url));

  GURL origin_url = ApplyHostMappingRules(request_info_.url, &destination);

  // Create an alternative job if alternative service is set up for this domain,

  // but only if we'll be speaking directly to the server, since QUIC through

  // proxies is not supported.

  if(proxy_info_.is_direct()) {

    alternative_service_info_ =

        GetAlternativeServiceInfoFor(request_info_, delegate_, stream_type_);

  }

  quic::ParsedQuicVersion quic_version = quic::ParsedQuicVersion::Unsupported();

  if(alternative_service_info_.protocol() == kProtoQUIC) {

    quic_version =

        SelectQuicVersion(alternative_service_info_.advertised_versions());

    DCHECK_NE(quic_version, quic::ParsedQuicVersion::Unsupported());

  }

  LOG(WARNING) <<"TripCronet alternative_service_info_ protocol: "<< alternative_service_info_.protocol();

  if(is_preconnect_) {

    // Due to how the socket pools handle priorities and idle sockets, only IDLE

    // priority currently makes sense for preconnects. The priority for

    // preconnects is currently ignored (see RequestSocketsForPool()), but could

    // be used at some point for proxy resolution or something.

    if(alternative_service_info_.protocol() != kProtoUnknown) {

      HostPortPair alternative_destination(

          alternative_service_info_.host_port_pair());

      ignore_result(

          ApplyHostMappingRules(request_info_.url, &alternative_destination));

      main_job_ = job_factory_->CreateAltSvcJob(

          this, PRECONNECT, session_, request_info_, IDLE, proxy_info_,

          server_ssl_config_, proxy_ssl_config_, alternative_destination,

          origin_url, alternative_service_info_.protocol(), quic_version,

          is_websocket_, enable_ip_based_pooling_, session_->net_log());

    }else{

      main_job_ = job_factory_->CreateMainJob(

          this, PRECONNECT, session_, request_info_, IDLE, proxy_info_,

          server_ssl_config_, proxy_ssl_config_, destination, origin_url,

          is_websocket_, enable_ip_based_pooling_, session_->net_log());

    }

    main_job_->Preconnect(num_streams_);

    returnOK;

  }

  main_job_ = job_factory_->CreateMainJob(

      this, MAIN, session_, request_info_, priority_, proxy_info_,

      server_ssl_config_, proxy_ssl_config_, destination, origin_url,

      is_websocket_, enable_ip_based_pooling_, net_log_.net_log());

  // Alternative Service can only be set for HTTPS requests while Alternative

  // Proxy is set for HTTP requests.

  if(alternative_service_info_.protocol() != kProtoUnknown) {

    DCHECK(request_info_.url.SchemeIs(url::kHttpsScheme));

    LOG(WARNING) <<"Selected alternative service (host: "

             << alternative_service_info_.host_port_pair().host()

             <<" port: "<< alternative_service_info_.host_port_pair().port()

             <<" version: "<< quic_version <<")";

    HostPortPair alternative_destination(

        alternative_service_info_.host_port_pair());

    ignore_result(

        ApplyHostMappingRules(request_info_.url, &alternative_destination));

    alternative_job_ = job_factory_->CreateAltSvcJob(

        this, ALTERNATIVE, session_, request_info_, priority_, proxy_info_,

        server_ssl_config_, proxy_ssl_config_, alternative_destination,

        origin_url, alternative_service_info_.protocol(), quic_version,

        is_websocket_, enable_ip_based_pooling_, net_log_.net_log());

    main_job_is_blocked_ =true;

    alternative_job_->Start(request_->stream_type());

  }

  // Even if |alternative_job| has already finished, it will not have notified

  // the request yet, since we defer that to the next iteration of the

  // MessageLoop, so starting |main_job_| is always safe.

  main_job_->Start(request_->stream_type());

  returnOK;

}

相关文章

网友评论

      本文标题:Cronet代码解析

      本文链接:https://www.haomeiwen.com/subject/vbsivktx.html