HTTP协议|青训营

98 阅读3分钟

HTTP协议|青训营

HTTP协议是什么?

HTTP: Hypertext Transfer Protocol超文本传输协议。它依赖于资源或统一资源定位符(URI)的概念、一个简单的消息结构和一个客户端——服务器结构的通信流。

为什么我们需要协议?

  • 需要协议来规定明确的边界-开始,结束
  • 能够携带信息-什么消息,消息类型

HTTP协议有什么?

客户端请求:

2012072810301161.png

例如:

POST /sis HTTP/1.1 ①

Who: Alex

Content-Type: text/plain

User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3

Host: 192.168.31.101:8080

Content-Length:18 ②

Let's take a walk. ③

①请求行: 对HTTP当前版本的描述,有方法名,URL,协议版本

常见方法名:GET, HEAD,POST,PUT,DELETE,CONNECT,OPTIONS,TRACE,PATCH

②请求头

③请求体

服务端响应:

HTTP/1.1 200 OK

Server: hertz

Date: Thu ,22 Apr 2023 20:15:44 GMT

Content-Type: text/plain; charset=utf-8

content-Length: 2

Upstream-Caught: 1650541592984580

OK

①状态行: 对HTTP当前版本的描述,有协议版本,状态码,状态码描述

常见状态码:1xx:信息类、2xx:成功、3xx:重定向、4xx:客户端错误、5xx:服务端错误

②响应头

③响应体

HTTP的不足与展望

HTTP1:
  • 由于基于TCP,所以会产生队头阻塞的问题,后续分片需要等待前面的分片到来,才能继续发送后边的数据,否则将会一直等待
  • 传输效率低,无用信息非常多,可能大于需要传输的数据
  • 不支持多路复用,这个请求没结束之前,这个连接上不能发送其它的请求
  • 它是一个明文传输,不安全
HTTP2解决了部分H1的问题:
  • 支持了多路复用,头部压缩,是一个二进制协议,解析起来更加高效
  • 但没有解决对头阻塞的问题,而且HTTP1为了加密tos,握手开销未优化
新一代QUIC协议:
  • 基于UDP实现,可以解决TCP的队头阻塞
  • 优化了加密算法,减少了握手次数
  • 支持快速启动

OSI七层模型分别对应的网络协议

OSI七层网络模型TCP/IP四层概念模型对应的网络协议
应用层应用层HTTP,TFTP,FTP,NFS,WAIS,SMTP
表示层应用层Telnet,Rlogin,SNMP,Gopher
会话层应用层SMTP,DNS
传输层传输层TCP,UDP
网络层网络层IP,ICMP,ARP,RARP,AKP,UUCP
数据链路层数据链路层FDDI,Ethernet,Arpanet,PDN,SLIP,PPP
物理层数据链路层IEEE802.1A,IEEE802.2到IEEE802.11
分层设计——应用层设计

要提供合理的API,要具有如下的性质:

  • 可理解性:如ctx.Body(),ctx.GetBody()
  • 简单性:如ctx.Request.Header.Peek(key)->ctx.GetHeader(key)
  • 冗余性
  • 兼容性
  • 可测性
  • 可见性
分层设计——中间件设计
  • 配合Handler实现一个完整的请求处理生命周期
  • 拥有预处理逻辑与后处理逻辑
  • 可以注册多中间件
  • 对.上层模块用户逻辑模块易用
分层设计——路由设计

框架路由实际上就是为了URL匹配对应的处理函数(Handlers)

  • 静态路由: /a/b/c、 /a/b/d
  • 参数路由: /a/id/c (/a/b/c, /a/d/c)、 /*all
  • 路由修复: /a/b <-> /a/b/
  • 冲突路由以及优先级: /a/b、 /:id/c
  • 匹配HTTP方法
  • 多处理函数:方便添加中间件
分层设计——协议层设计

抽象出合适的接口:

  • 不要把context写到struct,要显式把它通过函数的第一个参数传递进来
  • 需要在连接上读写数据
分层设计——传输层设计
  • BIO:同步阻塞IO——客户端发送一个请求,服务端Socket进行处理后返回响应,在响应返回前,客户端那边就阻塞等待,什么事情也做不了。
  • NIO:注册监听器,只有客户端有相应的操作的时候才发起通知,创建一个线程来处理请求。