C++第三方库【httplib】断点续传
什么是断点续传

上图是我们平时在浏览器下载文件的场景,下载的本质是数据的传输。当出现网络异常,浏览器异常,或者文件源的服务器异常,下载都可能会终止。而当异常解除后,重新下载文件,我们希望从上一次下载的位置开始下载,而不是从头开始下载。这就是断点续传
断点续传的实现
ETag头部字段
ETag是用来标识文件的头部字段,由用户自己设定,其目的是表示文件的唯一性,修改过的文件和原文件是不同的。
ETag由服务端设置
static void download(const httplib::Request& req, httplib::Response& resp)
{//......//服务端设置ETag头部字段resp.set_header("ETag", "......");//......
}
浏览器解析响应,发现有ETag字段,保存并在下次发送GET请求时包含。ETag搭配Range字段实现断点续传
Range
当服务端返回的响应中有Accept-Ranges头部字段,代表服务端允许断点续传
客户端此时发送的请求可以携带Range头部字段,形式如下:
//服务端响应设置允许断点续传
static void download(const httplib::Request& req, httplib::Response& resp)
{//......//bytes表示客户端数据请求区间的单位resp.set_header("Accept-Ranges", "bytes");//......
}//客户端请求断点续传区间
static void download(const httplib::Request& req, httplib::Response& resp)
{//......//val是服务端上一次发送的ETagres.set_header("If-Range", ETag);//val的bytes是服务端返回的断点区间的单位//start-end代表重传start到end区间的数据,比如5430-66758res.set_header("Range", "bytes=start-end");//......
}//服务端返回响应
static void download(const httplib::Request& req, httplib::Response& resp)
{//......//响应的文件数据范围是start-end,文件总大小为fsizeresp.set_header("Content-Range, "start-end/fsize");//重新设置ETagresp.set_header("ETag", "......");//......
}
- 服务端设置Accept-Range字段,val值一般为bytes。该字段表示服务端支持断点续传,以字节单位传输数据
- ETag表示服务端上某一版本资源的唯一标识,如果资源被改动,则ETag改变。客户端收到ETag表示会保存
当下载中断时,浏览器重新下载文件,则第二次的http请求需要包含If-Range字段和Range字段
- If-Range字段:保存服务端响应的ETag字段的信息。用于服务端判断是否和上一次请求的资源一致,一致则断点续传,不一致则从头重新下载
- Range字段:记录断点请求的数据区间,bytes start-end,表示请求服务器资源从第start字节开始到第end个字节的数据
收到客户端发送的断点续传的http响应,需要包含Content-Range字段和ETag字段4
- Content-Range: start-end/文件大小,表示http响应包含文件数据从start开始到end结束的文件数据,文件大小表示文件总大小
- ETag:服务端资源的唯一标识
当服务端返回的数据是断点续传的数据区间时,状态码是206
示例断点续传的请求&响应如下:
GET /download/a.txt http/1.1
If-Range: "文件唯一标识"
Range: bytes=89-999
-------------------------------------------
HTTP/1.1 206 Partial Content
Accept-Ranges: bytes
Content-Range: bytes 89-999/100000
Content-Type: application/octet-stream
ETag: "文件唯一标识"对应文件从89到999字节的数据。
编码实现
使用httplib实现断点续传。
基本逻辑:
- 查看客户端请求是否包含If-Range字段,有则匹配请求文件的ETag,没有则是正常下载文件
- 若相同,说明客户端请求断点续传,解析Range字段,将start-end的数据填入响应的正文部分。并设置头部字段
- 若不同,说明客户端请求的数据被修改了,则需要从头下载,返回文件全部数据。并设置头部字段
以上逻辑,我们需要手动解析客户端响应的Range字段,但httplib已经帮我们解析了,以下源码是httplib做的部分处理

这部分表示,httplib解析客户端请求,如果包含Range字段,会自动设置响应的状态码为206

