上一篇中我们实现了接受浏览器的请求,并返回本地的网页给浏览器展示,接下来对该简单的功能进行下一步完善
Content-Type
http响应头中非常重要的一个字段是Content-Type,它决定了浏览器如何解析返回的响应内容,如果该字段缺失则默认为text/html格式,因此我们上文返回的简单html网页并没有添加该字段,浏览器也能正常解析。
但是稍微复杂的前端页面都包含了css样式文件,JavaScript脚本文件等,如果不指定Content-Type字段,则浏览器无法正确解析这些文件(有些浏览器超强的兼容性可以一定程度上自动判断内容格式)
因此我们在返回本地的文件作为响应时,需要手动设置Content-Type字段,判断依据为文件的扩展名,这里使用了一个map维护扩展名与Content-Type映射关系。
1 | void HttpResponse::init_content_type_map(){ |
这里添加了一些常用格式的Content-Type类型,后续涉及到更复杂的文件类型时对其进一步扩展
gzip压缩
在http响应的结构中,我们常常可以看到一个名为Content-Encoding的字段,其值大多为gzip,deflate等。该字段决定的是http响应体的编码格式。目前主流浏览器均支持gzip等格式的压缩格式。使用压缩格式的最大好处就是减少网络传输的信息量,提高网页加载速度,但由于服务端多了压缩的步骤,也一定程度增加了服务器的负担(客户端单次处理时,解压的影响可以忽略不计)。
而gzip格式又是应用最广泛的一种压缩格式,其对文本内容的压缩率常常可以达到40%以上,对于html,css,javascript文件均有着非常好的压缩效果。
本文实现的Minihttpd为了增加gzip格式的压缩功能使用了zlib库,其代码均为c编写,使用方法相对简单,这里列出部分供参考
1 | //raw_data为原始数据,buffer为压缩后数据存储缓冲区,buffer_size为缓冲区大小,返回值为压缩后数据字节数 |
主要工作流程为:
- deflateInit2() 设置压缩格式等信息
- deflate() 进行压缩
- deflateEnd() 压缩完毕释放临时空间等收尾工作
编码格式判别
接收到http请求后,首先判断请求头中是否包含Accept-Encoding字段,如果存在,检查其后面接受的压缩格式等,决定是否使用gzip压缩(注意响应头也需要添加Content-Encoding:gzip字段)
####Github
https://github.com/njuwuyuxin/MiniHttpd
欢迎共同学习