读书笔记_图解HTTP(三) Web服务器以及http首部

读《图解HTTP》记录

上一篇 读书笔记_图解HTTP(二) 简单HTTP协议及HTTP报文内的HTTP信息

web服务器

http通信时,除了客户端和服务器之外,还有一些用于通信数据转发的程序,例如代理、网关、隧道。它们可以配合服务器工作。
这些应用程序和服务器可以将请求转发给通信线路上的下一站服务器,并且能接收从那台服务器发送的响应再转发给客户端。

代理

代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色,接收客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。

代理服务器的基本行为就是接收客户端的请求后转发给其他服务器。代理不改变请求的URI,会直接发送给前方持有资源的目标服务器。
持有资源实体的源服务器返回的响应经过代理服务器再传给客户端。

代理服务器

使用代理服务器的理由:利用缓存技术减少网络带宽的流量,组织内部针对特定网站的访问控制等

代理的分类

代理有多种使用方法,按两种基准分类。一是 是否使用缓存,另一种是 是否会修改报文。

  • 缓存代理
    代理转发响应时,缓存代理会预先将资源的副本保存在代理服务器上。当代理服务再次接收到对相同资源的请求时,就可以不从源服务器那里获取资源,而是将之前缓存的资源作为响应返回。
  • 透明代理
    转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理。反之,对报文内容进行加工的代理被称为非透明代理。

网关

网关是转发其他服务器通信数据的服务器,接收从客户端发来的请求时,他会像自己拥有资源的源服务器一样对请求进行处理。有时客户端可能都不会察觉,自己的通信目标是一个网关。

网关

网关的工作机制和代理十分相似。而网关能使通信线路上的服务器提供非Http协议服务。

利用网关能提升通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。比如,网关可以连接数据库,使用sql语句查询数据。另外,在Web购物网站上进行信用卡结算时,网关可以和信用阿卡结算系统联动。

隧道

隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。

隧道

隧道可按要求建立一条与其他服务器的通信线路,届时使用SSL等加密手段进行通信。隧道的目的是确保客户端能与服务器进行安全的通信。
隧道本身不会去解析HTTP请求。请求将保持原样中转给之后的服务器。隧道会在通信双方断开连接时结束。隧道本身是透明的,客户端不用在意隧道的存在。

保存资源的缓存

缓存是指代理服务器或客户端本地磁盘内保存的资源副本。利用缓存可减少对源服务器的访问,因此节省了通信流量和通信时间。
缓存服务器是代理服务器的一种,并归类在缓存代理类型中。


缓存服务器

缓存服务器会因为客户端的要求、缓存的有效期等因素,向源服务器确认资源的有效性。若判断缓存失效,缓存服务器将会再次从 源服务器上取“新”资源。


缓存的有效期

客户端中同样有缓存,客户端缓存称为临时网络文件。浏览器缓存如果有效,就不必去服务器请求相同资源了,可以直接在本地缓存内读取。
客户端缓存和服务器缓存一样,当判定缓存过期后,会向源服务器确认资源的有效性。如果判断浏览器缓存失效,会再次请求新资源。

客户端缓存

Http首部

通用首部字段

请求报文和响应报文两方都会使用的首部。

首部名称 说明
Cache-Control 控制缓存的行为
Connection 逐跳首部、连接的管理
Date 创建报文的时间日期
Pragma 报文指令
Trailer 报文末端的首部一览
Transfer-Encoding 指定报文主体的传输编码方式
Upgrade 升级为其他协议
Via 代理服务器的相关信息
Warning 错误通知

1、Cache-Control 缓存工作机制

通过指定首部字段Cache-Control的指令,就能操作缓存的工作机制。
指令的参数是可选的,多个指令之间通过“,”分隔。首部字段Cache-Control的指令可用于请求及响应。
例:Cache-Control: private, max-age=0, no-cache

缓存请求指令

指令 参数 说明
no-cache 强制向源服务器再次验证
no-store 不缓存请求或响应的任何内容
max-age=[秒] 必需 响应的最大Age值
max-stale=[秒] 可省略 接收已经过期的响应
min-fresh=[秒] 必需 期望在指定时间内的响应仍有效
no-transform 代理不可更改媒体类型
only-if-cached 从缓存获取资源
cache-extension - 新指令标记(token)

缓存响应指令

指令 参数 说明
public 可向任意方提供响应的缓存
private 可省略 仅限向特定用户返回响应
no-cache 可省略 缓存前必须先确认其有效性
no-store 不缓存请求或响应的任何内容
no-transform 代理不可改变媒体类型
must-revalidate 可缓存当必须向源服务器进行确认
proxy-revalidate 要求中间缓存服务器对缓存的响应有效性再进行确认
max-age=[秒] 必需 响应的最大Age值
s-maxage=[秒] 必需 公共缓存服务器的最大Age值
cache-extension - 新指令标记(token)
表示是否能缓存的命令
  • public 指令
Cache-Control: public

当使用public指令时,则明确表明其他用户也可以利用缓存。

  • private 指令
Cache-Control:private

当指定private指令后,响应只以特定的用户作为对象,这与public指令的行为相反。
缓存服务器会对该特定用户提供资源缓存的服务,对其他用户发送过来的请求,代理服务器则不会返回缓存。

