一、概念引入
HTTP协议是 Hyper Text Transfer Protocol(超文本传输协议)的缩写,平时上网时,浏览器基本都是基于该协议与服务器通信的,HTTP是基于 TCP/IP 协议来传输数据的,包括HTTP文件、图片、查询结果等。
HTTP是一个典型的 C/S (即client-server)协议:请求通过一个实体被发出,实体也就是用户代理。大多数情况下,这个用户代理都是指浏览器。
每一个发送到服务器的请求request,都会被服务器处理并返回一个消息,也就是response。在这个请求与响应之间,还有许许多多的被称为 proxies(代理) 的实体,他们的作用与表现各不相同。
代理(proxies)是在客户端和服务器之间充当中介的服务器。它们可以缓存数据、过滤请求、提供匿名性或实现负载均衡等功能。代理服务器接收客户端的请求,处理或修改后再将其转发给目标服务器,最后将响应返回给客户端。
二、http报文格式
1) 报文概念理解
HTTP通信实际上就是按照HTTP协议的规范,将TCP数据段进一步封装为HTTP数据包发送给对方,以及将对方发来的HTTP数据包按规范逐次拆解的过程。
HTTP(超文本传输协议)是网络七层模型中的应用层协议。它定义了在客户端和服务器之间如何交换信息和数据。
2)典型HTTP请求报文 --- GET方法
char *http_request = "GET /repo/boa-0.100.9.tgz HTTP/1.1\r\n"
"Range:bytes=0-\r\n"
"Host:www.boa.org\r\n\r\n";
可以看到,整个 HTTP 请求报文由请求行、请求头部 和 请求包体组成,请求行以
"\r\n" 结束,请求头部中的每个头部字段也用
"\r\n" 相区隔,最后整个请求头部的结束还有一个
"\r\n",这些固定的格式规范是特别要注意的。
以上HTTP头部请求报文,所遵循的HTTP头部规范如下图所示:
3)典型HTTP响应报文
HTTP/1.1 206 Partial Content\r\n
Server: nginx/r/n
Content-Type: application/x-xz\r\n
Last-Modified: Mon, 28 Mar 2022 08:16:22 GMT\r\n
X-Frame-Options: DENY\r\n
X-Content-Type-Options: nosniff\r\n
Content-Security-Policy: default-src https:\r\n
X-XSS-Protection: 1; mode=block\r\n
Strict-Transport-Security: max-age=15768001\r\n
Accept-Ranges: bytes\r\n
Age: 6151\r\n\r\n
\r
...
...
以上HTTP头部响应报文,所遵循的HTTP头部规范如下图所示:
HTTP响应报文
4)响应与请求的理解
三、HTTP请求
1)请求格式
在 HTTP 请求报文中,其格式规范如下:
char *requestHead = "请求方法 URL 协议版本\r\n"
"字段1:值\r\n"
"字段2:值\r\n"
"字段3:值\r\n"
"..."
"字段n:值\r\n"
"\r\n"
"请求包体";
请求格式分为:
请求行
请求头部
请求包体
2)请求报文中的请求行
① 请求行中 的 请求方法
HTTP协议中的请求方法常见的有 GET、HEAD、POST、PUT 等等:
GET 一般用来指示从服务器获取资源,服务器返回响应头部和响应包体。
HEAD 一般用来指示检测文件是否存在或判定文件版本,服务器只返回响应头部。
POST 一般用来指示向服务器递交新的 HTML form 表单,实际数据类型一般通过 attribute 来决定。
PUT 一般用来指示向服务器递交修改信息。
要注意,HTTP 并非一种强制协议,HTTP 有很高的拓展性,因此在实际应用中,客户端发起请求时所使用的的请求方法是由当时具体提供服务的服务端决定的,并不一定遵循上述约定。
② 请求行中的URL:数据连接
URL(Uniform Resource Locator,统一资源定位符)指的是所请求的资源在服务主机中的路径。比如:
某下载地址:https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.17.2.tar.xz 子网络位置位置
"https://" 是协议信息。
"cdn.kernel.org" 是域名,即主机名
"/pub/linux/kernel/v5.x/linux-5.17.2.tar.xz" 则是此例中的 URL。
③ 请求行中的协议版本
协议版本,一般写 HTTP/1.1即可,具体而言:
HTTP与1990年问世,版本是 HTTP/0.9,当时并未作为正式的标准被建立。
HTTP作为标准被公布是1996年5月,版本是 HTTP/1.0。
1997年1月公布 HTTP/1.1,记载于 RFC2616,这是目前最被广泛使用、覆盖率最高的 HTTP 协议版本。
2013年8月对 HTTP/2.0 做了首次合作共事性测试,改版本只适用于 https:// 网址。
3)请求报文中的请求头部
① 请求头部中的头部字段
HTTP协议的首部字段有很多,并且根据HTTP的设计原则,各种字段是不具备强制性的,只要服务器和客户端约定好相关含义和位置即可通信。
以下是常见的标准字段:
Accept:请求希望服务器能响应何种表现格式。
例如 "Accept:text/plain\r\n",这代表客户端跟服务器说它只接受纯文本数据(不接收图片、视频)。
Accept-Encoding:告诉服务器可以接收何种压缩格式传输,以减少带宽。
Range:请求获得一个资源的部分表示,常与If-Unmodified-Since一起用。
例如 "Range:bytes=-\r\n",代表客户端要求服务器发送资源全文。
例如 "Range:bytes=-1000\r\n",代表客户端要求服务器发送资源的前1000个字节。
例如 "Range:bytes=100-\r\n",代表客户端要求服务器发送资源的第100开始的后面所有字节。
If-Modified-Since:通过前一次响应Last-Modified的时间值,当条件不成立,请求成功返回。
Host:用于指明服务器的主机名称。
Authorization:按特定认证方案编码的用户名和密码证书,服务器接收验证通过执行请求。
以下是常见的非标准字段:
Cookie:客户端告诉服务器Cookie属性。HTTP是无状态协议,客户端的多次请求能保持连贯,是因为有Cookie属性的帮助。
4)请求报文中的请求包体
大多数请求报文中,请求包体可以为空。但要注意,请求报文的首部字段最后要以 "\r\n" 结束。
四、HTTP响应
1)响应格式
在 HTTP 响应报文中,其格式规范如下:
char *responseHead = "协议版本 状态码 状态码描述\r\n"
"字段1:值\r\n"
"字段2:值\r\n"
"字段3:值\r\n"
"..."
"字段n:值\r\n"
"\r\n"
"响应包体";
char buf[1000];
read(xxx,buf,10000);
2)响应报文中的状态行
① 协议版本
服务器返回其当前所使用的 HTTP 协议版本。
② 状态码
状态码是响应报文中最重要的信息,由3个数字构成,大致可分为以下五大类:
1xx:通知。仅在与HTTP服务器沟通时使用。
2xx:成功。表示成功收到、理解和接受服务器动作。例如:
200(“OK")
201(“Created")
204(“No Content")
3xx:重定向。表示为完成请求,必须进一步采取措施。例如:
301(“Moved Permanently”)
303(“See Other”)
304(“Not Modified”)、
307(“Temporary Redirect”)
4xx:客户端错误。代表客户端发出的请求报文有误不能完成。例如:
400(“Bad Request”)
401(“Unauthorized”)
403(“Forbidden”)
404(“Not Found”),这就是著名的 404 错误
405(“Method Not Allowed”)
406(“Not Acceptable”)、
409(“Conflict”)、 410(“Gone”)
5xx:服务器端错误。代表服务器无法完成明显合理的请求。例如:
500(“Internal Server Error”)
503(“Service Unavailable”)
更详细的 HTTP 状态码,点击查询
https://tool.oschina.net/commons?type=5
3)响应报文中的响应头部中的头部字段
以下是常见的HTTP响应报文头部字段及其含义:
Content-Length: 给出响应包体的大小,客户端可据此做读取准备,也可通过Head请求来获知。
Transfer-Encoding: 给出响应包体的编码形式,若出现该字段且其值为 chunked,则代表服务端将以分段方式返回资源数据。
Accept-Ranges: 表明支持部分Get请求,客户端通过Head请求获取该值,然后发送Range报头请求,获取资源部分表示。
Content-Encoding: 对应Accept-Encoding请求报头。
Content-Language: 给出响应包体采用的自然语言,对应Accept-Language请求报头,可能多个值。
Content-Location: 把请求资源的规范URI告知客户端,但并不要求其使用新URI。
Content-MD5: 实体主体MD5,可检测错误损坏。
Last-Modified: 资源表示的最后修改时间。
ETag: 比Last-Modified更精确,能反映1秒内变化。
Expires: 客户端可在一段时间内缓存整个响应(不光是实体主体),但服务器不保证该时间段内一定不更新。
Location: 与3xx系列响应密切相关,可表示新资源创建后的URI,也可表示默认URI,还可是补充建议URI。
WWW-Authorization: 配合401 Unauthorized响应代码,可指定认证方式WSSE等。
4)对上述前两个响应报文字段要作特别的说明:Content-Length 和 Transfer-Encoding
① Content-Length
一般而言,当客户端向服务器请求资源(比如请求下载某文件、查询某信息等),服务器都需要告诉客户端其所申请的数据总量,以便于客户端可以准备恰当的内存来存储对应数据。在通常情况下,服务器会返回 Content-Length 直接告诉客户端响应包体总大小,此时响应包体会一次性发送给客户端。
此时的响应报文形如:
HTTP/1.1 200 OK \r\n
Date: Tue, 12 Apr 2022 07:26:41 GMT \r\n
Content-Length: 2889\r\n
Connection: keep-alive\r\n
...
...
{实际响应包体}
2)Transfer-Encoding
但此种简单情况无法应对一些动态数据,比如服务器在发送响应包体结束之前无法得知具体大小,那么就无法采用此种模式,改而采用分块(chunked)发送,每一块数据发送前,都先以十六进制发送此数据块的大小,每个数据块大小和数据块本身都以"\r\n"结束。
此时的响应报文形如:
HTTP/1.1 200 OK\r\n
Date: Tue, 12 Apr 2022 07:26:41 GMT\r\n
Transfer-Encoding: chunked\r\n
Connection: keep-alive\r\n
...
...
aa3
{响应数据块1}
82
{响应数据块2}
8da
{响应数据块3}
5)响应报文的响应包体
响应包体中通常包含了客户端所请求的资源,比如请求加载的HTML网页文档、请求下载的文件资源或者数据资源(天气)等。
标签:HTTP,请求,认识,报文,响应,关于,服务器,http,客户端
From: https://www.cnblogs.com/hhail08/p/18372456