http协议之Range

news2025/1/17 14:10:23

http协议中可能会遇到:请求取消或数据传输中断,这时客户端已经收到了部分数据,后面再请求时最好能请求剩余部分(断点续传);或者,对于某个较大的文件,能够支持客户端多线程分片下载...

以上在我们平时应用中已经有很多产品支持了,其中原理就和http协议中的Range有关。

Range是在 HTTP/1.1里新增的一个请求头字段域,rfc文档:RFC 7233: Hypertext Transfer Protocol (HTTP/1.1): Range Requests HTTP协议博大精深,设计有很多巧妙的地方,Range也许就是一处吧。

1、Range协议:

1)检查服务端是否支持Range:

客户端发起请求,服务端收到后在response的header中如果有Accept-Ranges:bytes ,表示支持Range。

比如,我们通过curl -I发起一个请求,查看响应头信息:(curl -I 表示Show document info only)

$ curl -I http://127.0.0.1/rt1/2.mp4
HTTP/1.1 200 OK
Server: openresty/1.19.9.1
Date: Thu, 12 Jan 2023 08:04:32 GMT
Content-Type: video/mp4
Content-Length: 505199705
Last-Modified: Fri, 08 Jul 2022 07:09:25 GMT
Connection: keep-alive
ETag: "62c7d825-1e1cbc59"
Accept-Ranges: bytes

上面Accept-Ranges: bytes 表示界定范围的单位是 bytes;Content-Length 表示文件大小。如果服务端响应header内容Accept-Ranges:none 表示不支持!

2)Range协议格式:

客户端在header中添加Range信息,表示发起一次范围请求,格式如下:

Range:unit=first byte pos-[last byte pos]

例如: 单位(如bytes)= 开始字节位置-结束字节位置。

服务端响应在header中添加Range信息:

Content-Range: unit first byte pos-[last byte pos]/[entity length]
例如:Content-Range:字节 开始字节位置-结束字节位置/文件大小。

注:first byte pos从0开始!
看个例子:假设有个文件大小为 5000 个 byte,现要开启多线程下载(比如4个),每个线程负责下载一个部分,那么我们可以划分为:

Range: bytes=0-1199 头1200个字节
Range: bytes=1200-2399 第二个1200字节
Range: bytes=2400-3599 第三个1200字节
Range: bytes=3600-5000 最后的1400字节

服务器给出响应:
// 第1个响应
Content-Length:1200
Content-Range:bytes 0-1199/5000
// 第2个响应
Content-Length:1200
Content-Range:bytes 1200-2399/5000
// 第3个响应
Content-Length:1200
Content-Range:bytes 2400-3599/5000
// 第4个响应
Content-Length:1400
Content-Range:bytes 3600-5000/5000

Content-Length表示对应范围的大小,Content-Range返回和请求对应的范围。

3)Range请求的响应码:

Server通过请求头中的Range: bytes=0-xxx来判断是否是做 Range 请求,如果这个值存在而且有效,则只发回请求的那部分文件内容,响应的状态码变成206,表示Partial Content,并设置Content-Range。如果无效,则返回416状态码,表明Request Range Not Satisfiable。如果请求头中不带 Range,那么 Server则正常响应,也不会设置 Content-Range 等。

  • 206:在请求成功的情况下,服务器会返回 206 Partial Content 状态码。
  • 416:在请求的范围越界的情况下(范围值超过了资源的大小),服务器会返回 416 Requested Range Not Satisfiable (请求的范围无法满足)状态码。
  • 200:服务端不支持Range请求的情况下,服务器会返回 200 OK 状态码。

4)与分块传输编码的对比

Transfer-Encoding 首部允许分块编码,这在数据量很大,并且在请求未能完全处理完成之前无法知晓响应的体积大小的情况下非常有用。服务器会直接把数据发送给客户端而无需进行缓冲或确定响应的精确大小——后者会增加延迟。范围请求与分块传输是兼容的,可以单独或搭配使用。

