Cronet代碼解析

從Cronet.mm開始

1. CRNHTTPProtocolHandler來處理攔截的請(qǐng)求

CRNHTTPProtocolHandler攔截請(qǐng)求

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


startLoading

3. url_request Start


url_request Start

4. URLRequestHttpJob StartJob


URLRequestHttpJob

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


HttpNetworkTransaction

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?


http_stream_factory_job_controller

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;

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容