当客户端发起对/range
路径的请求时,可以在handlerrange
函数中实现支持范围下载功能。以下是一个简单的示例代码:
func handlerrange(w http.ResponseWriter, r *http.Request) {
// 获取要处理的文件路径
filePath := "/path/to/file.ext"
// 打开文件
file, err := os.Open(filePath)
if err != nil {
http.Error(w, "Failed to open file", http.StatusInternalServerError)
return
}
defer file.Close()
// 获取文件信息
fileInfo, err := file.Stat()
if err != nil {
http.Error(w, "Failed to get file info", http.StatusInternalServerError)
return
}
// 获取请求头中的Range字段值
rangeHeader := r.Header.Get("Range")
if rangeHeader == "" {
http.Error(w, "Missing Range header", http.StatusBadRequest)
return
}
var start, end int64
if strings.HasPrefix(rangeHeader, "bytes=") {
rangeValue := strings.TrimPrefix(rangeHeader, "bytes=")
byteRangeParts := strings.SplitN(rangeValue, "-", 2)
startStr := byteRangeParts[0]
endStr := byteRangeParts[1]
// 处理start和end值为空情况(例如:bytes=100- 或 bytes=-500)
if startStr == "" && endStr != "" {
end, _ = strconv.ParseInt(endStr, 10, 64)
start = fileInfo.Size() - end
end = fileInfo.Size() - 1
} else if startStr != "" && endStr == "" {
start, _ = strconv.ParseInt(startStr, 10, 64)
end = fileInfo.Size() - 1
} else {
start, _ = strconv.ParseInt(startStr, 10, 64)
end, _ = strconv.ParseInt(endStr, 10, 64)
}
// 设置Content-Range响应头
w.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", start, end, fileInfo.Size()))
} else {
http.Error(w, "Invalid Range header", http.StatusBadRequest)
return
}
contentLength := end - start + 1
// 设置Content-Length和Content-Type响应头
w.Header().Set("Content-Length", strconv.FormatInt(contentLength, 10))
w.Header().Set("Content-Type", "application/octet-stream")
buffer := make([]byte, 1024)
_, err = file.Seek(start, io.SeekStart)
if err != nil {
http.Error(w, "Failed to seek file", http.StatusInternalServerError)
return
}
for remainingBytes := contentLength; remainingBytes > 0; {
numBytesToRead := int64(len(buffer))
if remainingBytes < numBytesToRead {
numBytesToRead = remainingBytes
}
numBytesRead, err := file.Read(buffer[:numBytesToRead])
if err != nil && err != io.EOF {
http.Error(w, "Failed to read from file", http.StatusInternalServerError)
return
}
if numBytesRead == 0 {
break
}
w.Write(buffer[:numBytesRead])
remainingBytes -= int64(numBytesRead)
}
}
请注意,上述代码只是一个简单的示例,你可能需要根据具体情况进行修改和完善。
内容由零声教学AI助手提供,问题来源于学员提问