Http简介

HTTP协议的定义

Wen的应用层协议就是超文本传输协议,即HTTP。HTTP由两个程序实现:客户程序和服务器程序。这两个程序运行在不同的端系统的进程中,他们通过HTTP协议进行会话。下面是一些Web术语:

  • Web页面:由一个或多个对象组成,也称为文档
  • 对象:一个对象就是一个文件,比如:html文件、jpg图片或者一个Java小程序,他们可以通过一个url地址寻找
  • Web浏览器:实现了Http的客户端
  • 服务器:实现了Http的服务器端,它用于存储Web对象,每个对象可通过url寻址,主流的Web服务器有Apache和Microsoft Internet Informaton Server

HTTP定义了Web客户端向Web服务器请求Web页面的方式(HTTP请求),以及服务器向客户端传送Web页面的方式(HTTP响应)。如图:
image.png
HTTP使用TCP作为它的支撑运输协议(而不是在UDP上运行),HTTP客户首先发起一个与服务器的TCP连接,一旦连接建立,该浏览器和服务器进程就可以通过套接字接口访问TCP。

注意点

下面是HTTP协议的一些注意点:

  • 客户向它的套接字接口发送HTTP请求报文并从它的套接字接口接收HTTP响应报文;服务器从它的套接字接口接收HTTP请求报文和向它的套接字接口发送HTTP响应报文。
  • 一旦客户向它的套接字接口发送了一个请求报文,该报文就脱离了客户控制并进入TCP的控制;一旦服务器向它的套接字发送了一个响应报文,改报文同样也就脱离服务器的控制进入到TCP的控制。
  • HTTP协议使用的是TCP服务而不是UDP服务,因此HTTP报文不用担心数据丢失,也不关注TCP从网络的数据丢失和乱序故障中恢复的细节
  • HTTP服务器并不会主动保存客户端的状态信息,即HTTP是一个无状态协议

    说明: 客户端的套接字接口是客户进程与TCP连接之间的门,在服务器端的套接字接口则是服务器进程与TCP连接之间的门

用户与服务器的交互:cookie

HTTP服务器是无状态的,这简化了服务器的设计,并且允许工程师们去开发可以同时处理数以千计的TCP连接的高性能Web服务器。然而一个Web站点通常希望能够识别用户,可能是因为服务器希望限制用户的访问,或者因为它希望把内容与用户身份联系起来。为此,HTTP使用了 cookie。cookie技术有四个组件:
①在HTTP响应报文中的一个cookie首部行;
②在HTTP请求报文中的一个cookie首部行;
③在用户端系统中保留有一个cookie文件,并由用户的浏览器进行管理;
④位于Web站点的一个后端数据库。
下面是用户和服务器使用cookie交互的流程图:
image.png

HHTP的非持续链接和持续连接

客户端和服务器如果使用TCP连接进行交互,二者交互会有许多请求,开发者就需要决定这些请求是使用一个TCP连接还是使用多个TCP连接。即每个请求/响应是经过一个单独的TCP连接,还是所有的请求及响应都经过相同的TCP连接,前者就是非持续连接,而后者就是持续连接。但是,值得注意的是:HTTP默认使用的是持续连接,当前HHTP客户和服务器也可以配置成使用非持续连接。

使用非持续连接的HTTP

假设在浏览器访问:http://www. someSchool. edu/someDepartment/home.index,假设访问的对象是一个html文件,这个文件里面还包括10张JPEG图片,就会发生下面步骤:

  1. HTTP客户进程在端口号80发起一个到服务器www. someSchool. edu的TCP连接,该端口号是HTTP的默认端口,在客户和服务器上分别有一个套接字与该连接相关联。
  2. HTTP客户经它的套接字向该服务器发送一个HTTP请求报文,在这个请求报文中包含了路径名/someDepartment/home.index
  3. HTTP服务器进程经它的套接字接收该请求报文,从其存储器(RAM或磁盘)中检索出对象 www. someSchool. edu/someDepartment/home. index,在一个 HTTP 响应报文中封装对象,并通过其套接字向客户发送响应报文。
  4. HTTP服务器进程通知TCP断开该TCP连接,但是直到TCP确认客户已经完整地收到响应报文为止,它才会实际中断连接
  5. HTTP客户接收响应报文,TCP连接关闭。该报文指岀封装的对象是一个HTML文件,客户从响应报文中提取出该文件,检査该HTML文件,得到对10个JPEG图形的引用
  6. 对每个引用的JPEG图形对象重复前4个步骤

