HTTP/1.1报文详解

>>强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!
HTTP/1.1报文详解
打开公众号右上角选择设为星标,最新干货不错过




本文为《三万长文50+趣图带你领悟web编程的内功心法》第三个章节。

3、HTTP/1.1报文详解

在RFC2616中心详细的描述了HTTP/1.1[3]的报文,感兴趣的朋友也可以前往阅读。

HTTP是基于TCP的,HTTP作为应用层协议,会在TCP/IP协议栈往下传递的时候,不断封装数据帧,如下图:

HTTP/1.1报文详解

上面HTTP正文即是以我们HTTP报文格式来组织的。下面我们看看具体的HTTP报文的格式。

3.1、HTTP报文组成部分

HTTP请求和响应都使用如下通用的格式:

HTTP/1.1报文详解

  • start-line:起始行,起始行可以为以下两者之一:

  • Request-Line:请求行,如:

    • <br />GET /hello-world2.html HTTP/1.1<br />

  • Status-Line:状态行,如:

    • <br />HTTP/1.1 200 OK<br />

  • *(message-header CRLF):0个或者多个消息头

  • CRLF:一个空行;

  • [message-body]:可选的消息体;

可以分别把请求报文和响应报文分开来描述:

请求报文

HTTP/1.1报文详解

响应报文

HTTP/1.1报文详解

可以发现,请求报文和响应报文格式就起始行不一样。

下面我们逐个来介绍。

为了尽可能保证内容的准确性,下面报文各种字段说明部分内容,大部分整理自RFC2616和MDN web docs:

  • Hypertext Transfer Protocol -- HTTP/1.1 2616[3]

  • HTTP. MDN web docs[7]

  • 《HTTP权威指南》

以上资料内容有冲突的,以RFC2616的为准。

3.2、请求行

请求行格式:

1Request-Line = Method SP Request-URI SP HTTP-Version CRLF

3.2.1、METHOD

方法是区分大消息的,以下是常用的方法:

HTTP/1.1报文详解

另外,服务器还可以实现一些自己的请求方法,这些附加的方法是对HTTP规范的扩展,因此也成为扩展方法。

extension-method = token

请求可能的返回结果:

  • 405:表示请求的方法不被允许,这个时候服务器响应头会响应当前资源允许的方法,如:

  • 1Allow: GET, HEAD, PUT
  • 501:代表原服务器的该方法未能被识别或者未实现;

下面逐个方法介绍下:

GET

GET方法意味着可以检索 Request-URI标识的任何信息。

如果Request-URI涉及到创建数据,则应该将新建的数据作为响应实体返回。

如果请求消息包含 If-Modified-Since,If-Unmodified-Since,If-Match,If-None_match或If-Range标头字段,则此时的Get为条件GET。通过使用缓存标头,可以尽可能避免不必要的网络传输。

如果请求标头包含Range,则GET方法变为部分GET。

HEAD

HEAD方法与GET方法很类似,但是HEAD方法在在响应中只返回首部,不会返回消息体。

这就允许客户端再不用获取实际资源的情况下,对资源首部进行检查。如:

  • 检查资源是否有更新:如果获取到的 Content-Length、Content-MD5、ETag、Last-Modified与之前获取到的值不同,那么缓存应该被视为过期;

  • 查看响应状态码,查看资源是否存在;

  • 获取首部更多信息,判断资源情况。

POST

POST方法起初是用来向服务器传输数据的,通常用来提交HTML的表单到服务器。

PUT

PUT方法用于向服务器写入资源,如果Request-URI对应的资源已经存在的话,就进行更新。

注意:

POST用于向服务器发送数据,PUT用于向服务器上的资源中存储数据。

DELETE

请求服务器删除URL所指示的资源,但是客户端无法保证删除操作一定会被执行,除非在响应式服务器打算删除资源或者将其移动到无法访问的位置。可能的响应:

  • 如果响应包含描述状态的实体,则响应200(确定);

  • 如果尚未执行删除操作,则响应202(接受);

  • 如果已执行该操作,并且响应不包含任何实体,则响应204(无内容)。

