HTTP协议分析

TCP/IP协议

Posted by Pele on March 28, 2022

HTTP 协议分析

超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议[1]。HTTP是万维网的数据通信的基础。 —— Wikipedia

尽管TCP/IP协议是互联网上最流行的应用,但是在HTTP协议中并没有规定它必须使用或它支持的层。事实上HTTP可以在任何互联网协议或其他网络上实现。HTTP假定其下层协议提供可靠的传输。因此,任何能够提供这种保证的协议都可以被其使用,所以其在TCP/IP协议族使用TCP作为其传输层。

请求方法

  • GET —— 向指定的资源发出“显示”请求。
  • HEAD —— 与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。
  • POST —— 向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。
  • CONNECT —— HTTP/1.1协议中预留给能够将连接改为隧道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)。

HTTP服务器至少应该实现GET和HEAD方法,其他方法都是可选的。当然,所有的方法支持的实现都应当符合下述的方法各自的语义定义。

HTTP 版本迭代

HTTP/0.9

已过时。只接受GET一种请求方法,没有在通讯中指定版本号,且不支持请求头。由于该版本不支持POST方法,因此客户端无法向服务器传递太多信息。

HTTP/1.0

这是第一个在通讯中指定版本号的HTTP协议版本。

HTTP/1.1

默认采用持续连接(Connection: keep-alive),能很好地配合代理服务器工作。还支持以管道方式在同时发送多个请求,以便降低线路负载,提高传输速度。

HTTP/1.1相较于HTTP/1.0协议的区别主要体现在:

  • 缓存处理
  • 带宽优化及网络连接的使用
  • 错误通知的管理
  • 消息在网络中的发送
  • 互联网地址的维护
  • 安全性及完整性
HTTP/2

当前版本,于2015年5月作为互联网标准正式发布。

HTTP 状态码

响应类型

状态类型 信息
1xx 指示信息–表示请求已接收,继续处理。
2xx 成功–表示请求已被成功接收、理解、接受。
3xx 重定向–要完成请求必须进行更进一步的操作。
4xx 客户端错误–请求有语法错误或请求无法实现。
5xx 服务器端错误–服务器未能实现合法的请求。
常见状态码  
200 OK 客户端请求成功
400 Bad Request 客户端请求有语法错误,不能被服务器所理解
401 Unauthorized 请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden 服务器收到请求,但是拒绝提供服务
404 Not Found 请求资源不存在,举个例子:输入了错误的URL
500 Internal Server Error 服务器发生不可预期的错误
503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后可能恢复正常

持续连线

使用多个链接和使用持久链接的对比

在HTTP 0.9和1.0中,TCP连接在每一次请求/回应对之后关闭。在HTTP 1.1中,引入了保持连线的机制,一个连接可以重复在多个请求/回应使用。持续连线的方式可以大大减少等待时间,因为在发出第一个请求后,双方不需要重新执行TCP握手程序

抓包分析

建立TCP链接

三次握手🤝

image-20220328184450099

请求头

GET

image-20220328184929273

  • 请求方式 GET
  • Host: log.people.cn
  • User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62
  • Accept: */* 接受所有类型
  • Accept-Encoding: gzip, deflate 接受的编码类型
  • Accept-Language: zh-CN,zh;q=0.9, en;q=0.8, en-GB;q=0.7, en-US;q=0.6 对不同语言的偏好
  • If-Modified-Since:Fri, 24 Dec 2021 03:27:02 GMT 服务器文件上次修改时间
  • Referer: http://www.people.com.cn

POST

image-20220328190531290

  • 请求类型:POST
  • Host: search.people.cn
  • Content-Length: 145 内容长度 145字节
  • Accept: application/json, text/plain,*/*
  • Content-Type: application/json 内容类型为应用数据,格式为json
  • 包内包含了一个大小为145bytes的json文件,发送要搜索的数据信息

响应头

image-20220328191533727

  • 状态码: 200

  • Response Phrase: OK

    请求成功

  • Connection: Keep-alive

  • Content-Encoding: gzip 内容编码 gzip

  • Content-Type: text/html 内容格式 text/html

  • Date:Mon, 28 Mar 2022 16:29:49 GMT

  • Server:nginx 服务器运行的系统

  • Vary:Accept-Encoding 代表在下次的请求头中还需包含Accept-Encoding条目

image-20220328192352842

  • 状态码:403 Forbidden
  • Transfer-Encoding: chunked
    • Transfer-Encoding 指明了将实体报文安全传递给用户所采用的编码形式。
    • chunked指数据以一系列分块的形式进行发送。 Content-Length 首部在这种情况下不被发送。

Node.js 实现

刚好最近在学Node.js, 尝试使用node.js 配置服务器后端响应。

对GET请求的响应

image-20220328193150881

创建一个最简单的对GET请求的响应,当收到GET请求时返回一个text文件

image-20220328193445652

使用 API Tester 向 127.0.0.1:3000端口发送一个GET请求

可以发到返回的内容为一个text,长度为11字节

获取服务器中的文件

image-20220328195259155

image-20220328195520799

判断逻辑为,向服务器发送GET请求,如果该用户存在,会返回用户名对应的json文件,如果data中没有该用户的信息,则返回404错误,提示‘no user’

  • 不存在的用户名,返回404错误码

  • 存在的用户,返回对应的json文件

    image-20220328200335934

对POST请求的响应

image-20220329074753862

  • 如果请求为POST,并且访问的路径为api/v1/user进入函数解析

  • 如果数据校验出错,返回状态码 422 ,提示``name required`

  • 如果请求正确,且数据符合要求,返回状态码200,并且返回一个json文件,内容为

    {
      "success": true
    }
    
  • 其他情况,调用错误处理函数兜底,返回错误码400

测试

image-20220329110859327

发送一个body为空的POST请求,服务器响应422 name required,说明缺少内容

image-20220329111037617

访问其他路径,返回400 Error

image-20220329111223843

发送一个POST报文,body包含一个json字段

image-20220329111317139

在请求报文的头部加入Content-Type为 json类型

服务器返回的信息为

{"success":true}

image-20220329111429591

image-20220329111513944

在本地的data文件夹中成功创建了名为pqq.json的文件