Skip to content

支持断点续传#4558

Merged
Glavo merged 11 commits into
HMCL-dev:mainfrom
Glavo:download
May 9, 2026
Merged

支持断点续传#4558
Glavo merged 11 commits into
HMCL-dev:mainfrom
Glavo:download

Conversation

@Glavo
Copy link
Copy Markdown
Member

@Glavo Glavo commented Sep 27, 2025

在下载失败重试时尝试从失败处继续下载,而不是从头开始下载。

@Glavo Glavo marked this pull request as ready for review May 7, 2026 13:52
@Glavo
Copy link
Copy Markdown
Member Author

Glavo commented May 7, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements HTTP download resuming by introducing HttpResumeContext and updating FetchTask to handle range requests and 206 Partial Content responses. It refactors the Context architecture to include a reset() method, migrates file operations to FileChannel for better control, and introduces UrlResponseInfo to decouple caching logic from the HttpResponse class. Feedback was provided regarding the progress reporting logic, noting that using local request counters during a resumed download could cause the progress bar to reset incorrectly, and a specific fix was suggested to use the resume context for accurate progress tracking.

Comment on lines +237 to +238
if (resume != null)
resume.countUncompressed += len;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

在断点续传的情况下,目前的进度更新逻辑(位于第 242 行,虽然不在本次 diff 中直接修改,但受本次修改影响)会导致进度条重置。counter.downloaded 仅代表当前 HTTP 请求已下载的字节数,而 contentLength206 Partial Content 响应中仅代表剩余待下载的字节数。为了提供正确的进度反馈,应当使用 resume 上下文中的总长度和累计已下载字节数。建议修改第 242 行为:

updateProgress(resume != null ? resume.countUncompressed : counter.downloaded, resume != null ? resume.contentLength : contentLength);

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 在 FetchTask 的 HTTP 下载重试流程中引入断点续传能力:当下载在中途失败时,后续重试会尝试携带 Range 请求从已写入的位置继续下载(在满足服务器与响应头条件时),以减少重复流量与重下成本。

Changes:

  • FetchTask.downloadHttp 中新增基于 Accept-Ranges / Content-Range / Last-Modified 等条件的续传判定与重试续传流程,并为可重试的 Context 增加 reset() 机制。
  • 缓存相关接口从直接依赖 HttpResponse 调整为传递 UrlResponseInfo(URI + headers),降低耦合并适配新流程。
  • 新增 FetchTaskTest,覆盖校验失败不覆盖目标文件、无效 Content-Range 触发全量回退、有效 Content-Range 成功续传等场景。

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
HMCLCore/src/test/java/org/jackhuang/hmcl/task/FetchTaskTest.java 新增本地 HTTP 服务器测试,验证重试续传/回退与校验行为
HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/UrlResponseInfo.java 新增用于缓存层的响应元信息载体(URI + headers)
HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/NetworkUtils.java 增加从 HttpResponse 提取 ResponseInfo 的工具方法
HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/ContentEncoding.java fromResponse 改为基于 HttpHeadersfromHeaders
HMCLCore/src/main/java/org/jackhuang/hmcl/util/CacheRepository.java 缓存写入接口改为接收 UrlResponseInfo,避免直接依赖 HttpResponse
HMCLCore/src/main/java/org/jackhuang/hmcl/task/GetTask.java Context 支持 reset(),并适配缓存接口变更
HMCLCore/src/main/java/org/jackhuang/hmcl/task/FileDownloadTask.java Context 支持 reset();写入改为 FileChannel 以支持多次重试/续写;适配缓存接口
HMCLCore/src/main/java/org/jackhuang/hmcl/task/FetchTask.java 核心:实现 HTTP 下载重试的断点续传逻辑,新增 Context.reset() 与续传上下文
HMCLCore/src/main/java/org/jackhuang/hmcl/task/CacheFileTask.java Context 支持 reset();适配缓存接口变更
HMCLCore/src/main/java/org/jackhuang/hmcl/auth/offline/Skin.java Context 支持 reset();适配缓存接口变更
HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaBundle.java 包装下载 Context 时转发 reset() 并修正 withResult 行为

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread HMCLCore/src/main/java/org/jackhuang/hmcl/task/FetchTask.java Outdated
Comment thread HMCLCore/src/main/java/org/jackhuang/hmcl/task/FetchTask.java
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@Glavo
Copy link
Copy Markdown
Member Author

Glavo commented May 9, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements HTTP download resume (breakpoint transmission) support and refactors the download task architecture. Key changes include the introduction of HttpResumeContext to track progress across retries, the addition of a reset() method to the Context interface for clean task restarts, and a transition from OutputStream to FileChannel in file-based tasks. Additionally, it decouples caching logic from the HttpResponse object using a new UrlResponseInfo record and adds unit tests for download retry and resume behaviors. Feedback suggests improving the accuracy of progress reporting during resumed downloads and explicitly resetting the file channel position after truncation to ensure robustness.

Comment on lines +237 to +238
if (resume != null)
resume.countUncompressed += len;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

在断点续传的情况下,counter.downloadedcontentLength 仅代表当前分段的下载进度。这会导致进度条在重试并开始续传时从 0% 重新开始,从而给用户带来误导。建议修改后续的 updateProgress 调用(第 242 行),在 resume 不为空时使用 resume.countUncompressedresume.contentLength 来更新总进度。

Comment thread HMCLCore/src/main/java/org/jackhuang/hmcl/task/CacheFileTask.java
@Glavo
Copy link
Copy Markdown
Member Author

Glavo commented May 9, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for resuming HTTP downloads by implementing partial content handling using Range and If-Range headers. It adds an HttpResumeContext to FetchTask to manage download state and introduces a reset() method to the Context class to handle download restarts. File-based tasks now utilize FileChannel for efficient data management and truncation. Additionally, the caching layer was refactored to use a new UrlResponseInfo record, and comprehensive unit tests were added to verify various resume and retry scenarios. I have no feedback to provide.

@Glavo Glavo merged commit 72b3c19 into HMCL-dev:main May 9, 2026
2 checks passed
@Glavo Glavo deleted the download branch May 9, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants