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

 

上一次说到怎么样开始把任务发送出去,也就是调用函数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  }

 

由于这里是对URLHTTP请求下载数据,所以这里的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个函数的调用处理,然后就会通过WindowsHTTP 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) {

 

下面就是调用WindowsAPI函数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收到网页的数据后,又是怎么样处理的呢?下一次再来分析这个问题。

 

你可能感兴趣的:(源码分析)