You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTTP服务器处理Range GET请求时少返回1字节问题求助

多线程分块下载最后一块缺失1字节的问题分析与解决

问题场景

实现多线程分块HTTP下载器时,仅最后一块出现异常:服务器返回的内容比请求的Range少1字节。

请求与响应详情

发送的HTTP GET请求:

GET /idman642build20.exe HTTP/1.1
Host: mirror2.internetdownloadmanager.com
Range: bytes=8388608-12243840
Connection: close

收到的HTTP GET响应:

HTTP/1.1 206 Partial Content
Date: Sat, 31 Aug 2024 18:08:40 GMT
Server: Apache/2.4.37 (AlmaLinux) OpenSSL/1.1.1k
Last-Modified: Tue, 20 Aug 2024 21:29:03 GMT
ETag: "bad380-620241d5e53f9"
Accept-Ranges: bytes
Content-Length: 3855232
Content-Range: bytes 8388608-12243839/12243840
Connection: close
Content-Type: application/octet-stream

可见请求的Range为bytes=8388608-12243840,但服务器返回的Content-Range为bytes 8388608-12243839/12243840,少了最后1字节,且该问题仅出现在文件的最后一块。

问题原因

这并非服务器Bug,而是符合HTTP规范(RFC 7233)的行为:

  • HTTP字节范围的索引从0开始计数,文件总大小为total_size时,最后一个有效字节的位置是total_size - 1
  • 当请求的Range结束值大于等于文件总大小时,服务器会自动将结束值调整为total_size - 1,返回从起始位置到文件末尾的所有字节

在这个案例中,文件总大小是12243840,请求的结束值12243840超出了有效字节索引范围,因此服务器将其修正为12243839,导致返回的内容看起来比请求少1字节,但实际是正确的完整最后一块。

解决方案

调整最后一块的Range请求方式,避免指定超出范围的结束值:

方案1:计算正确的结束位置

在分块计算时,对最后一块的结束位置做限制:

# 示例伪代码
total_size = 12243840
chunk_size = 8388608  # 示例块大小
start = 8388608
end = min(start + chunk_size - 1, total_size - 1)  # 确保结束位置不超过最后一个有效字节
range_header = f"bytes={start}-{end}"

方案2:省略结束值

直接省略Range的结束部分,让服务器自动返回从起始位置到文件末尾的所有字节:

GET /idman642build20.exe HTTP/1.1
Host: mirror2.internetdownloadmanager.com
Range: bytes=8388608-
Connection: close

两种方案都能确保获取到完整的最后一块内容,避免出现“缺失字节”的误解。

内容的提问来源于stack exchange,提问作者Abhishek Sagar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 23:22:23