2、从服务端请求特定范围的数据

1)单一范围:

客户端请求时,可以在header中通过Range表示请求的范围,这时如果服务端支持Range,则会返回206状态码,并返回指定范围的数据,并在header中添加Content-Range;否则不支持,则返回200。

例如:(curl -i 表示打印响应头)

$ curl -i -H "Range: bytes=0-102300"   http://127.0.0.1/f1.txt
HTTP/1.1 206 Partial Content
Server: openresty/1.19.9.1
Date: Thu, 12 Jan 2023 09:34:49 GMT
Content-Type: text/plain
Content-Length: 10
Last-Modified: Thu, 12 Jan 2023 09:34:44 GMT
Connection: keep-alive
ETag: "63bfd434-a"
Content-Range: bytes 0-9/10

123456789

2)多范围:

$ curl -i -H "Range: bytes=0-1,4-5"   http://127.0.0.1/f1.txt
HTTP/1.1 206 Partial Content
Server: openresty/1.19.9.1
Date: Thu, 12 Jan 2023 09:36:21 GMT
Content-Type: multipart/byteranges; boundary=00000000000000000001
Content-Length: 198
Last-Modified: Thu, 12 Jan 2023 09:34:44 GMT
Connection: keep-alive
ETag: "63bfd434-a"


--00000000000000000001
Content-Type: text/plain
Content-Range: bytes 0-1/10

12
--00000000000000000001
Content-Type: text/plain
Content-Range: bytes 4-5/10

56
--00000000000000000001--

Range 头部也支持一次请求文档的多个部分。请求范围用一个逗号分隔开。

服务器返回 206 Partial Content 状态码和 Content-Type:multipart/byteranges; boundary=00000000000000000001 头部,Content-Type:multipart/byteranges 表示这个响应有多个 byterange。每一部分 byterange 都有他自己的 Content-type 头部和 Content-Range,并且使用 boundary 参数对 body 进行划分。

3)条件范围:

当(中断之后)重新开始请求更多资源片段的时候,必须确保自从上一个片段被接收之后该资源没有进行过修改。

The If-Range 请求首部可以用来生成条件式范围请求:假如条件满足的话,条件请求就会生效,服务器会返回状态码为 206 Partial 的响应,以及相应的消息主体。假如条件未能得到满足,那么就会返回状态码为 200 OK 的响应,同时返回整个资源。该首部可以与 Last-Modified 验证器或者 ETag 一起使用,但是二者不能同时使用。

参考:

HTTP 请求范围 - HTTP | MDN

聊一聊HTTP的Range, Content-Range | HappyCoding:)

3、示例:nginx提供视频下载服务

http的Range可以提供范围请求,最重要的应用就是视频播放。

1)nginx配置:

使用openresty的docker景象启动,配置如下

server {
    listen       80;
    server_name  localhost;

    location = /f1.txt {
        root /data/;
    }
    location = /rt1/2.mp4 {
        root /data/;
    }

创建如下文件:/data/rt1/2.mp4 /data/f1.txt

说明:nginx本身支持了Range,我看nginx也提供了ngx_http_slice_module模块(--with-http_slice_module参数),支持Range回源。

2)浏览器访问:

配置好nginx后,通过浏览器访问:http://127.0.0.1/rt1/2.mp4 打开chrome的控制面板,切换到network tab页

可以看到有多个请求,第一个请求的状态码是200,剩余请求的状态码都是206(partial content-部分内容)。而且chrome非常贴心地用内置的视频解码工具来播放MP4文件,还有暂停按钮。(如果开始播放后不暂停,nginx会不断地给chrome吐数据,这个过程不会中断,暂停按钮会中断此次通信,断开connection,此时nginx才会写入access log)。

参考:【nginx】大文件下载 - awildfish - 博客园

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/158717.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

某集团汽车配件电子图册性能分析案例(三)