private 指令和public 指令正好相反,举个栗子解释上边的。
我和小A是邻居,我们俩用同一个网关。我喜欢体育,他喜欢音乐。这时候我登录后通过网络去请求数据,返回给我的都是和体育相关的数据。他登录后去网络请求数据,返回的都是音乐相关的数据。这样是正确的,因为这时候服务器返回的缓存指令可能是private,告诉中间的网关,或者缓存服务器不要缓存。但是如果使用public指令,返回的可能缓存过的数据了,这样就是不对的了。

  • no-cache指令


    no-cache
Cache-Control: no-cache

使用no-cache指令的目的是为了防止从缓存中返回过期的资源。
客户端发送的请求中如果包含no-cache指令,则表示客户端将不会接收缓存过的响应。于是,“中间”的缓存服务器必须从客户端请求转发给源服务器。
如果服务器返回的响应中包含no-cache指令,那么缓存服务器不能对资源进行缓存。源服务器以后也将不会再对缓存服务器请求中提出的资源有效性进行确认,且禁止其对响应资源进行缓存操作。

Cache-Control:no-cache=Location

由服务器返回的响应中,如果报文首部字段Cache-control中对no-cache字段名具体指定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存。就是说,无参数值的首部字段可以使用缓存。只能在响应指令中指定该参数。

控制可执行缓存的对象的指令
  • no-store指令
Cache-Control:no-store

使用no-store指令时,暗示请求和响应中包含机密信息。因此,该指令缓存不能在本地存储请求或者响应的任一部分。

指定缓存期限和认证的指令
  • s-maxage 指令
Cache-Control:s-maxage=604800(s)

s-maxage指令的功能和max-age指令的相同,他们的不同点是max-age指令只适用于供多位用户使用的公共缓存服务器。也就是说,对于向同一用户重复返回响应的服务器来说,这个指令没有任何作用。
另外,当使用s-maxage指令后,则直接忽略对Expires首部字段以及max-age指令的处理。

  • max-age 指令


    max-age
Cache-control:max-age=604800(s)

客户端:客户端发送的请求中包含max-age指令,如果判定混村资源的缓存时间数值比指定时间的数值更小,那客户端就接受缓存的资源。另外,当指定max-age值为0,那么缓存服务器通常需要将请求转发给源服务器。
服务器:返回的响应中包含max-age时,缓存服务器将不对资源的有效性再做确认,而max-age的数值代码资源保存为缓存的最大时间。

在http1.1版本中,同时存在Expires首部字段,会优先处理max-age指令,忽略Expires首部字段。http1.0相反,max-age会被忽略掉。

  • min-fresh指令


    min-fresh
Cache-Control: min-fresh=60(单位:秒)

min-fresh 指令要求缓存服务器返回至少还未过指定时间的缓存资源。
比如,当指定min-fresh为60s后,过了60s的资源都无法作为响应返回了。

  • max-stale指令
Cache-Control:max-stale=3600(s)

使用max-stale可指示缓存资源,即使过期也照常接收。
如果指令中未指定参数值,那么无论经过多久,客户端都会接收响应;如果指令中指定了具体数值,那么即使过期,只要仍处于max-stale指定的时间内,仍会被客户端接收。

  • only-if-cached指令
Cache-Control:only-if-cached

使用only-if-cached指令表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。换言之,该指令要求缓存服务器不重新加载响应,也不会再次确认资源有效性。若发生请求缓存服务器的本地缓存无响应,则返回状态码504 Gateway Timeout.

  • must-revalidate 指令
Cache-Control:must-revalidate

代理会向源服务器再次验证即将返回到额相应缓存目前是否仍然有效。
若代理无法连通源服务器再次获取有效资源的话,缓存必须给客户端一条504状态码。
另外,使用该指令会忽略请求的max-stale指令(即使已经在首部使用了max-stale,也不会再有效果)。

  • proxy-revalidate 指令
Cache-Control:proxy-revalidate

proxy-revalidate 指令要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性。

  • no-transform 指令
Cache-Control:no-transform

使用no-transform指令规定无论是在请求还是响应中,缓存都不能改变实体主体的媒体类型。
这样做可以饭知缓存或代理压缩图片等类似操作。

Cache-Control扩展
  • cache-extension token
Cache-Control:private,community="UCI"

通过cache-extension 标记(token),可以扩展Cache-Control首部字段的指令。
如上例,Cache-Control首部字段本身没有community这个指令。借助extension tokens实现了该指令的添加。如果缓存服务器不能理解community这个新指令,就会直接忽略。因此,extension tokens仅对能理解它的缓存服务器来说是有意义的。

2、Connection

Connection首部字段具备如下两个作用

  • 控制不再转发给代理的首部字段
Connection:不在转发的首部字段名

在客户端发送请求和服务器返回响应内,使用Connection首部字段,可控制不再转发给代理的首部字段(即Hop-by-hop首部)。

Connection1
  • 管理持久连接
Connection:close

http1.1版本的默认链接都是持久连接。为此,客户端会在持久连接上连续发送请求。当服务器想明确断开连接时,则指定Connection首部字段的值为Close。


Connection2
Connection:Keep-Alive

http1.1之前的所有http版本默认的连接方式都是非持久连接。为此,如果想在旧版本的http协议上维持 持续连接,则需要指定Connection首部字段的值为Keep-Alive。


Connection

如上图1客户端发送请求给服务器时,服务器会像上图2那样加上首部字段Keep-Alive及首部字段Connection后返回响应。