image.png
一次HTTP从请求到响应的总用时间就是两次RTT(往返时间)加上传输文件的时间。当前非持续连接有一些缺点,主要是一下两点:

  • 必须为每一个请求的对象建立和维护一个全新的连接。对于每个这样的连接,在客户和服务器中都要分配TCP的缓冲区和保持TCP变量,这给Web服务器带来了严重的负担,因为一台Web服务器可能同时服务于数以百计不同的客户的请求
  • 每一个对象经受两倍RTT的交付时延,即一个RTT用于创建TCP,另一个RTT用于请求和接收一个对象

    采用持续连接的HHTP

    在采用HTTP 1.1持续连接的情况下,服务器在发送响应后保持该TCP连接打开。在相同的客户与服务器之间,后续的请求和响应报文能够通过相同的连接进行传送。特别是,一个完整的Web页面(上例中的HTML基本文件加上10个图形)可以用单个持续TCP连接进行传送。更有甚者,位于同一台服务器的多个Web页面在从该服务器发送给同一个客户时,可以在单个持续TCP连接上进行。对象的这些请求可以一个接一个地发出,而不必等待对未决请求(流水线)的回答。一般来说,如果一条连接经过一定时间间隔(一个可配置的超时间隔)仍未被使用,HTTP服务器就关闭该连接,HTTP的默认模式是使用带流水线的持续连接。

    HTTP报文格式

    HTTP请求报文

    image.png
    上面就是一个HTTP请求报文,报文时普通的ASCII文本写的,上述报文分为5行,每一行由一个回车和换行符结束。其中,第一行叫做请求行,其后续的行叫做首部行,首部行后面会有一个空行,而空行后面就是实体体,它是用来请求体的,当然这个例子没有体现出来,下面是HTTP请求报文的通用格式:
    image.png

    请求行

    请求行有三个字段:方法字段、URL字段和HTTP版本字段,他们之间用一个空格隔开。

    方法字段

    其中方法字段主要有:GET、POST、HEAD、PUT和DELETE。

  • GET:主要用于请求获取服务器的对象到客户端

  • POST:主要用于向服务器请求带参数(如表单参数)的对象,即请求的对象依赖用户的参数
  • HEAD:将会用一个HHTP报文进行响应,但是并不会返回请求对象,通常用于开发者调试应用
  • PUT:主要用于用户上传对象到指定的Web服务器
  • DELETE:主要用于客户端删除服务器上的对象

    URL字段

    URL字段就是请求服务器对象的唯一标识符,上面的“/somedir/page. html”就是URL字段。

    HTTP版本字段

    HTTP版本字段是自解释的,在本例中,,浏览器实现的是HTTP/1. 1版本

    首部行

  • Host: 首部行www. someschool. edu指明了对象所在的主机

  • Connection: close首部行,该浏览器告诉服务器不要麻烦地使用持续连接,它要求服务器在发送完被请求的对象后就关闭这条连接
  • User-agent:首部行用来指明用户代理,即向服务器发送请求的浏览器的类型,这里浏览器类型是Mozilla/5.0,即Firefox浏览器
  • Accept-language首部行:表示用户想得到该对象的法语版本(如果服务器中有这样的对象的话);否则,服务器应当发送它的默认版本

可以看到,首部行(也称请求头)就是用来描述客户端和服务器的相关信息、该次请求的相关信息。

实体体

实体体也称为请求体,使用GET方法时实体体为空,而使用POST方法时才使用该实体体。当用户提交表单时,HTTP客户常常使用POST方法,例如: 当用户向搜索引擎提供搜索关键词时。使用POST报文时,用户仍可以向服务器请求一个Web页面,但Web页面的特定内容依赖于用户在表单字段中输入的内容。如果方法字段的值为POST时,则实体体中包含的就是用户在表单字段中的输入值。 当然,用表单生成的请求报文不是必须使用POST方法,HTML表单也经常使用GET方法,并在(表单字段中)所请求的URL中包括输入的数据。

注意: GET请求的参数携带在URL中并不是说GET请求的请求体不为空,其实GET请求的请求体还是空的,即参数不放在实体体里面。其实GET请求并不是说不可以具体实体体,而是Web服务器不会接收GET请求的实体体,因此GET的实体体通常为置为空。

HTTP响应报文

image.png
HTTP响应报文也是一样,第一行叫做状态行,后面的几行叫做首部行,也称为响应头,空行后面的就是实体体了,也叫做响应体。下面时HTTP通用报文格式:
image.png

状态行

状态行具有三个字段:协议版本字段、状态码和相应状态信息。

协议版本字段

上例中的协议版本就是HTTP/1.1

状态码和状态信息

上例中的状态码是200,标识请求成功,下面是一些常见的状态码和对应的状态信息:

  • 200 0K:请求成功,信息在返回的响应报文中。
  • 301 Moved Permanently:请求的对象已经被永久转移了,新的URL定义在响应报文的Location 首部行中,客户软件将自动获取新的URL。
  • 400 Bad Request:一个通用差错代码,指示该请求不能被服务器理解。
  • 404 Not Found:被请求的文档不在服务器上。
  • 505 HTTP Version Not Supported:服务器不支持请求报文使用的HTTP协议版本。

    首部行

    HTTP响应报文的首部行一样,用于描述报文的一些状态,如:

  • Server:首部行指示该报文是由一台Apache Web服务器产生的

  • Last-Modified:首部行指示了对象创建或者最后修改的日期和时间
  • Content-Length: 首部行指示了被发送对象中(实体体)的字节数
  • Content-Type:首部行指示了实体体中的对象是HTML文本

    实体体

    实体体就是客户端请求的对象了,这个例子中返回的就是一个html文本对象。

    Web缓存器

    简介

    Web缓存器(Web cache)也叫代理服务器(proxy server),它是能够代表初始Web服务器来满足HTTP请求的网络实体。Web缓存器有自己的磁盘存储空间,并在存储空间中保存最近请求过的对象的副本。如图,可以配置用户的浏览器,使得用户的所有HTTP请求首先指向Web缓存器。一旦某浏览器被配置,每个对某对象的浏览器请求首先被定向到该Web缓存器。
    image.png
    假设浏览器正在请求对象 http://www. someschool. edu/campus.gif,将会发生如下情况:
  1. 浏览器创建一个到Web缓存器客户初始服务器的TCP连接,并向Web缓存器中的对象发送一个HTTP请求
  2. Web缓存器进行检查,看看本地是否存储了该对象副本,如果有,Web缓存器就向客户浏览器用HTTP响应报文返回该对象
  3. 如果Web缓存器中没有该对象,它就打开一个与该对象的初始服务器(即要请求的www. someschool. edu)的TCP连接。Web缓存器则在这个缓存器到服务器的TCP连接上发送一个对该对象的HTTP请求,在收到该请求后,初始服务器向该Web缓存器发送具有该对象的HTTP响应。
  4. 当Web缓存器接收到该对象时,它在本地存储空间存储一份副本,并向客户的浏览器用HTTP响应报文发送该副本(通过现有的客户浏览器和Web缓存器之间的TCP连接)

    注意: Web缓存器既是服务器又是客户,当它接收浏览器的请求并发回响应时,它是一个服务器。当它向初始服务器发出请求并接收响应时,它是一个客户

在因特网上面部署Web缓存器主要有以下两个好处:

  • Web缓存器可以大大减少对客户请求的响应时间,特别是当客户与初始服务器之间的瓶颈带宽远低于客户与Web缓存器之间的瓶颈带宽时
  • Web缓存器能够大大减少一个机构的接入链路到因特网的通信量,从而从整体上大大减低因特网上的Web流量,改善接入因特网的应用的性能

image.png

条件GET方法

接入Web缓存器,带来了很多好处,同时也会暴露一些问题,那就是缓存一致性的问题:存放在Web缓存器中的对象是一个旧的对象。为了解决这个问题,HTTP提供了条件GE方法:

  • 请求报文使用GET方法
  • 请求报文中包含一个“If Modified-Since”首部行

满足上述两个条件就是一个条件GET方法,举个例子:

  1. 代理缓存器(proxy cache)代表一个请求浏览器,向某Web服务器发送一个请求报文:

image.png

  1. 该Web服务器向缓存器发送具有被请求的对象的响应报文:

image.png

  1. 该缓存器在将对象转发到请求的浏览器的同时,也在本地缓存了该对象。重要的是,缓存器在存储该对象时也存储了最后修改日期。最后,一个星期后,另一个用户经过该缓存器请求同一个对象,该对象仍在这个缓存器中。由于在过去的一个星期中位于Web服务器上的该对象可能已经被修改了,该缓存器通过发送一个条件GET执行最新检查。具体来说,该缓存器发送:

image.png

  1. 值得注意的是If Modified-Since:首部行的值正好等于一星期前服务器发送的响应报文。如果改对象没有被修改,那么缓存器的对象可以给浏览器,并且本次请求也不会返回对象;如果对象被修改了,那么就会返回新的对象到Web缓存器,然后更新这个对象,在传给浏览器

    说明: 其实就是根据Web缓存器中的对象的最后修改时间和Web服务器是对象的最近修改时间进行比对,这样就可以知道Web缓存器上的对象是不是最新的对象。