背景 汽车配件电子图册系统是某汽车集团的重要业务系统。业务部门反映,汽车配件电子图册调用图纸时,出现访问慢现象。 汽车集团总部已部署NetInside流量分析系统,使用流量分析系统提供实时和历史原始流量。本次分析重点针对汽车配件电子图册…

web服务器、中间件和他们的漏洞

目录 Nginx Apache Tomcat IIS 漏洞 Apache解析漏洞 文件名解析漏洞 罕见后缀 .htaccess文件 Ngnix解析漏洞 畸形解析漏洞(test.jpg/*.php) %00空字节代码解析漏洞 CVE-2013-4547(%20%00) IIS解析漏洞 目录解析漏洞(/test.asp/1.jpg) 文件名解析漏洞(test.asp;…

想转行没方向,PMP证书用处大吗?

当下了要转行的决心,你又陷入另一种焦虑中——怎么转?毕竟“隔行如隔山”。要知道缺乏经验,你要面对的是旷日持久的努力、未知的付出和回报转换率。 但别忘了,在山与山之间,有一些纵横交错的道路相连,可以…

详解SpringMVC

1.DispatcherServlet初始化时机 DispatcherServlet是由spring创建的,初始化是由Tomcat完成的,通过setLoadOnStartup来决定是否为tomcat启动时初始化 Configuration ComponentScan // 没有设置扫描包的话默认扫描当前配置的包及其子包 PropertySource(&…

verilog学习笔记- 11)按键控制蜂鸣器实验

简介: 蜂鸣器按照驱动方式主要分为有源蜂鸣器和无源蜂鸣器,其主要区别为蜂鸣器内部是否含有震荡源。一般的有源蜂鸣器内部自带了震荡源,只要通电就会发声。而无源蜂鸣器由于不含内部震荡源,需要外接震荡信号才能发声。 左边为有源…

JAVA JVM学习

1.JVM介绍 越界检查肯定有用,防止覆盖别的地方的代码。 JVM来评价java在底层操作系统的差异。 2.程序计数器 我们java源代码会变成一条一条jvm指令。 在物理上实现程序计数器,是用一个寄存器。这样速度更快。 程序计数器不会内存溢出 2.1 线程私有 …

clickhouse整合ldap,无需重启

测试你的ladp服务ldapsearch -x-bdcexample,dccom -H ldap://ldap.forumsys.com应该输出类似以下的内容# extended LDIF # # LDAPv3 # base <dcexample,dccom> with scope subtree # filter: (objectclass*) # requesting: ALL # ​ # example.com dn: dcexample,dccom o…

【Premake】构建工程

Premake 一、什么是Premake&#xff1f; Premake 是一种命令工具&#xff0c;通过读取项目脚本&#xff0c;来生成各种开发环境的项目文件。 开源地址&#xff1a;https://github.com/premake/premake-core 下载地址&#xff1a;https://premake.github.io 实例地址&#xf…

揭秘HTTP/3优先级

编者按 / 相对于HTTP2&#xff0c;HTTP/3的优先级更加简单&#xff0c;浏览器厂商更可能实现统一的优先级策略。本文来自老朋友Robin Marx&#xff0c;已获授权转载&#xff0c;感谢刘连响对本文的技术审校。翻译 / 核子可乐技术审校 / 刘连响原文链接 / https://calendar.per…

【MySQL数据库入门】:面试中常遇到的 ‘ 数据类型 ’

文章目录数据类型1.数据类型分类2.数值类型2.1 tinyint类型2.2 bit类型2.3 小数类型2.3.1 float2.3.2 decimal3.字符串类型3.1 char3.2 varchar3.3 char和varchar比较4.日期和时间类型5.enum和set数据类型 1.数据类型分类 2.数值类型 2.1 tinyint类型 create table tt1(num t…

解决unable to find valid certification path to requested target

问题描述 最近java程序去调用远程服务器接口时报错了&#xff1a; I/O error on POST request for “https://XXX.xyz/create”: sun.secu rity.validator.ValidatorException: PKIX path building failed: sun.security.provi der.certpath.SunCertPathBuilderException: una…

终极 3D 图形工具包:Ab3d.PowerToys 10.2.X Crack

Ab3d.PowerToys改进了 Ab3d.Utilities.Triangulator 通过添加对带孔的多个多边形进行三角剖分的支持&#xff08;之前只能对没有任何孔的单个多边形进行三角剖分&#xff09;。这可用于从文本创建 3D 网格。 Ab3d.Utilities.PolygonAnalyzer 现在是一个公共类&#xff0c;可用于…

【学习笔记】【Pytorch】五、DataLoader的使用

【学习笔记】【Pytorch】五、DataLoader的使用学习地址主要内容一、DataLoader模块介绍二、DataLoader类的使用1.使用说明2.代码实现好的文章学习地址 PyTorch深度学习快速入门教程【小土堆】. 主要内容 一、DataLoader模块介绍 介绍&#xff1a;分配数据集。 二、DataLoade…

EMS运行数据处理-pandas降采样、合并多表

文章目录read_csv读取出错。因为多余异常列数据解决方法pd.to_datetime(df[time_key])但time_key出现不能转换的序列解决方法pandas 提取时间序列年、月、日方法一:pandas.Series.dt.month() 方法提取月份方法二:strftime() 方法提取年、月、日方法三:pandas.DatetimeIndex.mon…

【阶段三】Python机器学习20篇:机器学习项目实战:AdaBoost回归模型

本篇的思维导图: 项目实战(AdaBoost回归模型) 项目背景 本项目应用AdaBoost回归算法进行项目实战,整体流程包括数据收集、数据预处理、探索性数据分析、特征工程、模型构建及优化、模型评估。 数据收集 本次建模数据来源于网络,数据项统计如下: 编号

问题:在 ArcMap 中编辑数据时,无法使用捕捉功能

问题&#xff1a;在 ArcMap 中编辑数据时&#xff0c;无法使用捕捉功能 说明 编辑时&#xff0c;捕捉命令无法按预期运行。无法连接要素&#xff0c;因为指针没有捕捉到地图文档中的边缘和折点。 原因 此问题可能由以下原因之一引起&#xff1a; 捕捉选项已禁用 当前编辑会…

foxmail 发送邮件到 Poste邮件服务的端口设置

Poste服务器 发件端口设置的是 587 端口&#xff0c;没有开通 465 端口。 在foxmail用户账号设置中&#xff0c;发送端口不使用 ssl 默认是 25&#xff0c;使用 ssl 使用的是 465 端口。 一、无效设置的3种情况 1、在发送邮件的时候&#xff0c;不使用 ssl&#xff0c; 端口…

某固态放大器输出单次微波脉冲信号测量方案

某固态放大器输出单次微波脉冲信号测量方案摘要测量指标范围频率测量测量方案仪器选择衰减器混频器信号发生器频谱分析仪可行性分析脉宽和功率测量方案一方案二仪器选择检波器衰减器示波器可行性分析摘要 某固态放大器输出单次微波脉冲信号测量&#xff0c;需测量单个脉冲的频…

Java锁之ReentrantLock(源码详解)

视频地址Java学习文档 ReentrantLock 这个Java中重要的锁&#xff0c;我想可能很多人只是听过&#xff0c;并没有使用过&#xff0c;我在看RocketMQ客户端源码的时候发现大量的使用了这个ReentrantLock&#xff0c;从而引起了我的兴趣&#xff0c;下面我们一起从源码的角度来学…

JDK7时间相关类超详细总结(含多个实例)

JDK7时间相关类一、概述二、Date类1.构造函数2.常用函数1️⃣格式2️⃣实例三、 SimpleDateFormat类1.概述2.构造方法3.常用方法1️⃣格式2️⃣实例四、Calendar类1.概述2.使用方法3.常用方法4.实例五、结语一、概述 本文主要介绍JDK7中的时间相关类 二、Date类 1.构造函数 …