Http头信息(一)——通用头信息(二)

介绍

上一篇博文着重介绍了Cache-Control,这篇博文将会介绍剩余的:

  • Connection
  • Date
  • Transfer-Enconding
  • Trailer
  • Upgrade
  • Via
  • Warning

1. Connection

Connection头信息有2个作用,分别是:

  1. 控制不再转发给代理服务器的头信息
  2. 管理持久连接

(1).控制不再转发的头信息

Connection:逐跳首部

什么是逐跳首部?参见:这可能是最全的Http头信息资料了

例如:客户端发送给代理服务器的中头信息中是

GET / HTTP/1.1
Connection:Upgrade
Upgrade:HTTP/1.1
Cache-Control:no-cache

那么代理服务器发送给下一个服务器(可能是代理,也可能是最终服务器)的头信息中就会将Upgrade头信息删除,变成

GET / HTTP/1.1
Cache-Control:no-cache

(2).管理持久连接

<!--关闭连接-->
Connection:close
<!--开启持久连接(适用于Http 1.1之前的版本)-->
Connection:Keep-Alive

HTTP 1.1版本中,所有的连接默认都是持久连接

持久连接:进行一次Http通讯后,不断开TCP连接

当明确想断开连接时使用Connection:close
HTTP 1.1之前的版本中,默认都是非持久连接,因此如果要保持持久连接需要指定Connection:Keep-Alive

2.Date

Date指明了创建Http报文的时间
使用的格式有:

  • RFC1123中规定的格式
<!--2021年10月17号,星期天,下午3点08分00秒-->
Date:Sun, 17 Oct 2021 15:08:00 GMT
  • RFC850中规定的格式
<!--2021年10月17号,星期天,下午3点08分00秒-->
Date:Sun, 17-Oct-21 15:08:00 GMT
  • C语言标准库中asctime()的输出格式
<!--2021年10月17号,星期天,下午3点08分00秒-->
Date:Sun Oct 17 15:08:00 2021

3.Transfer-Enconding

该头信息规定了传输报文主体是采用的编码方式。注意和Content-Encoding区分。

  • Transfer-Enconding :在传输过程中使用的编码方式,仅用于两个节点之间的传递,而不是资源本身 [1]

      例如:源服务器采用了`gzip`传送给了代理服务器,代理服务器解析数据后,将传输方式更改为`chunked`分块传输给客户端
    
  • Content-Encoding:报文主体采用什么方式编码,整个传输过程中都不会更改

<!--分块传输-->
Transfer-Enconding:chunked
<!--采用 Lempel-Ziv-Welch (LZW) 压缩算法,这种内容编码方式已经被大部分浏览器弃-->
Transfer-Encoding: compress
<!--采用 zlib 结构 (在 RFC 1950 中规定),和 deflate 压缩算法(在 RFC 1951 中规定)。-->
Transfer-Encoding: deflate
<!--表示采用  Lempel-Ziv coding (LZ77) 压缩算法,以及32位CRC校验的编码方式-->
Transfer-Encoding: gzip
<!--用于指代自身(例如:未经过压缩和修改)。除非特别指明,这个标记始终可以被接受-->
Transfer-Encoding: identity

分块传输会将实体分成多个部分,每一块都会用十六进制来标记块的大小,而实体的最后一块会使用0(CR+LF)来标记。

对于非持久连接,浏览器可以通过连接是否关闭来界定请求或响应实体的边界;而对于持久连接,这种方法显然不奏效,尽管已经发送完所有数据,但浏览器并不知道这一点,它无法得知这个打开的连接上是否还会有新数据进来,只能傻傻地等
要解决上面这个问题,最容易想到的办法就是计算实体长度,并通过头部告诉对方。这就要用到 Content-Length
由于 Content-Length 字段必须真实反映实体长度,但实际应用中,有些时候实体长度并没那么好获得,例如实体来自于网络文件,或者由动态语言生成。这时候要想准确获取长度,只能开一个足够大的 buffer,等内容全部生成好再计算。但这样做一方面需要更大的内存开销,另一方面也会让客户端等更久。
Transfer-Encoding 正是用来解决上面这个问题的。历史上 Transfer-Encoding 可以有多种取值,为此还引入了一个名为 TE 的头部用来协商采用何种传输编码。但是最新的 HTTP 规范里,只定义了一种传输编码:分块编码(chunked)。
分块编码相当简单,在头部加入 Transfer-Encoding: chunked 之后,就代表这个报文采用了分块编码。这时,报文中的实体需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的 CRLF(\r\n),也不包括分块数据结尾的 CRLF。最后一个分块长度值必须为 0,对应的分块数据没有内容,表示实体结束 [2]

例子:

HTTP/1.1 200 OK
...
Content-Encoding:gzip
Transfer-Econding:chunked
...