3、Date

首部字段Date表明创建HTTP报文的日期和时间


Date

Http1.1协议使用在RFC1123中规定的日期时间的格式,如下:

Date:Tue, 03 Jul 2012 04:40:59 GMT

之前的http协议版本中使用在RFC850中定义的格式,如下所示。

Date: Tue, 03-Jul-12 04:40:59 GMT

除此之外,还有一种格式。它与 C 标准库内的 asctime() 函数的输出 格式一致。

Date: Tue Jul 03 04:40:59 2012

4、Pragma

pragma是Http1.1之前版本的历史遗留字段,仅作为与http1.0的向后兼容而定义。规范定义的形式唯一,如下:

Pragma:no-cache

该首部字段属于通用首部字段,但只用在客户端发送请求中。客户端会要求所有的中间服务器不返回缓存的资源。


Pragma

所有的中间服务器如果都能以http1.1为基准,那么直接采用Cache-Control:no-cache指定缓存的处理方式最为理想。但是要整体掌握全部中间服务器使用的http协议版本确实不现实的。要兼容http1.1之前版本。因此,发送的请求会同时含有下面量子首部字段。

Cache-Control:no-cache
Pragma:no-cache

5、Trailer

Trailer

首部字段Trailer会事先说明在报文主体后记录了哪些首部字段。该首部字段可应用在http1.1版本分块传输编码时。

HTTP/1.1 200 OK 
Date: Tue, 03 Jul 2012 04:40:56 GMT 
Content-Type: text/html 
... 
Transfer-Encoding: chunked 
Trailer: Expires 
...(报文主体)... 
0 
Expires: Tue, 28 Sep 2004 23:59:59 GMT 

以上用例中,指定首部字段Trailer的值为Expires,在报文主体之后(分块长度0之后)出现了首部字段Expires。

6、Transfer-Encoding

Transfer-Encoding

首部字段Transfer-Encoding规定了传输报文主体时采用的编码方式。
Http1.1的传输编码方式仅对分块传输编码有效。

HTTP/1.1 200 OK 
Date: Tue, 03 Jul 2012 04:40:56 GMT 
Cache-Control: public, max-age=604800 
Content-Type: text/javascript; charset=utf-8 
Expires: Tue, 10 Jul 2012 04:40:56 GMT 
X-Frame-Options: DENY 
X-XSS-Protection: 1; mode=block 
Content-Encoding: gzip 
Transfer-Encoding: chunked 
Connection: keep-alive 
cf0    ←16进制(10进制为3312) 
...3312字节分块数据... 
392    ←16进制(10进制为914) 
...914字节分块数据... 
0 

以上用例中,在首部字段Transfer-Encoding中指定,有效使用分块传输编码,且分别被分成3312字节和914字节大小的分块数据。

7、Upgrade

首部字段Upgrade用于检测Http协议以及其他协议是否可用于更高版本进行通信,其参数值可以用来指定一个完全不同的通信协议。


Upgrade

上图用例中,首部字段Upgrade指定的值为TLS1.0,请注意此处两个字段首部字段的对应关系,Connection的值被指定为Upgrade。Upgrade首部字段产生作用的Upgrade对象仅限于客户端和邻接服务器之间。因此,使用首部字段Upgrade时,还需要额外指定Connection:Upgrade.
对于附有首部字段Upgrade的请求,服务器可用101 Switching Protocols状态码作为响应返回。

8、Via

使用首部字段Via是为了追踪客户端和服务器之间的请求和响应报文的传输路径。

报文经过代理或者网关时,回现在首部字段Via中附加该服务器的信息,然后再进行转发。这种做法和traceroute及电子邮件的Received首部的工作机制很类似。

首部字段Via不仅用于追踪报文的转发,还可避免请求回环的发生,所以必须在经过代理时附加该首部字段内容。

Via

上图用例中,在经过代理服务器A时,Via首部附加了“1.0 gw。hackr.jp(Squid/3.1)”这样的字符串。行头的1.0是指接收到请求的服务器上应用的Http协议版本。在接下来经过代理服务器B时也是在Via中添加服务器信息。

Via首部是为了追踪传输路径,所以经常会和TRACE方法一起使用。比如,代理服务器接收到TRACE方法发送过来的请求(其中Max-Forwards:0)时,代理服务器就不能再转发该请求了。这种情况下,代理服务器会将自身的信息附加到Via首部后,返回该请求的响应。

9、Warning

Http1.1 的Warning首部是从Http1.0的响应首部(Retry-After)演变过来的。该首部通常会告知用户一些与缓存相关的问题的警告。

Warning : 113 gw.hackr.jp:8080  "Heuristic expiration" Tue, 03 Jul 2012 04:40:56 GMT 

Warning 首部的格式如下。

Warning: [警告码][警告的主机:端口号]“[警告内容]”([日期时间])

Http1.1中定义了7中警告。警告码对应的警告内容仅推荐参考。另外,警告吗具备扩展性,今后有可能追加新的警告码。

  • Http1.1警告码
