chromium中HTTP网络资源的加载过程

chromium中HTTP网络资源的加载主要分两部分,一部分是缓存的网络资源,一部分是线上的网络资源。

我们访问http网页的时候,首先访问httpcache,看缓存中的数据是否有效,如果有效,那么我们加载这个数据,如果无效,那么我们访问网络去重新加载资源,当然chromium中HTTP网络资源的加载并没有说起来这么简单,实际上架构设计还是比较复杂的。首先我们先看看HttpCache::Transaction的相关设计及实现,研究一下缓存的处理。

HttpCache::Transaction

在源码分析之前,我们先看一个小示例,从使用者的角度看看cache的使用过程,那么就需要一个切入点。

情景分析

首先我们在windbg中启动chromium,然后设置多进程调试。

0:000> .childdbg 1
Processes created by the current process will be debugged
0:000> g

运行后待程序稳定后,中断到调试器,之后在主进程上下断

0:011> bp chrome_7feed810000!net::HttpCache::Transaction::Start

之后运行起来,然后在浏览器的地址窗口中输入一个字符“c”,这是我假定的设置的,因为浏览器的地址窗口默认设置了百度的搜索引擎,当用户输入一个字符的时候会触发一次搜索。而实际上确实是这样。当输入字符后,我的程序中断了。

0:028> kc
 # Call Site