cf0 <!--转为10进制为:3312-->
... <!--3312字节的内容-->
392 <!--转为10进制为:914-->
... <!--914字节的内容-->
0 <!--分块结束-->

4. Trailer

<!--在报文主体之后还有Date头信息-->
Trailer:Date

该指令指示在报文主体之后还有哪些头信息,不可以包含以下头信息 [3]

  • 用于信息分帧的首部 (例如Transfer-EncodingContent-Length)
  • 用于路由用途的首部 (例如 Host)
  • 请求修饰首部 (例如控制类和条件类的,如Cache-ControlMax-Forwards,或者 TE)
  • 身份验证首部 (例如 Authorization 或者 Set-Cookie)
  • Content-Encoding, Content-Type, Content-Range,以及 Trailer 自身

可应用于分块传输编码,如:

HTTP/1.1 200 OK
...
Content-Encoding:gzip
Transfer-Econding:chunked
Trailer:Date
...

cf0 <!--转为10进制为:3312-->
... <!--3312字节的内容-->
392 <!--转为10进制为:914-->
... <!--914字节的内容-->
0 <!--分块结束-->

Date:Sun Oct 17 15:08:00 2021
为什么还需要这个字段?直接把头信息放到前面不就好了吗?
这时因为有些信息只有处理完实体内容后才知道。比如一个字节流的大小、消息的完整性验证,消息经过处理后的最终状态等。这时,就需要是使用`Trailer`将信息加到实体的后面

5.Upgrade

询问下一个直连服务器,是否可以使用其他的协议进行通信

<!--询问对方是否可以使用 TLS/1.0或者webSocket协议进行通信-->
Upgrade:TLS/1.0,webSocket
为什么使用`Upgrade`的时候,要配合`Connection:Upgrade`一起使用?

再回到HTTP 1.1的Connection头部,这儿有一个兼容性问题:我们以Upgrade头部为例,某个proxy实现了HTTP 1.0协议,将Upgrade原样转发给后端,后端和proxy升级协议,但是这个情况下,proxy不认识升级后的协议啊 [4]

如果服务器决定升级这个连接,会返回 101 Switching Protocols状态码,和要切换的协议,如:
客户端发起请求

GET / HTTP/1.1
...
Connection:Upgrade
Upgrade:TLS/1.0,webSocket <!--询问本次通讯是否可以使用`TLS 1.0`或者`webSocket`协议-->
...

服务器给与回应

HTTP/1.1 101 Switching Protocols
...
Upgrade:TLS/1.0 <!--本次通讯可以使用`TLS 1.0`协议-->
...

如果不能使用其他协议,会返回常规的响应,例如:200 OK
注意: 由HTTP/1.1请求建立的连接可以升级为HTTP/2协议的连接,但是反过来不可以。事实上HTTP/2已经不再支持101状态码了,也不再支持任何连接升级机制。[5]

6.Via

<!--
经过的1个代理地址为:p1.example.com,使用的Http协议版本是1.0
经过的2个代理地址为:p1.example.com,使用的Http协议版本是1.1
-->
Via: 1.0 p1.example.com, 1.1 p2.example.net

这个首部由代理服务器添加,每经过一个代理服务器,代理服务器会在Via后面添加一条信息。可以用来追踪消息转发情况

7. Warning

HTTP/1.1Warning首部是从HTTP/1.0的响应首部Retry-After演变过来的。该首部通常会告知用户一些与缓存相关的问题的警告。
Warning的格式如下:

Warning: <警告码> <警告的主机:端口号> "<警告内容>" [<警告时间>]

警告码[6]

  • 1XX:警告码描述了关于当前响应的新鲜度或者验证状态的警告信息,并且将会在验证之后被缓存服务器删除。
  • 2XX:警告码描述了验证之后不会被修复的某些展现内容方面的警告信息,并且在验证之后不会被缓存服务器删除。

7种警告码

警告码文字描述详细说明
110Response is stale (响应已过期)代理返回的资源已过期
111Revalidate failed (再验证失败)代理再验证资源有效性时失败
112Disconnected Operation(断开链接操作)代理无法连接互联网
113Heuristic Expiration(试探性过期)响应的使用期超过24小时 (有效缓存的设定时间为24小时的情况下)
199Miscellaneous Warning (杂项警告)任意的警告内容
214Transformation Applied(使用了转换)代理返回的展现内容进行了某些处理,比如改变了内容编码、媒体类型等。
299Miscellaneous Warning与199类似,只不过指代的是持久化警告。

下篇文章:Http头信息(二)——请求头信息(一)
关注我,获取最新的更新

Reference

[1]. Transfer-Encoding
[2]. HTTP 协议中的 Transfer-Encoding
[3]. Trailer
[4]. 为什么HTTP Upgrade的时候,需要Connection: upgrade
[5]. 协议升级机制
[6]. Warning

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值