警告码 警告内容 说明
110 Response is stale(响应已过期) 代理返回已过期的资源
111 Revalidation failed(再验证失败) 代理再验证资源有效性时失败(服务器无法到达等原因)
112 Disconnection operation(断开连接操作) 代理与互联网连接被故意切断
113 Heuristic expiration(试探性过期) 响应的使用期超过24h(有效缓存的设定时间大于24h的情况下)
199 Miscellaneous warning(杂项警告) 任意的警告内容
214 Transformation applied(使用了转换) 代理对内容编码或媒体类型等执行了某些处理时
299 Miscellaneous persistent warning(持久杂乱警告) 任意的警告内容

请求首部字段

请求首部字段是从客户端往服务器端发送请求报文所使用的字段,用于补充请求的附加信息、客户端信息、对相应内容相关的优先级等内容。


请求首部字段
1、Accept
Accept
Accept:text/html,application/xhtml+xml,application/xml

Accept首部字段可通知服务器,用户代理能够处理的媒体类型以及媒体类型的相对优先级。可使用type/subtype这种形式,一次指定多种媒体类型。

例子:

  • 文本文件
text/html,text/plain,text/css...
application/xhtml+xml,application/xml...
  • 图片文件
image/jpeg,image/gif,image/png...
  • 视频文件
video/mpeg,video/quicktime...
  • 应用程序使用的二进制文件
application/octet-stream,application/zip...

比如,如果浏览器不支持PNG图片的显示,那Accpet就不指定image/png,而指定可处理的image/gif和image/jpeg等图片类型。

若想要给显示的媒体类型增加优先级,则使用q=来额外便是权重值,用分号(;)来进行分隔。权重值q的范围是0~1(可精确到小数点后3位),且1为最大值。不指定权重时,默认权重为q=1.0。

2、Accept-Charset
Accept-Charset
Accept-Charset: iso-8859-5, unicode-1-1;q=0.8

Accept-Charset首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性只当多种字符集。与首部字段Accept相同的是可使用权重P值表示相对优先级。
该首部字段应用于内容协商机制的服务器驱动协商。

3、Accept-Encoding
Accept-Encoding
Accept-Encoding:gzip,deflate

Accept-Encoding首部字段用来告知服务器用户代理支持的内容编码以及内容编码的优先级顺序。可一次性指定多种内容编码。
内容编码类型

  • gzip
    由文件压缩程序 gzip(GNU zip)生成的编码格式(RFC1952),采用Lempel-Ziv算法(LZ77)及32位循环冗余校验。
  • compress
    由UNIX文件压缩程序compress生成的编码格式,菜用Lempel-Ziv-Welch算法。
  • deflate
    组合使用zlib格式及由deflate压缩算法生成的编码格式。
  • identity
    不执行压缩或者不会变化的默认编码格式
4、Accept-Language
Accept-Language
Accept-Language:zh-cn,zh;q=0.7,en-us,en;q=0.3

首部字段Accept-Language用来告知服务器用户代理能够处理的自然语言集(指中文或英文等),以及自然语言集的相对优先级。可一次指定多种自然语言集。

和Accept首部字段一样,按权重值q来表示相对优先级。在上述图中,客户端在服务器有中文版资源的情况下,会请求其返回中文版对应的响应,没有中文版时,则请求返回英文版响应。

5、Authorization
Authorization
Authorization:Basic dwxxxxxxxxxxxxxxxxxxxxxxxxx==

首部字段Authorization是用来告知服务器,用户代理的认证信息(证书值).通常,想要通过服务器认证的用户代理会在接收到返回的401状态码响应后,把首部字段Authorization加入到请求中。共用缓存在接收到含有Authorization首部字段的请求时的操作处理会略有差异。

6、Expect
Expect
Expect: 100-continue

客户端使用首部字段Expect来告知服务器,期望出现的某种特定行为。因为服务器无法理解客户端的期望作出回应而发生错误时,则返回状态码417 Expectation Failed。
客户端也可以利用该首部字段,写明所期望的扩展。虽然http1.1规范只定义了100-continue(状态码100 Continue之意)。
等待状态码100响应的客户端在发生请求时,需要指定Expect:100-continue。

7、From
From

首部字段From用来告知服务器使用用户代理的用户的电子邮件地址。通常,其使用目的就是为了显示搜索引擎等用户代理的负责人的电子邮件联系方式。使用代理时,应尽可能包含From首部字段(但可能会因为代理不同,将电子邮件地址记录在User-Agent首部字段内).

8、Host
Host

图:虚拟主机运行在同一ip上,使用Host字段加以区分。

Host:www.hackr.jp
注意:这个字段是用来确定在目标服务器上的子服务器的,不是用来在网络上找主机的。

首部字段Host会告知服务器,请求的资源所处的互联网主机名和端口号。Host首部字段在Http1.1规范内是唯一一个必须包含在请求内的首部字段。

首部字段Host和以单台服务器分配多个域名的虚拟主机的工作机制有很密切的关联,这是首部字段Host必须存在的意义。

请求被发送至服务器时,请求中的主机名会用IP地址直接解决。但如果这时,享用的额IP地址下部署运行着多个域名,那么服务器就会无法理解究竟是哪个域名对应的请求。因此,就需要使用首部字段Host来明确指出请求的主机名。若服务器未设置主机名,那直接发送一个空值即可。如下所示。

Host:
9、If-Match
If-Match1.png

附带条件请求
形如if-xxx这种样式的请求首部字段,都可称为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。

If-Match2.png

图:只有当If-Match的字段值跟ETag值匹配一致时,服务器才会接受请求

If-Match:"123456"

