谷歌浏览器的源码分析(27)

系统 1683 0
 

上一次说到怎么样开始把任务发送出去,也就是调用函数 BeginRequestInternal 来把 URL 请求发送,它的代码如下:

#001   void ResourceDispatcherHost::BeginRequestInternal(URLRequest* request,

#002                                                     bool mixed_content) {

 

获取请求信息。

#003     ExtraRequestInfo* info = ExtraInfoForRequest(request);

 

生成全局 ID ,然后保存到正在下载请求队列里。

#004     GlobalRequestID global_id(info->render_process_host_id, info->request_id);

#005     pending_requests_[global_id] = request;

#006     if (mixed_content) {

#007       // We don't start the request in that case.   The SSLManager will potentially

#008       // change the request (potentially to indicate its content should be

#009       // filtered) and start it itself.

#010       SSLManager::OnMixedContentRequest(this, request, ui_loop_);

#011       return;

#012     }

 

这里开始处理请求。

#013     request->Start();

#014  

 

启动上传状态更新定时器。

#015     // Make sure we have the load state monitor running

#016     if (!update_load_states_timer_.IsRunning()) {

#017       update_load_states_timer_.Start(

#018           TimeDelta::FromMilliseconds(kUpdateLoadStatesIntervalMsec),

#019           this, &ResourceDispatcherHost::UpdateLoadStates);

#020     }

#021   }

 

通过上面的函数可以看到主要调用 URLRequest::Start() 来处理下载的请求,它的代码如下:

#001   void URLRequest::Start() {

#002     DCHECK(!is_pending_);

#003     DCHECK(!job_);

#004  

 

创建一个下载的工作任务。

#005     job_ = GetJobManager()->CreateJob(this);

#006     job_->SetExtraRequestHeaders(extra_request_headers_);

#007  

 

判断是否有数据需要上传。

#008     if (upload_.get())

#009       job_->SetUpload(upload_.get());

#010  

 

设置请下开始下载的时间,以便后面检查超时的状态。

#011     is_pending_ = true;

#012     response_info_.request_time = Time::Now();

#013  

#014     // Don't allow errors to be sent from within Start().

#015     // TODO(brettw) this may cause NotifyDone to be sent synchronously,

#016     // we probably don't want this: they should be sent asynchronously so

#017     // the caller does not get reentered.

 

这里把工作任务启动运行。

#018     job_->Start();

#019   }

 

由于这里是对 URL HTTP 请求下载数据,所以这里的 job_ 是类 URLRequestHttpJob 的实例,也就是调用函数 URLRequestHttpJob::Start() ,在函数 URLRequestHttpJob::Start() 的处理过程序如下:

1.        URLRequestHttpJob::StartTransaction()

2.        net::HttpCache::Transaction::Start

3.        net::HttpCache::Transaction::BeginNetworkRequest()

4.        net::HttpTransactionWinHttp::Start

5.        net::HttpTransactionWinHttp::DidResolveProxy()

6.        net::HttpTransactionWinHttp::OpenRequest

7.        net::HttpTransactionWinHttp::SendRequest()

8.        net::WinHttpRequestThrottle::SubmitRequest

9.        net::WinHttpRequestThrottle::SendRequest

通过上面 9 个函数的调用处理,然后就会通过 Windows HTTP API 进行发送请求和下载数据。我们来分析一下最后的函数 WinHttpRequestThrottle::SendRequest ,看看怎么样调用 Windows HTTP API 函数来获取数据的,它的代码如下:

#001   BOOL WinHttpRequestThrottle::SendRequest(HINTERNET request_handle,

#002                                            DWORD total_size,

#003                                            DWORD_PTR context,

#004                                            bool report_async_error) {

 

下面就是调用 Windows API 函数 WinHttpSendRequest 来发送请求,当然在调用这个函数之前,需要调用函数 WinHttpOpenRequest 先打开一个 TCP 连接。

#005     BOOL ok = WinHttpSendRequest(request_handle,

#006                                  WINHTTP_NO_ADDITIONAL_HEADERS,

#007                                  0,

#008                                  WINHTTP_NO_REQUEST_DATA,

#009                                  0,

#010                                  total_size,

#011                                  context);

#012     if (!ok && report_async_error) {

#013       WINHTTP_ASYNC_RESULT async_result = { API_SEND_REQUEST, GetLastError() };

 

出错处理,就调用外面的回调函数。

#014       HttpTransactionWinHttp::StatusCallback(

#015           request_handle, context,

#016           WINHTTP_CALLBACK_STATUS_REQUEST_ERROR,

#017           &async_result, sizeof(async_result));

#018     }

#019     return ok;

#020   }

 

通过前面一系列的分析学会 chrome 浏览器怎么样输入 URL 地址,以及怎么样进行 URL 自动完成,然后把 URL 发送到渲染进程去处理,最后渲染进程又把资源下载请求发送到资源下载进程里处理,最后资源下载进程通过 Windows HTTP API 函数进行 TCP 连接,以及 HTTP 数据的上传和下载。浏览器向网站发送请求的过程已经分析完成了,那么 HTTP API 收到网页的数据后,又是怎么样处理的呢?下一次再来分析这个问题。

 

谷歌浏览器的源码分析(27)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论