我们接着上期继续干,如果没有充分理解消化上一期内容, 本期将会比较吃力
最好好好看一下了解一下HTTP请求的数据包
上期我们有个基础的可以接收请求的服务器了, 接下来我们处理一下请求, 将请求的数据包结构分出来
但是你会发现数据是bytes的数据. 而且全部写一个文件也不好, 我们封装一下
我考虑到可能有点人基础不太好, 就不封装类了, 以封装函数来写. 提供一个原型方法, 剩下的你们自己来发挥自己的想象力
在同目录下新建一个 handler.py 文件用来存放我们封装的处理请求的函数
在server下导入进来
我们先来看一下效果
成功拿到了, 接下来将第二部分, 请求头部分拿到,处理成 dict 类型,还记等我们的每一项头信息都是怎么样的吧,以 请求头名称: 值,我们先将他转码, 然后根据冒号切片拿到每一项的 名称和值, 同时删除他们前后多余的空字符
使用循环取到剩下所有的数据, 循环读取行, 如果读取不到了就退出循环,
我们来看一下效果
确实拿到了, 但是你会发现你的浏览器/postman一直在请求始终没有停止过, 注意!我们的rbuff是readline如果没有取到数据他是阻塞等待的, 也就是说 下面这句 if header is None: break其实等同与没有!!!!!
但是!!, 你会发现标识请求头结束的地方是 \r\n 然后他的列表长度为 1!也就是说我们可以通过判断长度, 如果切片后的长度为 1,我们就跳出循环, 那么我们拿到的就是我们的请求头数据了!!!!!
别忘记在server调用, 我们来看一下效果
nice!!!!!!!!!,现在我们已经拿到了请求方法, 路由地址, 协议版本和头部了那我们是不是该取拿一下我们的请求体中的内容了
还记得上一期POST请求中, 注意是POST(但不限于POST请求)我们给他加上了请求内容, GET方法同样可以加请求体,
如果没有请求体数据的话就没有这个Content-Length的头部信息, 那我们判断一下如果投不中存在Content-Length我们就需要获取请求体中的数据, 不然会数据丢失
还记得我们的数据包是怎么样的吧, 下面发送了username(用户名), password(密码)数据之间用&连接
那么很简单我们获取到数据先以 & 进行切片拿到每一项, 在以 = 切片拿到键值和值
这样就完成了! 可能有的人会问为什么!!!这他妈不是最后一行数据了吗??你**怎么不直接readline()????你*吧!(内心戏)。我们要遵循规范!Content-Length是多少我们就取多少!
我们来看一下效果
好了body我们也拿到了!, 有没有发现少了什么呢??我们的 url 传参!!!还没拿呢!
我先来随便乱发点东西,通过url。可能这个时候有人问数据不都取完了吗???上哪拿去呀??, (这是我的失误没有在第一期的时候准备好把这个url传参也算进去)确实取完了但他在我们取过的数据中!在我们的 请求路由地址 (route) 里!
我们打印来看一下
OK 我们通过 ? 分割路由地址和参数, 以 & 分割每一个参数, 以 = 分割拿到键值和值,这个操作我们得在处理第一行数据的时候进行
查看处理HTTP数据包的结果
我们来看一下我们处理请求数据包的结果
HTTP请求数据包的解析我们就完成了!下期我们处理一下返回数据包