应用层协议之Web和HTTP
一、HTTP概况
Web的应用层协议是超文本传输协议,它是Web的核心。HTTP有连个程序实现:一个客户程序和一个服务器程序。客户程序和服务器程序运行在不同的端系统,通过交换HTTP报文进行会话。
Web页面(也叫文档)是由对象组成的。一个对象只是一个文件(如HTML文件、JPEG图形、视频片段等等),并且他们可以通过一个URL地址寻址。每个URL地址由两个部分组成:存放对象的服务器主机名和对象的路径名。例如,URL地址:http://www.somSchool.com.edu/somDepartment/picture.gif,其中www.somSchool.com.edu就是服务器主机名,/somDepartment/picture.gif就是路径名。Web浏览器实现了HTTP的客户端,WEB服务器实现了HTTP的服务器端。
HTPP定义了Web客户端向Web服务器请求WEb页面的方式,以及服务器向客户传送Web页面的方式。值得注意的是HTTP使用了TCP作为它的支撑运输协议(而不是在UDP上运行)
HTTP客户首先发起一个与服务器的TCP连接。一旦连接建立,该浏览器和服务器进程就可以通过套接字接口访问TCP了。客户段的套接字是客户进程与TCP连接之间的门,在服务器端的套接字是服务器进程与TCP连接之间的门。因为TCP为HTTP提供可靠地数据传输服务,这意味着一个客户进程发送的每一个HTTP请求报文最终能完整的到达服务器;类似的服务器进程发出的每一个HTTP响应报文最终也能完整地到达客户。在这过程中,HTTP协议不用担心数据的丢失,也不用关注TCP从网络的数据丢失和乱序故障中恢复的具体细节。那是TCP以及协议栈较低层协议的工作。
注意下列现象很重要:服务器向客户发送被请求的文件。而不存储任何关于该客户的状态信息加入某个特定的客户在短短的几秒钟内两次请求同一个对象,服务器不会因为刚刚为该客户提供了该队形就不再做出反应了,而是重新发送该对象。因为HTTP服务器并不保存关于客户的任何信息,所以我们说HTTP是一个无状态协议。
二、非持续连接和持续连接
在许多因特网应用程序中,客户和服务器在一个相当长时间范围内通信,其中客户发出一系列请求并且服务器对每一个请求进行响应。依据应用程序以及应用程序的使用方式,这一系列的请求可以以规定的间隔周期性地或者间断性地一个接一个发出。当这种客户--服务器的交互式经TCP进行的,应用程序的研发者就需要做一个重要的决定,即每一个请求/响应对是经过一个单独的TP连接发送的,还是所有的请求及其响应经相同的TCP连接发送的?采用前者,该应用程序就被称为使用非持续连接。采用后者,该应用程序就被称为持续连接
三、HTTP报文格式
HTTP请求报文有两种:请求报文和响应报文
1.HTTP请求报文:
下面为一个典型的HTTP请求报文:
GET /somedir/page.html HTTP/1.1
Host: www.someschool.edu
Connection: close
User-agent: Mozilla/5.0
Accept-language: fr
HTTP请求报文的第一行叫做请求行,其后继的行叫做首部行。
请求行:请求行有三个字段:方法字段,URL字段和HTTP版本字段。方法字段可以区集中不同的值,包括get,post,head,put和delete。绝大多数HTTP请求报文使用get方法;URL字段带有请求对象的标识,在本例子中该浏览器正在请求对象/somedir/page.html;HTTP版本字段是自解释的,本例子中浏览器实现的是HTTP/1.1版本。
首部行:
1.Host: www.someschool.edu指明了对象所在位置的主机;
2.Connection: close指明该浏览器告诉服务器不希望使用持续连接,他要求服务器在发送完被请求的对象后就关闭这条连接。
3.User-agent: Mozilla/5.0指明了用户代理,即说明了向服务器发送请求的浏览器的类型,在本里中浏览器的类型为 Mozilla/5.0(即Firefox浏览器)
4.Accept-language: fr指明了用户想要得到该对象的语言版本,在本例子中为法语版本(若不存在者版本,服务器应当发送它的默认版本)
(请求斑纹的通用格式不进行详细的说明)
1.HTTP响应报文:
下面为一个典型的HTTP请求报文:
HTTP/1.1 200 OK
Connection: close
Date: Tue,09 Aug 2011 15:44:04 RMT
Server: Apache/2.2.3 (Centos)
Last-Modified: Tue, 09 Aug 2011 15:11:03 GMT
Content_Length: 6821
Content-Type: text/html
(data data data data data .................)
仔细看一下这个响应报文,他有三个部分组成:一个初始状态行,六个首部行,然后是实体体,实体体部分是报文的主要部分,即它包含了请求的对象的本身。
状态行:包货了三个字段:协议版本字段、状态码和相应的状态信息;
首部行:
1.Connection: close告诉客户,发送完报文知乎将关闭该TCP连接
2.Date:指明服务器产生并发送该响应报文的日期和时间
3.Server: Apache/2.2.3 (Centos)指明了该报文是有一台Apache Web服务器产生的
4.Last-Modified:指明了对象创建或者最后修改的日期和时间,与代理服务器(也叫缓存服务器)有关
5.Content_Length: 6821指明了被发送的对象中的字节数
6.Content-Type: text/html指明了实体中的对象的类型,在本例子中实体对象是HTML文本
(HTTP响应报文的通用格式不详细说明)
四、用户与服务器的交互:cookie
前面提到HTTP服务器是无状态的,但由于种种的需要往往一个Web站点希望能识别用户。为此,HTTP使用了cookie,它允许站点对用户的跟踪。目前大多数商务Web站点都使用了cookie。
cookie技术的4个组件:
1.在HTTP响应报文中的一个cookie首部行;
2.在HTTP请求报文中的一个cookie首部行;
3.在用户端系统中保留一个cookie文件,并由用户的浏览器进行管理;
4.位于Web站点后端的一个cook后端数据库
我们通过一个典型的例子看看cookie的工作过程,假设Sam总是从家中的PC使用IE上网,它首次访问Amazon.com并假定它应经访问过taobao.com。当请求报文到达Amazon Web服务器时,,该服务器会产生一个唯一的识别码,并以此作为索引在它的后端数据库中产生一个表项。接下来Amazon Web服务器会用一个包含Set-cookie首部的HTTP响应报文对Susan的浏览器进行响应。当Sam的浏览器收到该响应报文时,它会看到Set-cookie:首部,该浏览器会在它管理的cookie文件中新添一行,该行包括服务器的主机名和Set_cookie:首部的识别码。值得注意的是该cookie文件中已经用于taobao.com的表项,因为Sam已经访问过该站点。当Sam继续浏览Amazon站点的是,每请求一个Web页面,该浏览器都会在cookie文件中找到它对这个网站的识别码,并把它放到HTTP请求报文中包括识别码的cookie首部行中。如果Sam过一段时间(如几个星期)再访问Amazon.com站点,她的浏览器会在其的HTTP请求报文中继续放入特定的首部行cookie。通过这样的方式实现了Web站点对用户在站点中的活动的跟踪。
五、WEB缓存
Web缓存器也叫代理服务器,它是能够代替初始Web服务器来满足HTTP请求的网络实体。Web缓存服务器有自己的磁盘存储空间,并在存储空间中保存最近请求多的对象的副本。下面用一个例子说明Web缓存服务器的工作过程:假设浏览器正在请求对象http://www.someschool.edu/campus.gif,将会发生如下情况:
1.浏览器建立一个到Web缓存器的TCP连接,并向Web缓存器中的对象发送一个HTTP请求。
2.Web接受到HTTP请求报文时进行检查,看看本地是否存储了该对象副本。如果有则Web服务器就向客户浏览器用HTTP响应报文返回该对象。
3.如果Web缓存器中没有该对象,他就打开一个与该对象的初始服务器的TCP连接。Web缓存器则在这个缓存器到服务器的TCP连接上发送一个对该对象的HTTP请求报文。在收到该请求后,初始服务器想改Web缓存器发送具有该对象的HTTP响应报文。
4.当Web缓存器收到该对象时,它在本地存储空间存储一份副本,并向客户的浏览器用HTTP响应报文发送该副本(通过现有的客户浏览器和Web缓存器之间的TCP连接)。
值得注意的是Web缓存器既是服务器又是客户。
六、条件get方法
尽管高速缓存能减少用户感受到的响应时间,但是也引入了一个新的问题,即存放在缓存器中的对象副本可能是陈旧的。换句话说,保存在服务器中的对象自该副本缓存在客户上以后可能已经被修改了。幸运的是,HTTP协议有一机制允许缓存器证实它的对象是最新的,这种机制是条件GET方法。如果:1.请求报文使用了GET方法,并且2.请求报文中包含了一个“If-Modified-Since:”首部行,那么这个HTTP请求报文就是一个条件GET请求报文。看下面的例子:
首先一个代理服务器代表一个请求浏览器,向某Web服务器发送一个请求报文,然后Web服务器向缓存器发送具有被请求的对象的响应报文,在该响应报文中包括了首部行:1.Date:(该首部行记录了Web服务器向缓存器产生并发送该响应报文时的日期和时间)2.Last-Modified:(该首部行记录了该对象被创建或者最后被修改的日期和时间)。该缓存器接受到该响应报文后会将对象转发到浏览器的同时也在本地缓存了该对象。重要的是缓存器在存储该对象的同时也存储了最后的修改时间(即Last-Modified首部行的时间,此处我们暂且私自将它记为T)。最若干时间后,某一个浏览器经过该缓存器请求同一对象,虽然该对象仍然存在于缓存器中,但是位于Web服务器中的该对象很可能已经被修改了。改缓存器会通过发送一个一条件GET执行最新检查。具体来说,该缓存器会向Web服务器发送包含首部行“If-Modified-Since:T”的请求报文 ,该条件GET方法告诉Web服务器,仅当自指定日期(T)之后该对象被修改过才发送该对象。若带对象在T之后没有被修改过,Web服务器仍然会发送一个响应报文,但值得注意的是该响应报文中不包含所请求的对象。还有一点是此时该响应报文中的状态行为“304 Not Modified”,它告诉缓存器可以使用该对象,能向请求的浏览器转发它(代理服务器)中的该对象的副本。