从Cronet.mm开始
1. CRNHTTPProtocolHandler来处理拦截的请求
2. CRNHTTPProtocolHandler 中startLoading开始发送请求
3. url_request Start
4. URLRequestHttpJob StartJob
5. 接着进入HttpNetworkTransaction::Start 这个比较重要,里面调用DoLoop
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
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;
}