浏览器探究——webkit部分——http请求
执行加载一个页面时,BrowserFrame的loadUrl会通过jni调用到WebCoreFrameBridge.cpp的LoadUrl中。Java层的BrowserFrame对应的是c层的WebCore::Frame
WebCoreFrameBridge::LoadUrl
这个函数会通过参数获取到url并用url创建一个WebCore::KURL。这个类其实就是对url的一个封装,可以通过该类对url的一些信息做分离。
之后创建了关键的类对象WebCore::ResourceRequest request(kurl);
ResourceRequest
这个类就是对Http请求的一个抽象的封装。这个类集成自ResourceRequestBase。在android上ResourceRequest本身没有实现什么新的函数,其主要工作都在ResourceRequestBase上。ResourceRequest主要用于针对特殊的平台添加某些特殊的数据信息和接口。可以看到webkit中有多个ResourceRequest.h,都是针对各个相应平台的,但是ResourceRequestBase是唯一的,提供了公共的数据结构和接口。
ResourceRequestBase
该了包含了一个http请求所需要的各种数据信息。一些头的key-value信息存在HTTPHeaderMap m_httpHeaderFields;成员变量中。
另外这里定义了几个枚举值
enum ResourceRequestCachePolicy {
UseProtocolCachePolicy, // normal load
ReloadIgnoringCacheData, // reload
ReturnCacheDataElseLoad, // back/forward or encoding change - allowstale data
ReturnCacheDataDontLoad //results of a post - allow stale data and only use cache
};
这些枚举值用于定义该请求的一个Policy,或者可以说是一个类型,标识该请求是出于什么原因发出的。
在创建出ResourceRequest后,会判断下调用LoadUrl时是否设置了一些扩展的Header信息,如果有则把这些信息设置进ResourceRequest中。这些扩展信息就是一些key-value的对,存他们的位置就是上述的HTTPHeaderMap m_httpHeaderFields中。这样一个Http请求(ResourceRequest)就准备好了。
此时我们有了一个Frame还有一个ResourceRequest。
现在需要看下Frame里面如何利用这个ResourceRequest。Frame有个成员mutable FrameLoader m_loader;
FrameLoader
看名字就知道是为Frame执行Load用的。FrameLoader提供了很多跟加载相关的接口,另外有一个FrameLoadType枚举类型用于标识FrameLoader的类型。在Frame的构造时会同时创建它的FrameLoader成员,在Frame::init时也会执行FrameLoader::init。可见FrameLoader是Frame与生俱来的重要成员。但是注意FrameLoader没有ResourceRequest类型的成员,即它本身也不维护ResourceRequest。
在刚才的WebCoreFrameBridge::LoadUrl最后通过Frame找到它的FrameLoader,然后执行FrameLoader::load,并把ResourceRequest传给它。
FrameLoader::load
刚开始先对这个FrameLoader设置下类型,把类型设置成标准的。
之后会创建一个DocumentLoader,创建时会把ResourceRequest传入。
DocumentLoader
DocumentLoader会执行网络请求,下载资源的操作。在DocumentLoader中终于看到了ResourceRequest的成员,并且还不止一个。
// A reference to actual request used to create the data source.
// This should only be used by the resourceLoadDelegate's
// identifierForInitialRequest:fromDatasource: method. It is
// not guaranteed to remain unchanged, as requests are mutable.
ResourceRequest m_originalRequest;
// A copy of the original request used to create the data source.
// We have to copy the request because requests are mutable.
ResourceRequest m_originalRequestCopy;
// The 'working' request. It may be mutated
// several times from the original request to include additional
// headers, cookie information, canonicalization and redirects.
ResourceRequest m_request;
// The last request that we checked click policy for - kept around
// so we can avoid asking again needlessly.
ResourceRequest m_lastCheckedRequest;
这里额外先看下ResourceResponse在DocumentLoader中的情况
ResourceResponse m_response;
// We retain all the received responses so we can play back the
// WebResourceLoadDelegate messages if the item is loaded from the
// page cache.
ResponseVector m_responses;
一个html帧对应于一个DocumentLoader,而一个html帧中,会有一个html资源,多个派生资源(image,css,object等),所以每个DocumentLoader维护一个m_response,对应于html资源,维护一个ResourceResponse数组(ResponseVector m_responses),对应于派生资源(Subresour