上一次说到怎么样开始把任务发送出去,也就是调用函数
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
收到网页的数据后,又是怎么样处理的呢?下一次再来分析这个问题。