此方法的响应不可缓存。

TRACE

一个请求从客户端到服务端,中间可能会经历各种代理、网关等程序,每个中间节点都可能修改原始HTTP请求。为此,通过TRACE,服务端会在接收到请求后反馈一个TRACE响应,并且在响应主体中携带它收到的原始请求报文。客户端拿到TRACE响应,就可以进行测试和诊断了。其中Via标头字段特别有用,它用于充当请求链的跟踪。

可以使用Max-Forwards标头字段限制请求链的长度,这对于测试无限循环中转发消息的代理很有用。

如果请求有效,则响应应该在实体正文中包含整个请求消息,其 Content-Type为"message/http"。对此方法的响应绝对不能缓存。

TRACE允跨站点跟踪问题,并且可能使黑客可以选择窃取您的cookie信息。基于安全的考虑,一般的服务器会关掉TRACE:

1TraceEnable off

这样执行TRACE会导致客户端收到一个405不允许使用方法的状态码。

CONNECT

CONNECT 方法可以开启一个客户端与所请求资源之间的双向沟通的通道。它可以用来创建隧道(tunnel)。

例如,CONNECT 可以用来访问采用了 SSL (HTTPS) 协议的站点。客户端要求代理服务器将 TCP 连接作为通往目的主机隧道。之后该服务器会代替客户端与目的主机建立连接。连接建立好之后,代理服务器会面向客户端发送或接收 TCP 消息流。[5]

OPTIONS

通过该方法,可以请求服务器获取Request-URI对应支持的各种通信选项的信息。最常见的如:询问服务器当前URI支持哪些请求方法。

此方法响应不能缓存。

方法的安全性与幂等性

所谓安全性,就是无论方法执行多少次,服务器上的数据都不会被改变。

安全方法:GET、HEAD;

不安全方法:POST、PUT、DELETE操作则会改动数据。

所谓幂等,就是多次执行一个方法,结果都是相同的。

幂等方法:GET、HEAD、PUT、DELETE;

非幂等方法:POST。

3.2.2、REQUEST-URI

URI,Uniform Resource Identifier,请求的统一资源标识符。

3.2.2.1、URI与URL什么关系?

我们经常会用到这两个概念,但是他们是什么意思呢?

URI,Uniform Resource Identifier,统一资源标识符,能够唯一的标识网上的一个资源,比如,我的网站IT宅的Logo:

https://www.itzhai.com/resources/images/itzhai_logo_home_page.jpg

只要在世界的任何一个有网络的地方,发起请求,就可以拿到这个图片,这个URI具有唯一性。那什么是URL呢?

URI有两种形式:URL和URN。

URL

URL,Uniform Resource Locator,统一资源定位符,描述了一台特定服务器上某个资源的特定位置。例如上面的链接就是一个统一资源定位符:

HTTP/1.1报文详解

  • secheme方案:指定方位资源所使用的协议类型,如HTTPS;

  • 主机与端口:英特网地址,即域名,这里默认为80端口;

  • 路径:其余部分指定web服务器上的某个资源。

几乎所有的 URI都是URL。

一个完整的URL格式如下:

HTTP/1.1报文详解

  • 用户名和密码服务器要求输入用户名和密码才允许用户访问数据,如FTP;

  • ?query 查询字符串:可以通过查询字符串进行查询来缩小所请求资源类型的范围;

  • fragment片段:指向HTML文档中特定的图片或者小节。

URN

URL,Uniform Resource Name,统一资源名,作为特定内容的唯一名称,与资源所在位置无关。也就是说,我可以给一份文档定义一个URN,不管你把这个文档放到哪里,有多少个URL,但是都只有唯一个URN。举个例子,因特网标准文档 RFC 3986不管存在哪个服务器上,都可以用唯一的URN来命名:

urn:ietf:rfc:3986

URN处于试验阶段,暂未大范围使用。

