WebCore内核本身并不实现http协议,它通过调用不同平台的http库,比如Qt的QnetWorkRequest,gtk的soup,或者curl等,来实现http协议的功能。这里将以curl为例,来理解webcore中的请求信息维护。
http协议的细节,如果希望深入了解的话,可以参考rfc2616,rfc2617。简单介绍下它的原理,http协议遵循的是一个请求à响应的机制。 也就是说,一个url,对应一个请求à响应链。而在网页中,任何资源对应的都是一个url。如果客户端想从服务器端申请一个资源,需要发起一个请 求,http的请求格式是纯文本格式,如下是一个简单的例子:
Get /index.html HTTP/1.1
Accept: text/html,*/*
User-Agent:mozilla/4.0
Host:www.csdn.net
Referer:www.hao123.com
Connection:Keep-Alive
以上是获取http://www.csdn.net/index.html的请求。Accept,User-Agent,Host,Referer,Connection都是请求头部的字段。
Csdn在收到这样一个请求以后,如果它的服务器上确实存在test.png这个资源,则返回http响应如下
HTTP/1.1 200 OK
Content-Length: 862
Date: Tue, 12 Oct 2010 06:21:46 GMT
Content-Type: text/html
ETag: "b59305a7-35e-484b91e27e9ec"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=gb2312">
<title>csdn.net,中国领先的it技术社区</title>
</head>
<body>
…………………………….
</body>
</html>
这样,一个http请求就完成了,流程非常简单明了,所以在互联网上使用特别广泛。由于只是一个简单的请求à响应机制,所以http是没有状态这 一个说法的(这同大部分协议基于状态机的机制是不同的),当然,为了在某些情况下,维护一个状态,http加入了cookie的管理机制,利用 cookie来实现了一些状态的管理。另外,为了节约网络流量,提高性能,http协议中定义了cache的机制。
http的协议细节实现并不需要WebCore来关注,WebCore要关注的是,如何设置请求的相关头部信息,如何获取服务器返回回来的响应体部数据。
WebKit中同http打交道的类主要是ResourceRequest,ResourceResonse,ResourceHandle*,ResourceHandleManager等,这里先介绍同请求信息维护相关的ResourceRequest.
ResourceRequest类的作用比较好理解,基本上就是维护http请求相关的信息(app或者内核都有可能设置这些信息),然后当 WebCore发起http请求的时候,可以获取这些信息,调用curl的接口设置对应的http请求字段。在这些信息中,最常用到的是url。
ResourceRequest类继承于ResourceRequestBase类,绝大部分功能在ResourceRequestBase类中实现。
一)ResourceRequest构造:构造一个ResourceRequest对象只需要url参数就够了,这是比较简单的一个类,没有维护其它类的对象或者句柄。
ResourceRequest(const String& url);
ResourceRequest(const KURL& url);
二)ResourceRequest对象的创建与维护
1.当用户输入网址,开始一个网页的请求的时候,会调用QwebFrame::load函数,在该函数中,会构造出 ResourceRequest对象,并将这个对象作为一个参数,调用FrameLoader类的load函数,DocumentLoader类中会维护 这个ResourceRequest,在调用MainResourceLoader的load接口的时候,也会把ResourceRequest对象传递 过去,在MainResourceLoader中维护相应的信息。当MainResourceLoader类loadNow接口的时候,又会在创建的 ResourceHandle的内部数据结构成员(ResourceHandleInternal)d中维护ResourceRequest对象。
2.
点击一个链接的时候,也会通过FrameLoader类的urlSelected发出一个新的请求,在发起请求的时候构造出 ResourceRequest对象。同样也会在DocumentLoader、MainResourceLoader和ResourceHandle类 中都维护ResourceRequest对象。
3.
根据资源的种类,除了1和2,请求还可以分为子桢请求(如iframe标签),Css请求,Script请求,Image请求,Object请 求,Media请求,Worker请求(HTML5),Prefetch请求等,参考ResourceRequestBase类中的TargetType 枚举。
4.
ResourceHandleManager(/curl)类的initializeHandle函数中,会通过ResourceHandle类 来访问ResourceRequest对象,获取之前设置过的ResourceRequest的信息(比如url,method,user- agent,referer等),调用curl_easy_setopt接口,设置到curl里面。
5.FrameLoader
类的addExtraFieldsToRequest接口会设置一些请求头的信息。
6.DocumentLoader
对应的请求是不停地在变化的(比如发生重定向),所以结构中维护了多个ResourceRequest对象,这些对象可能不一样
三)其它
在这个类中,还可以通过cachePolicy,setCachePolicy,allowCookies,setAllowCookies在WebKit和http之间建立起控制的通道