從Cronet.mm開始
1. CRNHTTPProtocolHandler來處理攔截的請(qǐng)求

2.?CRNHTTPProtocolHandler 中startLoading開始發(fā)送請(qǐng)求

3. url_request Start

4. URLRequestHttpJob StartJob

5. 接著進(jìn)入HttpNetworkTransaction::Start 這個(gè)比較重要,里面調(diào)用DoLoop

6. DoCreateStream 可能會(huì)創(chuàng)建出三種Stream HttpBasicStream, SpdyHttpStream, QuicHttpStream ,而我們只需要QuicHttpStream, 創(chuàng)建stream的流程大致如下:
http_stream_factory::RequestStreamInternal?
http_stream_factory_job_controller::Start
http_stream_factory_job_controller::Start 又開始了一個(gè)新的loop?

7. http_stream_factory_job_controller::DoCreateJobs 這一步最為關(guān)鍵,全部源碼貼出來,
在QUIC的情況下會(huì)創(chuàng)建一個(gè)mainjob , 一個(gè)alternative_job_ ,優(yōu)先alternative_job_執(zhí)行,mainjob會(huì)執(zhí)行DoWait,alternative_job_是否能創(chuàng)建取決于proxy(網(wǎng)絡(luò)代理)的判斷和 之前我們添加的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;
}