这部分是httplib解析Range字段,在返回文件数据时,会根据Range字段的解析结果,截断文件数据。所以我们在代码编写时不管是正常下载,还是断点续传都直接响应文件全部数据即可, 如果是断点续传,httplib会帮我们进行数据截断,如果start-end是5430-66347,就截出这部分数据返回给客户端
示例代码如下:
//生成ETag
//ETag = 文件名 + 文件大小 + 文件最后一次修改时间
static std::string getETag(const std::string& filename, const struct stat st)
{std::string ETag;ETag = filename + std::to_string(st.st_size) + std::to_string(st.m_tim);return ETag;
} //返回客户端要下载的文件
static void download(const httplib::Request& req, httplib::Response& resp)
{//1. 获取客户端请求的资源路径:req.path。截取最后一个/后的字符串,为文件名//2. 根据资源路径,获取文件信息auto pos = req.path.find_last_of('/');std::string filenameif(pos == std::string::npos)filename = req.path;elsefilename = req.path.substr(pos + 1);struct stat st;stat(filename.c_str(), &st);//查看请求是否有If-Range(记录之前服务器响应的ETag)bool retrans = true;std::string old_etag;//有If-Range,两种可能:有修改,全部重传;没有修改,断点续传if(req.has_header("If-Range")){old_etag = req.get_header_value("If-Range");if(old_etag == getETag(info, st))retrans = false;}//4. 读取文件信息到响应中std::ifstream ifs(filename.c_str(), std::ios::binary);//读取文件内容body.resize(st.s_size);ifs.read(&body[0], st.s_size);//5. 设置头部字段resp.set_header("ETag", getETag(info, st));resp.set_header("Accept-Ranges", "bytes");//提供断点续传resp.set_header("Content-Type", "application/octet-stream");//下载文件if(retrans){//文件有修改,需要重传文件//ETag Accept-Ranges bytes(断点续传)resp.status = 200;}else{//断点续传实现:获取头部字段中Range:bytes start-end,解析请求文件的起始和结束//再返回响应时,对文件内容进行截断//但httplib都实现了,他检测到req中有Range,然后进行处理,甚至会设置resp的状态码//我们只要返回完整的文件,httplib会对文件进行截断,最后响应正文中只有start-end的文件内容//resp.set_header("Content-Range", "bytes start-end/fsize");//原本还要设置这个头部字段,httplib帮我们做了resp.status = 206;//断点续传的状态码}
}
相关文章:
C++第三方库【httplib】断点续传
什么是断点续传 上图是我们平时在浏览器下载文件的场景,下载的本质是数据的传输。当出现网络异常,浏览器异常,或者文件源的服务器异常,下载都可能会终止。而当异常解除后,重新下载文件,我们希望从上一次下载…...
[SaaS] AI+数据,tiktok选品,找达人,看广告数据
TK观察专访丨前阿里“鲁班”创始人用AIGC赋能TikTok获千万融资用AI数据做TikTokhttps://mp.weixin.qq.com/s/xp5UM3ROo48DK4jS9UBMuQ主要还是爬虫做数据的。 商家做内容:1.找达人拍内容,2.商家自己做原生自制内容,3.广告内容。 短视频&…...
A股冲高回落,金属、地产板块领跌,新股N汇成真首日暴涨753%
行情概述 AH股有色金属、教育及地产板块领跌,军工航天及半导体板块逆势走强;锂电池、创新药概念股也走强。创业板新股N汇成真首日暴涨753%,触发二次临停。 周三A股冲高回落,上证指数收跌0.83%,深成指跌0.8%ÿ…...
dns域名解析服务和bond网卡
目录 dns域名解析服务 一、DNS 1、定义 2、以www.baidu.com为例 3、域名体系结构 4、DNS解析使用的协议和端口 5、dns域名解析的过程 6、dns解析的优先级 二、如何实现域名解析 1、域名解析 2、bind配置文件位置 (一)正向解析 (…...
视频生成框架EasyAnimate正式开源!
近期,Sora模型的热度持续上涨,社区中涌现了一些类Sora的开源项目,这些项目均基于Diffusion Transformer结构,使用Transformer结构取代了UNet作为扩散模型的基线,旨在生成更长、更高分辨率、且效果更好的视频。EasyAnim…...
【微机原理与汇编语言】并行接口8255实验
一、实验目的 掌握可编程并行接口芯片8255的工作原理及初始化方法掌握8255在实际应用中的硬件连接及编程应用 二、实验要求 根据实验室现有条件,针对实验任务,设计实验方案并进行实现。 三、实验内容 启动0#计数器,每计5个数(…...
Oracle表分区的基本使用
什么是表空间 是一个或多个数据文件的集合,所有的数据对象都存放在指定的表空间中,但主要存放的是表,所以称为表空间 什么是表分区 表分区就是把一张大数据的表,根据分区策略进行分区,分区设置完成之后,…...
6月5号作业
设计一个Per类,类中包含私有成员:姓名、年龄、指针成员身高、体重,再设计一个Stu类,类中包含私有成员:成绩、Per类对象p1,设计这两个类的构造函数、析构函数 #include <iostream>using namespace std; class Slu { priv…...
中继器、集线器、网桥、交换机、路由器和网关
目录 前言一、中继器、集线器1.1 中继器1.2 集线器 二、网桥、交换机2.1 网桥2.1.1 认识网桥2.1.2 网桥的工作原理2.1.3 生成树网桥 2.2 交换机2.2.1 交换机的特征2.2.2 交换机的交换模式2.2.3 交换机的功能 三、路由器、网关3.1 路由器的介绍3.2 路由器的工作过程3.2.1 前置知…...
揭秘相似矩阵:机器学习算法中的隐形“纽带”
在机器学习领域,数据的处理和分析至关重要。如何有效地从复杂的数据集中提取有价值的信息,是每一个机器学习研究者都在努力探索的问题。相似矩阵,作为衡量数据之间相似性的数学工具,在机器学习算法中扮演着不可或缺的角色。 相似矩…...
攻防世界—webbaby详解
1.ssrf注入漏洞 ssrf(服务端请求伪造)是一种安全漏洞,攻击者通过该漏洞向受害服务器发出伪造的请求,从而访问并获取服务器上的资源,常见的ssrf攻击场景包括访问内部网络的服务,执行本地文件系统命令&#…...
MySQL中:cmd下输入命令mysql -uroot -p 连接数据库错误
目录 问题cmd下输入命令mysql -uroot -p错误 待续、更新中 问题 cmd下输入命令mysql -uroot -p错误 解决 配置环境变量:高级系统设置——环境变量——系统变量——path编辑——新建——MySQL.exe文件路径(如下图所示) phpstudy2018软件下&am…...
【开发利器】使用OpenCV算子工作流高效开发
学习《人工智能应用软件开发》,学会所有OpenCV技能就这么简单! 做真正的OpenCV开发者,从入门到入职,一步到位! OpenCV实验大师Python SDK 基于OpenCV实验大师v1.02版本提供的Python SDK 实现工作流导出与第三方应用集…...
基础数学-求平方根(easy)
一、问题描述 二、实现思路 1.题目不能直接调用Math.sqrt(x) 2.这个题目可以使用二分法来缩小返回值范围 所以我们在left<right时 使 mid (leftright)/21 当mid*mid>x时,说明right范围过大,rightright-1 当mid*mid<x时,说明left范…...
c语言项目-贪吃蛇项目2-游戏的设计与分析
文章目录 前言游戏的设计与分析地图:这里简述一下c语言的国际化特性相关的知识<locale.h> 本地化头文件类项setlocale函数 上面我们讲到需要打印★,●,□三个宽字符找到这三个字符打印的方式有两种: 控制台屏幕的长宽特性&a…...
力扣2831.找出最长等值子数组
力扣2831.找出最长等值子数组 思路:用二维数组存每个数字的出现下标 遍历所有数字求结果当前子数组大小:pos[i] - pos[j] 1;当前相同数个数:i - j 1;需要删去的数的个数:pos[i] - pos[j] - i j; class Solution {public:int…...
17K star,一款开源免费的手机电脑无缝同屏软件
导读:白茶清欢无别事,我在等风也等你。 作为程序员,在我们的工作中经常需要把手机投票到电脑进行调试工作,选择一款功能强大的投屏软件是一件很必要的事情。今天给大家介绍一款开源且免费的投屏软件,极限投屏ÿ…...
正则表达式二
修饰符 i:将匹配设置为不区分大小写,即A和a没有区别 var str"Google Runoob taobao runoob"; var n1str.match(/runoob/g); //runoob var n2str.match(/runoob/gi); //Runoob,runoobg:重找所有匹配项࿰…...
我的创作纪念日--我和CSDN一起走过的1825天
机缘 第一次在CSDN写文章,是自己在记录学习Java8新特性中Lambda表达式的内容过程中收获的学习心得。之前也有记录工作和生活中的心得体会、难点的解决办法、bug的排查处理过程等等。一直都用的有道笔记,没有去和大家区分享的想法,是一起的朋…...
递归书写树形图示例
大叫好,今天书写了一个扁型转换为树型的例子,使用的是递归,请大家食用,无毒 <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name"viewport" conte…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
