golang http断点续传

发布时间:2024-11-22 00:25:20

HTTP断点续传是一个在网络传输中常见的功能。在文件传输过程中,如果因为网络不稳定或其他原因导致传输中断,传统的HTTP协议需要重新下载整个文件。而HTTP断点续传则可以在传输中断后,从中断处继续传输,避免了重复下载,提高了传输效率。

如何实现HTTP断点续传?

要实现HTTP断点续传,首先需要服务器端支持该功能。在Go语言中,可以使用net/http包来实现HTTP服务器,并结合range请求头来实现断点续传。

1. 服务器端代码

在服务器端,我们需要处理range请求头,并根据请求头中的范围返回相应的文件内容。下面是一个简单的示例:

func handleFileDownload(w http.ResponseWriter, r *http.Request) {
    file, err := os.Open("path/to/file")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    defer file.Close()

    fileInfo, err := file.Stat()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    fileSize := fileInfo.Size()

    start, end := getInt64Range(r.Header.Get("Range"), fileSize)

    w.Header().Set("Content-Type", "application/octet-stream")
    w.Header().Set("Content-Length", strconv.FormatInt(end-start+1, 10))
    w.Header().Set("Accept-Ranges", "bytes")
    w.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", start, end, fileSize))

    file.Seek(start, 0)

    io.CopyN(w, file, end-start+1)
}

func getInt64Range(rangeHeader string, size int64) (start, end int64) {
    if rangeHeader == "" {
        return 0, size - 1
    }

    parts := strings.SplitN(rangeHeader, "=", 2)
    if len(parts) != 2 || parts[0] != "bytes" {
        return 0, size - 1
    }

    rangeStr := parts[1]
    rangeParts := strings.SplitN(rangeStr, "-", 2)
    if len(rangeParts) != 2 {
        return 0, size - 1
    }

    startStr := rangeParts[0]
    endStr := rangeParts[1]

    start, _ = strconv.ParseInt(startStr, 10, 64)
    end, _ = strconv.ParseInt(endStr, 10, 64)

    if start >= size {
        start = size - 1
    }
    if end >= size {
        end = size - 1
    }

    return start, end
}

相关推荐