首部字段If-Match,属附带条件之一,他会告知服务器匹配资源所用的实体标记(ETag)值。这时的服务器无法使用弱ETag值。

服务器会对比If-Match的字段值和资源的ETag值,仅当两者一致时,才会执行请求。反之,则返回状态码412 Precondition Failed的响应。
还可以使用星号(*) 指定If-Match的字段值。针对这种情况,服务器将会忽略ETag的值,只要资源存在就处理请求。

10、If-Modified-Since
If-Modified-Since

图:如果在If-Modified-Since字段指定的日期时间之后,资源发生了更新,服务器会接受请求

If-Modified-Since: Thu, 15 Apr 2004 00:00:00 GMT

首部字段 If-Modified-Since,属于附带条件之一,它会告知服务器若If-Modified-Since字段值早于资源的更新时间,则希望能处理该请求。而在指定If-Modified-Since字段值的日期时间之后,如果请求的资源都没有更新,则返回状态码304 Not Modified的响应。

If-Modified-Since用于确认代理或客户端拥有的本地资源的有效性。获取资源的更新日期时间。可通过确认首部字段Last-Modified来确定。

11、If-None-Match
If-None-Match

首部字段If-None-Match属于附带条件之一。它和If-Match作用相反,用于指定If-None-Match字段值的实体标记(ETag)值与请求资源的ETag不一致时,它就告知服务器处理该请求。

在GET或HEAD方法中使用首部字段If-None-Match 可获取最新的资源。因此,这与使用首部字段If-Modified-Since时有些类似。

12、If-Range
If-Range

If-Range属于附带条件之一。它告知服务器若指定的If-Range字段值和请求资源的ETag值或时间相一致时,则作为范围请求处理。反之返回全体资源。

If-Range1

下面我们思考一下不使用首部字段If-Range发送请求的情况。服务器端的资源如果更新,那客户端持有资源中的一部分也会随之无效,当然,范围请求作为前提是无效的。这时,服务器会暂且以无状态码412Precondition Failed作为响应返回,其目的是催促客户端再次发送请求。这样一来,与使用首部字段If-Range比起来,就需要花费两倍的时间。

13、If-Unmodified-Since
If-Unmodified-Since: Thu, 03 Jul 2012 00:00:00 GMT

首部字段If-Unmodified-Since和首部字段If-Modified-Since的作用相反。它用来告知服务器,指定的请求资源止只有在字段值内指定的日期时间之后,未发生更新的情况下,才能处理请求。如果在指定时间日期之后发生了更新,则以412 Precondition Failed 作为响应返回。

14、Max-Forwards

通过TRACE方法或OPTIONS方法,发送包含首部字段Max-Forwards的请求时,该字段以十进制整数形式指定可经过的服务器最大数目。服务器在往下一个服务器转发请求之前,Max-Forwards的值-1后重新赋值。当服务器收到的Max-Forwards的值为0的请求时,则不再进行转发,而是直接返回响应。

Max-Forwards

使用Http协议通信时,请求可能会经过代理等堕胎服务器。途中,如果代理服务器由于某些原因导致请求转发失败,客户端也就等不到服务器的响应了。对此,我们无从可知。

可以灵活使用首部字段Max-Forwards,针对以上问题产生的原因展开调查。由于当Max-Forwards字段值为0时,服务器会立即返回响应,由此,我们至少可以对以那台服务器为终点的传输路径的通信状况有所把握。

Max-Forwards

图:代理服务器B到源服务器的请求失败了,但是客户端不知道


Max-Forwards

图:由于未知原因,导致请求陷入代理之间的循环,但是客户端不知道

15、Proxy-Authorization
Proxy-Authorization:Basic dGlwoxxxxxxxxxxxx

接收到从代理服务器发来的认证质询时,客户端会发送包含首部字段的Proxy-Authorization的请求,以告知服务器认证所需要的信息。
这个行为是与客户端和服务器之间的Http访问认证相类似的,不同之处在于,认证行为发生在客户端与代理服务器之间。客户端与服务器之间的认证,使用首部字段Authorization可起到相同作用。

16、Range
Range: bytes=5001-10000

对于只需获取部分资源的范围请求,包含首部字段Range即可告知服务器资源的指定范围。上面的示例表示请求获取从5001字节至10000字节的资源。

接收到附带Range首部字段请求的服务器,会在处理请求之后返回状态码为206 Partial Content 的响应。无法处理该范围请求时,则会返回状态码200 OK的响应以及全部资源。

17、Referer
Referer
Referer: http://www.hackr.jp/index.html

首部字段Referer会告知服务器请求的原始资源URI。

客户端一般会发送Referer首部字段给服务器。但当直接在浏览器地址栏输入URI,或处于安全性的考虑时,也可以不发送该首部字段。

因为原始资源的URI中查询字符串可能会含有ID和密码等保密信息,要是写进Referer转发给其他服务器,则可能导致保密信息的泄露。

另外,Referer的正确拼写应该是Referrer,但是大家一直沿用这个错误的拼写。

18、TE
TE: gzip,deflate;q=0.5

首部字段TE会告知服务器客户端能处理的传输编码方式以及优先级。他和首部字段Accept-Encoding的功能很像,但是用于传输编码。
首部字段TE除制定传输编码之外,还可以指定伴随trailer字段的分块传输编码的方式。应用后者时,只需要吧trailers赋值给该字段值。