再通俗易懂点来说:URN就相当于身份证,通过特定的规则,制定了一串唯一的字符串作为你的身份证,但是没有规定身份证一定要放在哪里,只是作为你的个人唯一凭证。URL相当于是快递单上的地址,根据地址,快递员一定可以把快递送到唯一的一个目的地。

3.2.3、HTTP-VERSION

指定了当前请求用到的HTTP协议版本。

3.3、消息头[6]

通过传递消息头(首部),服务器和客户端可以把自己的信息或者是请求响应相关信息进行传递。

可以把首部分为:通用首部,请求首部,响应首部,实体首部,扩展首部。下面就来详细介绍下。

3.3.1、通用首部

有些首部,不管是请求还是响应都会出现他们的身影,我们把他们归类为通用首部。常见通用首部如下表格所示:

HTTP/1.1报文详解

3.3.2、请求首部

客户端通过传递请求头字段,将有关请求以及有关客户端本身的其他信息传递给服务器,这些字段充当请求修饰符,其语义等同于编程语言方法调用中的参数。

常见的请求头如下:

Accept首部

HTTP/1.1报文详解

条件请求首部

HTTP/1.1报文详解

HTTP/1.1报文详解

安全请求首部

HTTP/1.1报文详解

代理请求首部

HTTP/1.1报文详解

3.3.3、响应首部

HTTP/1.1报文详解

协商首部

如果资源有多种表示方法,服务器可以通过协商首部来传递可协商资源有关的信息。

HTTP/1.1报文详解

安全响应首部

HTTP/1.1报文详解

3.3.4、实体首部

用来描述HTTP报文中实体相关信息的首部,我们成为实体首部。

HTTP/1.1报文详解

内容首部

HTTP/1.1报文详解

实体缓存首部

实体缓存首部提供与被缓存实体有关的信息,如什么时候或者如何缓存,缓存是否有效等,通过缓存首部可以估计缓存何时失效。

HTTP/1.1报文详解

3.4、消息体

3.4.1、请求消息体

并不是所有的请求都需要body,如:GET,HEAD,DELETE,OPTIONS通常不需要body。

请求body可以分为两类:

  • Single-resource bodies,由单个文件组成。该类型 body 由两个 header 定义: `Content-Type` 和 `Content-Length`;

  • Multiple-resource bodies,由多部分body组成,每一部分包含不同的信息位。通常是和 HTML Forms 联系在一起。

3.4.2、响应消息体

并不是所有的响应都有body,如 201 或 204状态码的响应一般不会有body。

响应body可以分为三类:

  • Single-resource bodies,由已知长度的单个文件组成。该类型 body 由两个 header 定义:`Content-Type` 和 `Content-Length`;

  • Single-resource bodies,由未知长度的单个文件组成,通过将 `Transfer-Encoding` 设置为 chunked来使用 chunks 编码;

  • Multiple-resource bodies,由多部分 body 组成,每部分包含不同的信息段。但这是比较少见的。

3.5、状态行

响应消息的第一行是状态行,由协议版本,数字状态代码及其关联的文本短语组成,每个元素由SP字符分隔。除最后的CRLF序列外,不允许CR或LF。

状态行格式:

1Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

3.5.1、STATUS-CODE状态码和REASON-PHRASE状态描述

状态码是3位数的整数结果代码。

状态码的第一位数字定义响应的类别。后两位数字没有任何分类作用。可以分为5个类别:

  • 1xx:信息状态码,收到请求,继续进行;

  • 2xx:请求成功接收;

  • 3xx:重定向,必须采取进一步措施才能完成请求;

  • 4xx:客户端错误,请求包含错误语法,或者不能被完成;

  • 5xx:服务器错误,服务器无法完成看似有效的请求;

RFC中定义的状态码很多,这里我们列出最常见的一些状态码:

HTTP/1.1报文详解

HTTP/1.1报文详解

HTTP/1.1报文详解

更多状态码说明:

  • List of HTTP status codes[8]

  • https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status[9]

上面我们把HTTP报文介绍了一遍,HTTP作为一个协议,只是规定了大家要遵循这样的约定,但是具体实现的时候,还是要看应用程序的兼容程度。我们在写程序的时候,也不要跟协议对着干,这会让对接的同事无法理解的。