00 chrome_7feed810000!net::HttpCache::Transaction::Start
01 chrome_7feed810000!net::URLRequestHttpJob::StartTransactionInternal
02 chrome_7feed810000!net::URLRequestHttpJob::MaybeStartTransactionInternal
03 chrome_7feed810000!net::URLRequestHttpJob::StartTransaction
04 chrome_7feed810000!net::URLRequestHttpJob::SetCookieHeaderAndStart
05 chrome_7feed810000!base::internal::RunnableAdapter<void (__cdecl LocalDataContainer::*)(std::list<content::CacheStorageUsageInfo,std::allocator<content::CacheStorageUsageInfo> > const &)>::Run
06 chrome_7feed810000!base::internal::InvokeHelper<1,void,base::internal::RunnableAdapter<void (__cdecl LocalDataContainer::*)(std::list<content::CacheStorageUsageInfo,std::allocator<content::CacheStorageUsageInfo> > const &)> >::MakeItSo
07 chrome_7feed810000!base::internal::Invoker<base::IndexSequence<0>,base::internal::BindState<base::internal::RunnableAdapter<void (__cdecl LocalDataContainer::*)(std::list<content::CacheStorageUsageInfo,std::allocator<content::CacheStorageUsageInfo> > const & __ptr64) __ptr64>,void __cdecl(LocalDataContainer * __ptr64,std::list<content::CacheStorageUsageInfo,std::allocator<content::CacheStorageUsageInfo> > const & __ptr64),base::WeakPtr<LocalDataContainer> >,base::internal::InvokeHelper<1,void,base::internal::RunnableAdapter<void (__cdecl LocalDataContainer::*)(std::list<content::CacheStorageUsageInfo,std::allocator<content::CacheStorageUsageInfo> > const & __ptr64) __ptr64> >,void __cdecl(std::list<content::CacheStorageUsageInfo,std::allocator<content::CacheStorageUsageInfo> > const & __ptr64)>::Run
08 chrome_7feed810000!base::Callback<void __cdecl(void)>::Run
09 chrome_7feed810000!net::CookieMonster::CookieMonsterTask::InvokeCallback
0a chrome_7feed810000!net::CookieMonster::GetCookieListWithOptionsTask::Run
0b chrome_7feed810000!net::CookieMonster::DoCookieTaskForURL
0c chrome_7feed810000!net::CookieMonster::GetCookieListWithOptionsAsync
0d chrome_7feed810000!net::URLRequestHttpJob::AddCookieHeaderAndStart
0e chrome_7feed810000!net::URLRequestHttpJob::Start
0f chrome_7feed810000!net::URLRequest::StartJob
10 chrome_7feed810000!net::URLRequest::BeforeRequestComplete
11 chrome_7feed810000!net::URLRequest::Start
12 chrome_7feed810000!net::URLFetcherCore::StartURLRequest
13 chrome_7feed810000!net::URLFetcherCore::StartURLRequestWhenAppropriate
14 chrome_7feed810000!net::URLFetcherCore::DidInitializeWriter
15 chrome_7feed810000!net::URLFetcherCore::StartOnIOThread
16 chrome_7feed810000!base::Callback<void __cdecl(void)>::Run
17 chrome_7feed810000!base::debug::TaskAnnotator::RunTask
18 chrome_7feed810000!base::MessageLoop::RunTask
19 chrome_7feed810000!base::MessageLoop::DeferOrRunPendingTask
1a chrome_7feed810000!base::MessageLoop::DoWork
1b chrome_7feed810000!base::MessagePumpForIO::DoRunLoop
1c chrome_7feed810000!base::MessagePumpWin::Run
1d chrome_7feed810000!base::MessageLoop::RunHandler
1e chrome_7feed810000!base::RunLoop::Run
1f chrome_7feed810000!base::MessageLoop::Run
20 chrome_7feed810000!base::Thread::Run
21 chrome_7feed810000!content::BrowserThreadImpl::IOThreadRun
22 chrome_7feed810000!content::BrowserThreadImpl::Run
23 chrome_7feed810000!base::Thread::ThreadMain
24 chrome_7feed810000!base::`anonymous namespace'::ThreadFunc
25 kernel32!BaseThreadInitThunk
26 ntdll!RtlUserThreadStart

研究一下堆栈信息,其实就已经知道了大抵上的调用层次,这个请求的方式和我之前介绍过的chromium中FTP网络资源的加载 文章中很相似。

在一个IO线程中启动了URL的加载请求,这是一个内部请求,使用的是URLFetcherCore,然后启动URLRequest,之后开启一个特定的job,在这里这个job是URLRequestHttpJob,之后启动一个传输,而这个传输就是我们要说的HttpCache::Transaction,内部数据的请求基于HttpCache。

0:028> ~~[1244]s;.frame 0n0;dv /t /v
chrome_7feed810000!net::HttpCache::Transaction::Start:
000007fe`ee46c6e4 48895c2410      mov     qword ptr [rsp+10h],rbx ss:00000000`0961c408=0000000012695a60
00 00000000`0961c3f8 000007fe`ee4bf027 chrome_7feed810000!net::HttpCache::Transaction::Start [c:\b\build\slave\win64\build\src\net\http\http_cache_transaction.cc @ 254]
@rcx              class net::HttpCache::Transaction * this = 0x00000000`1269c170
@rdx              struct net::HttpRequestInfo * request = 0x00000000`12695c28
@r8               class base::Callback<void __cdecl(int)> * callback = 0x00000000`12695d40
@r9               class net::BoundNetLog * net_log = 0x00000000`12691ec8
<unavailable>     int rv = <value unavailable>
0:028> dx -id 0,0 -r1 (*((chrome_7feed810000!net::HttpRequestInfo *)0x12695c28))
(*((chrome_7feed810000!net::HttpRequestInfo *)0x12695c28))                 [Type: net::HttpRequestInfo]
    [+0x000] url              [Type: GURL]
    [+0x078] method           : "GET" [Type: std::basic_string<char,std::char_traits<char>,std::allocator<char> >]
    [+0x098] extra_headers    [Type: net::HttpRequestHeaders]
    [+0x0b0] upload_data_stream : 0x0 [Type: net::UploadDataStream *]
    [+0x0b8] load_flags       : 64
    [+0x0bc] motivation       : NORMAL_MOTIVATION (2) [Type: net::HttpRequestInfo::RequestMotivation]
    [+0x0c0] privacy_mode     : PRIVACY_MODE_DISABLED (0) [Type: net::PrivacyMode]
0:028> dx -id 0,0 -r1 (*((chrome_7feed810000!GURL *)0x12695c28))
(*((chrome_7feed810000!GURL *)0x12695c28))                 [Type: GURL]
    [+0x000] spec_            : "http://suggestion.baidu.com/su?wd=c&action=opensearch&ie=UTF-8" [Type: std::basic_string<char,std::char_traits<char>,std::allocator<char> >]
    [+0x020] is_valid_        : true
    [+0x028] parsed_          [Type: url::Parsed]
    [+0x070] inner_url_       [Type: scoped_ptr<GURL,std::default_delete<GURL> >]

接着,我们来看一下,当我们在浏览器中输入一个字符的时候,浏览器的一个URL的请求过程,上面的网址就是要请求的URL,“http://suggestion.baidu.com/su?wd=c&action=opensearch&ie=UTF-8”,这是一个http GET命令。Opensearch 字符”c”.
当然,浏览器地址栏的结果数据的提供过程并不是我们讨论的主题,我们是通过这个切入点去详细了解其中一点,http网络资源的加载过程。

源码分析

HttpCache::Transaction::Start

上面我们看到了最后一个函数栈,是一个缓存传输启动的过程,我们从这里开始,已知的一点是我们向启动函数中传递了请求信息,包含了URL和method。

int HttpCache::Transaction::Start(const HttpRequestInfo* request,
                                  const CompletionCallback& callback,
                                  const BoundNetLog& net_log) {
......

  if
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值