TE:trailers
19、User-Agent
User-Agent

图:User-Agent用于传达浏览器的种类

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko

首部字段User-Agent会创建请求的浏览器和用户代理名称等信息传递给服务器。
由网络爬虫发起请求时,有可能会在字段内添加爬虫者的电子邮箱地址。此外,如果请求经过代理,那么中安静也可能背添加代理服务器的名称。

响应首部字段

响应首部字段是由服务器端向客户端返回响应报文中使用的字段,用于补充响应的附加信息、服务器信息,以及对客户端的附加请求等信息。

1、Accept-Ranges
Accept-Ranges
Accept-Ranges:bytes

首部字段Accept-Ranges 是用来告知客户端,服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。
可指定的字段值有两种,可处理范围请求时指定位bytes,反之则指定为none。

2、Age
Age
Age:600

首部字段Age能告知客户端,源服务器在多久前创建了响应。字段值单位为秒。

若创建该响应的服务器是缓存服务器,Age值是指缓存后响应再次发起认证到认证完成的时间值。代理创建响应时必须加上首部字段Age。

3、ETag
ETag
ETag:"82e22293907ce725faf67773957acd12"

首部字段ETag能告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每一份资源分配对应的ETag值。
另外,当资源更新时,ETag值也需要更新。生成ETag值时,并没有统一的算法规则,而仅仅是由服务器来分配。

ETag

资源被缓存时,就会被分配唯一性标识。例如,当使用中文版浏览器访问时,就会返回中文版对应的资源,而使用英文版的浏览器访问时,则会返回英文版对应的资源。两者的URI相同,所以仅凭URI指定缓存的资源是相当困难的。若在下载过程中出现中断、再连接的情况,都会依照ETag值来指定资源。

  • 强ETag值和弱ETag值
    强ETag值,不论实体发生多么细微的变化,都会改变其值。
ETag:"usagi-1234"

弱ETag值
弱ETag值只会用于提示资源是否相同。只有资源发生了根本变化,产生差异时才会改变ETag值。这时,会在字段值最开始处附加W/.

ETag: W/"usagi-1234"
4、Location
Location
Location:http://www.xxxx.xx/index.html

使用首部字段Location可以将响应接收方经导至某个与请求URI位置不同的资源。
基本上,该字段会配合3xx:Redirection的响应,提供重定向的URI。
几乎所有的浏览器在接收到包含首部字段Location的响应后,都会强制性地尝试对已提示的重定向资源的访问。

5、Proxy-Authenticate
Proxy-Authenticate: Base realm="Usagidesign Auth"

首部字段Proxy-Authenticate会把代理服务器所要求的认证信息发送给客户端。
它与客户端和服务器之间的Http访问认证的行为相似,不同之处在于其认证行为是客户端和代理服务器之间进行的。而客户端与服务器之间进行认证时,首部字段WWW-Authorization有着相同的作用。

6、Retry-After
Retry-After
Retry-After:120

首部字段Retry-Afer告知客户端应该在多久之后再次发送请求。主要配合状态码503 Service Unavailable响应,或者3xx Redirect响应一起使用。
字段值可以指定为具体日期时间(Wed, 04 Jul 2012 06:34:24 GMT 等格式)或者创建响应后的秒数。

7、Server
server
Server:Apache/2.2.17(Unix)

首部字段Server会告知客户端当前服务器上安装的Http服务器应用程序的信息。不单单会标出服务器上的软件应用名称,还有可能包含版本号和安装时启动的可选项。

Server:Apache/2.2.6(Unix) PHP/5.2.5
8、Vary
Vary

图:当代理服务器接收到带有Vary首部字段指定获取资源的请求时,如果使用的Accept-Language字段的值相同,那么就直接从缓存返回响应。反之,则需要先从源服务器端获取资源后才能作为响应返回。

Vary:Accept-Language

首部字段Vary可对缓存进行控制。源服务器会向代理服务器传达关于本地缓存使用方法的命令。

从代理服务器接收到源服务器返回包含Vary指定项的响应后,若再进行缓存,仅对请求中含有Vary指定首部字段的请求返回缓存。即使对相同资源发起请求,但由于Vary指定的首部字段不相同,因此也必须要从源服务器上重新获取资源。

9、WWW-Authenticate
WWW-Authenticate: Basic realm="Usagidesign Auth"

首部字段WWW-Authenticate 用于Http访问认证。它会告知客户端适用于访问请求URI所指定资源的认证方案(Basic 或 Digest)和带参数提示的质询(challenge)。状态码401Unauthorized响应中,肯定带有首部字段WWW-Authenticate。
上述示例中,realm字段的字符串是为了辨别请求URI指定资源所受到的保护策略。

实体首部字段

实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于不中内容夫人更新时间等与实体相关的信息


实体首部

图:在请求和响应两方的http报文中都含有与实体相关的首部字段

1、Allow
Allow
Allow:GET,HEAD

首部字段Allow用于通知客户端能够支持Request-URI指定资源的所有http方法。当服务器接收到不支持http方法时,会以状态码405 Method Not Allowed作为响应返回。与此同时,还会把所有能支持的http方法写入首部字段Allow返回。

2、Content-Encoding
Content-Encoding:gzip

首部字段Content-Encoding会告知客户端 服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行的压缩。