你都知道以下状态码的含义了吗?

200 204 206 301 302 304 401 403 405 500 501 502 503 504


这篇文章的内容就差不多介绍到这里了,能够阅读到这里的朋友真的是很有耐心,为你点个赞。

本文为arthinking基于相关技术资料和官方文档撰写而成,确保内容的准确性,如果你发现了有何错漏之处,烦请高抬贵手帮忙指正,万分感激。

大家可以关注我的博客:itzhai.com 获取更多文章,我将持续更新后端相关技术,涉及JVM、Java基础、架构设计、网络编程、数据结构、数据库、算法、并发编程、分布式系统等相关内容。

如果您觉得读完本文有所收获的话,可以关注我的账号,或者点个赞吧,码字不易,您的支持就是我写作的最大动力,再次感谢!

关注我的公众号,及时获取最新的文章。

References

[1]: Hypertext Transfer Protocol -- HTTP/1.0 RFC 1945. Retrieved from https://datatracker.ietf.org/doc/rfc1945/

[2]: HypertextTransferProtocol--HTTP/1.1 2068. Retrieved from https://tools.ietf.org/html/rfc2068

[3]: Hypertext Transfer Protocol -- HTTP/1.1 2616. Retrieved from https://tools.ietf.org/html/rfc2616

[4]: Hypertext Transfer Protocol Version 3 (HTTP/3). Retrieved from https://quicwg.org/base-drafts/draft-ietf-quic-http.html

[5]: CONNECT. Retrieved from https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/CONNECT

[6]: HTTP Headers. Retrieved from https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers

[7]: HTTP. MDN web docs. Retrieved from https://developer.mozilla.org/zh-CN/docs/Web/HTTP

[8]: List of HTTP status codes. Retrieved from https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

[9]: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status. Retrieved from https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status

[10]: 两万字长文50+张趣图带你领悟网络编程的内功心法-TCP特点. Retrieved from https://www.itzhai.com/network/comprehend-the-underlying-principles-of-network-programming.html#4-2-2%E3%80%81TCP%E7%89%B9%E7%82%B9

[11]: 技术干货:HTTP/2 之服务器推送 (Server Push) 最佳实践. Retrieved from https://www.infoq.cn/article/qYdN85t4G4dL4vBAe3N2

[12]: 《HTTP权威指南》第17章 内容协商与转码. 人民邮电出版社. P413

[13]: 两万字长文50+张趣图带你领悟网络编程的内功心法-TCP连接管理. Retrieved from https://www.itzhai.com/network/comprehend-the-underlying-principles-of-network-programming.html#4-2-3、连接管理

[14]: 《HTTP权威指南》 第六章 代理

[15]: 《HTTP权威指南》 第八章 集成点:网关、隧道及中继

[16]: Module ngx_http_upstream_module. Retrieved from http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive

[17]: 161 Cipher Suites. Retrieved from https://ciphersuite.info/cs/?software=openssl&singlepage=true

[18]: HTTP/2 简介. Retrieved from https://developers.google.com/web/fundamentals/performance/http2


  • 谢希仁. 计算机网络(第6版). 电子工业出版社.

  • TCP/IP详解 卷1:协议(原书第2版). 机械工业出版社.

  • UNIX网络编程 卷1:套接字联网API. 人民邮电出版社

  • HTTP权威指南. 人民邮电出版社

  • HTTP/2基础教程. 人民邮电出版社

  • 刘超. 趣谈网络协议. 极客时间

  • 罗剑锋. 透视HTTP协议. 即可时间


·END·
 访问IT宅(itzhai.com)查看我的博客更多文章

扫码关注及时获取新内容↓↓↓



Java架构杂谈

Java后端技术架构 · 技术专题 · 经验分享

HTTP/1.1报文详解

blog: itzhai.com


码字不易,如有收获,点个「赞」哦~



我就知道你“在看
HTTP/1.1报文详解



原文始发于微信公众号(Java架构杂谈):HTTP/1.1报文详解