Skip to content

文件下载

包级下载函数

Download

go
func Download(ctx context.Context, url string, cfg *DownloadConfig, options ...RequestOption) (*DownloadResult, error)

使用默认客户端下载文件。Download 是贯穿包级函数、Client 接口和 DomainClient唯一规范下载入口,用单一签名取代了以往的变体矩阵。cfg 不能为 nil,且 cfg.FilePath 必须设置(否则返回 ErrEmptyFilePath)。

go
cfg := httpc.DefaultDownloadConfig()
cfg.FilePath = "/tmp/file.zip"
cfg.Overwrite = true
cfg.ResumeDownload = true

result, err := httpc.Download(context.Background(), url, cfg)

DownloadConfig

go
type DownloadConfig struct {
    FilePath          string
    ProgressCallback  DownloadProgressCallback
    Overwrite         bool
    ResumeDownload    bool
    Checksum          string
    ChecksumAlgorithm ChecksumAlgorithm
}

func DefaultDownloadConfig() *DownloadConfig
字段类型默认说明
FilePathstring-保存路径(必填)
ProgressCallbackDownloadProgressCallbacknil进度回调函数
Overwriteboolfalse覆盖已存在的文件
ResumeDownloadboolfalse启用断点续传
Checksumstring""期望的校验和值
ChecksumAlgorithmChecksumAlgorithm"sha256"校验和算法

DownloadProgressCallback

go
type DownloadProgressCallback func(downloaded, total int64, speed float64)
参数类型说明
downloadedint64已下载字节数
totalint64总字节数(-1 表示未知)
speedfloat64当前速度(字节/秒)
go
cfg.ProgressCallback = func(downloaded, total int64, speed float64) {
    pct := float64(downloaded) / float64(total) * 100
    fmt.Printf("\r%.1f%% (%s)", pct, httpc.FormatSpeed(speed))
}

DownloadResult

go
type DownloadResult struct {
    FilePath        string
    BytesWritten    int64
    Duration        time.Duration
    AverageSpeed    float64
    StatusCode      int
    ContentLength   int64
    Resumed         bool
    ResponseCookies []*http.Cookie
    ActualChecksum  string
    Proto           string
    ResponseHeaders http.Header
    RequestURL      string
    RequestMethod   string
    RequestHeaders  http.Header
}
字段类型说明
FilePathstring文件保存路径
BytesWrittenint64写入字节数
Durationtime.Duration下载耗时
AverageSpeedfloat64平均速度(字节/秒)
StatusCodeintHTTP 状态码
ContentLengthint64Content-Length 头值
Resumedbool是否为续传完成
ResponseCookies[]*http.Cookie响应 Cookie
ActualChecksumstring实际计算的校验和
ProtostringHTTP 协议版本(如 "HTTP/1.1""HTTP/2.0"
ResponseHeadershttp.Header响应头
RequestURLstring实际请求 URL
RequestMethodstring请求 HTTP 方法
RequestHeadershttp.Header请求头
go
fmt.Printf("下载完成: %s, 耗时 %v, 平均速度 %s\n",
    httpc.FormatBytes(result.BytesWritten),
    result.Duration,
    httpc.FormatSpeed(result.AverageSpeed),
)

TIP

使用 FormatBytesFormatSpeed 可获得人类可读的字节与速率字符串,避免手动换算 1024 进位。

校验和验证

ChecksumAlgorithm

go
type ChecksumAlgorithm string

下载文件完整性校验算法。

常量说明
ChecksumSHA256"sha256"SHA-256 哈希算法

使用示例

go
cfg := httpc.DefaultDownloadConfig()
cfg.FilePath = "/tmp/package.tar.gz"
cfg.Checksum = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
cfg.ChecksumAlgorithm = httpc.ChecksumSHA256

result, err := httpc.Download(context.Background(), url, cfg)
if err != nil {
    // 校验和不匹配时自动返回错误并删除已下载文件
    log.Fatal(err)
}
fmt.Println("校验和:", result.ActualChecksum)

TIP

设置 Checksum 后,下载完成时会自动校验文件完整性。校验失败会自动删除文件并返回错误,无需手动比较。

安全保护

文件下载内置多层安全防护:

保护说明
UNC 路径阻止禁止 \\server\share 格式路径
控制字符过滤禁止路径中的控制字符
系统路径保护禁止写入系统目录
路径遍历检测检测 ../ 路径遍历
符号链接检测防止符号链接攻击
父目录检测递归检查父目录符号链接

断点续传

go
cfg := httpc.DefaultDownloadConfig()
cfg.FilePath = "/tmp/large-file.zip"
cfg.ResumeDownload = true

result, err := httpc.Download(context.Background(), url, cfg)
if result.Resumed {
    fmt.Println("续传完成")
}

续传机制:

  1. 检查本地文件大小 → 作为 Range 请求偏移量
  2. 服务端返回 206 (Partial Content) → 追加写入
  3. 服务端返回 416 (Range Not Satisfiable) → 返回错误
  4. 服务端返回 200(不支持 Range)→ 返回错误(保护本地部分文件不被覆盖)

另见