Content-Encoding

主要采用下边四种内容编码的方式

  • gzip
  • compres
  • deflate
  • identity
3、Content-Language
Content-Language:zh-CN

首部字段Content-Language会告知客户端,实体主体使用的自然语言(指中文或者英文等语言)

4、Content-Length
Content-Length:15000

首部字段Content-Length表明了实体主体部分的大小(单位字节)。对实体主体进行内容编码传输时,不能再使用Content-Length首部字段。

5、Content-Location
Content-Location:http://www.xxx.xx/index.html

首部字段Content-Location 给出与报文主体部分相对应的URI。和首部字段Location不同,Content-Location表示的是报文主体返回资源对应的URI。

比如,对于使用首部字段Accept-Language的服务器驱动类型请求,当返回的页面内容与实际请求的对象不同时,首部字段Content-Location内会写明URI。(访问http://www.xx.jp/返回的对象却是http://www.xx.jp/index.html等类似情况)

6、Content-MD5
Content-MD5

图:客户端会对接收的报文执行相同的MD5算法,然后与首部字段Content-MD5的字段值比较

Content-MD5:OGFkZDUwNGVhNGY3N2MxMDIwZmQ4NTBmY2IyTY==

首部字段Content-MD5是一串由MD5算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。

对报文主体执行MD5算法获得的128位二进制数,再通过Base64编码后将结果写入Content-MD5字段值。由于Http首部无法记录二进制值,所以要通过Base64编码处理。为确保报文的有效性,作为接收方的客户端会对报文主体再执行一次相同的MD5算法。计算出的值与字段值比较后,即可判断出报文主体的准确性。

采用这种方法,对内容上的偶发性改变时无从查证的,也无法检测出恶意篡改,那么同时意味着Content-MD5也可重新计算然后被篡改。所以处于接收阶段的客户端是无法意识到报文主体以及首部字段Content-MD5是已经被篡改过的。

7、Content-Range
Content-Range
Content-Range:bytes 5001-10000/10000

针对范围请请求,返回响应时使用的首部字段Content-Range,能告知客户端作为响应返回的实体的哪个部分符合范围请求。字段值以字节为单位,单表当前发送部分以及整体实体大小。

8、Content-Type
Content-Type:text/html;charset:UTF-8

首部字段Content-Type说明了实体主体内对象的媒体类型。和首部字段Accept一样,字段值用type/subtype形式赋值。

9、Expires
Expires
Expires:Wed, 04 Jul 2012 08:26:05 GMT

首部字段Expires会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段Expires的响应后,会以缓存来应答请求,在Expires字段指定的时间之前,缓存的副本会一直被保存。当超过指定的时间之后,缓存服务器在请求发送过来时,会转向源服务器请求资源。

源服务器不希望缓存服务器对资源缓存时,最好在Expires字段内写入与首部字段Date相同的时间值。

但是,当首部字段Cache-Control有指定max-age指令时,比起首部字段Expires,会优先处理max-age指令。

10、Last-Modified
Last-Modified
Last-Modified: Wed, 23 May 2012 09:59:55 GMT

首部字段Last-Modified指明资源最终修改的时间。一般来说,这个值就是Request-URI指定资源被修改的时间。但类似使用CGI脚本进行动态数据处理时,该值有可能会变成数据最终修改时的时间。

为Cookie服务的首部字段

管理服务器与客户端之间状态的Cookie,虽然没有被编入标准化Http/1.1的RFC2616中,但在Web网站方面得到了广泛的应用。

Cookie的工作机制是用户识别及状态管理。Web网站为了管理用户的状态会通过Web浏览器,把一些数据临时写入用户的计算机内。接着但用户访问该Web网站时,可通过通信方式取回之前发放的Cookie。

调用Cookie时,由于可校验Cookie的有效期,以及发送方的域、路径、协议等信息,所以正规发布的Cookie内的数据不会因来自其他Web站点和攻击者的攻击而泄露。

至2013年5月,Cookie的规范标准文档有以下4种,

  • 由网景公司颁布的规格标准
    网景通信公司设计并发布了Cookie,并指定相关的规格标准。1994年前后,Cookie真是应用在网景浏览器中。目前最为普及的Cookie方式也是以此为基准的。
  • RFE2109
    某企业尝试以独立技术对Cookie规格进行标准化统筹。原本的意图是想和网景公司制定的标准交互应用,可惜发生了微妙的差异。现在该标准已经淡出了人们的视线。
  • RFC2965
    为终结Internet Explorer浏览器与Netscape Navigator的标准化差异而导致的浏览器战争,RFC2965内定义了新的HTTP首部SetCookie2和Cookie2。事实上,他们几乎没怎么投入使用。
  • RFC6265
    将网景公司指定的标准作为业界事实标准(De facto standard),重新定义Cookie标准后的产物。

目前使用最为广泛的Cookie标准却不是RFC中定义的任何一个。而是在网景公司制定的标准上进行扩张后的产物。

这里说明一下最为广泛普及的标准。

  • 为Cookie服务的首部字段
    | 首部字段名 | 说明 | 首部类型 |
    | ---------- | ------------------------------ | ------------ |
    | Set-Cookie | 开始状态管理所使用的Cookie信息 | 响应首部字段 |
    | Cookie | 服务器接收到的Cookie信息 | 请求首部字段 |
1、SetCookie
Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31 GMT; 

当服务器准备开始管理客户端的状态时,会实现告知各种信息。
下边列举SetCookie的字段值

属性 说明
NAME=VALUE 赋予Cookie的名车个和值(必须项)
exoires=DATE Cookie的有效期(若不明确指定则认为到浏览器关闭为止)
path=PATH 将服务器上的文件目录作为Cookie的适用对象(若不指定则默认位文档所在的文件目录)
domain=域名 作为Cookie适用对象的域名(若不指定则默认为创建Cookie的服务器的域名)
Secure 仅在Https安全通信时才会发送Cookie
HttpOnly 加以限制,使Cookie不能被JavaScript脚本访问
  • expires 属性
    Cookie的expires属性指定浏览器可发送Cookie的有效期。
    当省略expires属性时,其有效期仅限于维持浏览器会话(session)时间段内。这通常限于浏览器应用程序被关闭之前。

另外,一单Cookie从服务器发送至客户端,服务器端就不存在可以显式删除Cookie的方法。但是可以通过覆盖已过期的Cookie,实现对客户端Cookie的实质性删除操作。

  • path属性
    Cookie的path属性可用于限制指定Cookie的发送范围的文件目录。不过另有办法可避免这项限制,看来对其作为安全机制的效果不能抱有期待。
  • domain属性
    通过Cookie的domain属性指定的域名可以做到与结尾匹配一致。比如,当指定example.com后,除example.com外,wwww.example.com或者wwww2.example.com等都可以发送Cookie.

因此,除了针对具体指定的多个域名Cookie之外,不指定domain属性显得更安全。

  • secure属性
    Cookie的secure属性用于限制Web页面仅在Https安全连接时,才可以发送Cookie。
    发送Cookie时,指定secure属性的方法如下所示。
Set-Cookie:name=value;secure

以上例子仅当在https://www.xxx.com/(HTTPS)安全连接的情况下才会进行Cookie的回收。也就是说,即使域名相同,http://www.xxx.com/(HTTP)也不会发生Cookie回收行为。

当省略secure属性时,不论是HTTP,还是HTTPS,都会对Cookie进行回收。

  • HttpOnly属性
    Cookie的HttpOnly属性是Cookie的扩展功能,它使用JavaScript脚本无法获得Cookie。其主要目的为反之跨站脚本攻击(Cross-sitescripting,XSS)对Cookie的信息窃取。
    发送指定HttpOnly属性的Cookie的方法如下所示。
Set-Cookie:name=value;HttpOnly

通过上述设置,通过从Web页面内还可以对Cookie进行读取操作。但是用JavaScript的document.cookie就无法读取附加HttpOnly属性后的Cookie的内容了。因此,也就无法在XSS中利用JavaScript劫持Cookie了。

虽然是独立的扩展功能,但Internet Explorer6 SP1以上版本等当下的主流浏览器都已经支持扩展了。另外,该扩张并非是位了反之XSS而开发的。

Cookie
Cookie:status=enable

首部字段Cookie会告知服务器,但客户端想获得Http状态管理支持时,就会在请求中包含从服务器接收到的Cookie。接收到多克Cookie时,同样可以以多个Cookie形式发送。

其他首部字段

Http首部字段是可以自行扩展的。所以在Web服务器和浏览器的应用上,会出现各种非标准的首部字段。如下所示。

  • X-Frame-Options
  • X-XSS-Protection
  • DNT
  • P3P
1、X-Frame-Options
X-Frame-Options:DENY

首部字段X-Frame-Options属于Http响应首部,用于控制网站内容在其他Web网站的Frame标签内的显示问题。其主要目的是位了反之点击劫持(clickjacking)攻击。
首部字段X-Frame-Options有以下两个可指定的字段值。

  • DENY:拒绝
  • SAMEORIGIN:仅在同源域名下的页面匹配时许可。(比如,当指定http://www.xxx.jp/sample.html页面为SAMEORIGIN时,那么,xxx.jp上所有的页面的frame都被允许可加载该页面,而example.com等其他域名的页面就不行了)
2、X-XSS-Protection
X-XSS-Protection:1

首部字段X-XSS-Protection属于Http响应首部,它是针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器XSS防护机制的开关。

首部字段X-XSS-Protection可指定的字段值如下。

  • 0:将XSS过滤设置成无效状态
  • 1:将XSS过滤设置成有效状态
3、DNT
DNT:1

首部字段DNT属于Http请求首部,其中DNT是 Do Not Track 的简称,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法。
首部字段DNT可指定的字段值如下。

  • 0:同意被追踪
  • 1:拒绝被追踪
    由于首部字段 DNT的功能具备有效性,所以Web服务器需要对DNT做对应的支持。
4、P3P
P3P: CP="CAO DSP LAW CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa OUR BUS 

首部字段 P3P 属于 HTTP 相应首部,通过利用 P3P(The Platform for Privacy Preferences,在线隐私偏好平台)技术,可以让 Web 网站上 的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的 目的。
要进行 P3P 的设定,需按以下操作步骤进行。
步骤 1:创建 P3P 隐私
步骤 2:创建 P3P 隐私对照文件后,保存命名在 /w3c/p3p.xml
步骤 3:从 P3P 隐私中新建 Compact policies 后,输出到 HTTP 响应 中

下一篇 读书笔记_图解HTTP(四) HTTPS

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容