Range,If-Range,If-Match是HTTP中的几个头字段,其中Range和If-Range配合可以实现断点续传,If-Match也可以和Range配合,但底层逻辑确是不同。
Range: 按指定范围获取资源,范围越界报416。
If-Range: 断点续传恢复时,用If-Range携带上次获得的资源的etag或Last-Modified检查资源是否已发生变化,是则需要重新下载整个资源,否则取本次Range指定范围的资源。无论是否匹配都只会返回200。
If-Match: 如果资源未变动,则上传资源,否则报412。
btw: MDN上关于If-Match的描述有点小错误,即If-Match不匹配时,报412而不是416,更关键的是If-Match和Range虽然可以搭配使用,逻辑上不符合断点续传的要求,所以业务中,就不要使用Range+If-Match了。博主还提了一个PR,现在已经修正。
下面是一个实际的例子,包括了13个case。
其中使用了一个letter.txt文件作为资源文件。
[root@test01 conf]# cat ../html/letter.txt
abcdefghijklmnopqrstuvwxyz
server {
listen 80;
server_name test;
root html;
access_log logs/200_range_access.log main;
error_log logs/200_range_error.log debug;
location / {
#本例验证Range,If-Range,If-Match使用文件letter.txt
}
}
#测试实例
#case1:验证letter.txt可访问
#[root@test01 conf]# curl test/letter.txt
#abcdefghijklmnopqrstuvwxyz
#case2:取etag
#[root@test01 conf]# curl test/letter.txt -I
#HTTP/1.1 200 OK
#Server: nginx/1.20.1
#Date: Wed, 06 Apr 2022 02:00:38 GMT
#Content-Type: text/plain; charset=utf-8
#Content-Length: 27
#Last-Modified: Fri, 03 Sep 2021 02:13:49 GMT
#Connection: keep-alive
#ETag: "613184dd-1b"
#Accept-Ranges: bytes
#
#case3:If-Match匹配etag
#[root@test01 conf]# curl test/letter.txt -H 'If-Match: "613184dd-1b"' -I
#HTTP/1.1 200 OK
#Server: nginx/1.20.1
#Date: Wed, 06 Apr 2022 02:01:00 GMT
#Content-Type: text/plain; chars