断点续传
1.思路:分客户端和服务端,客户端发给服务端时的Get请求,带Range:bytes=0-500 字段
服务端判断Get请求中带Range字段就为断点续传。
服务端处理:获取到Get请求的Range字段后进行解析:对Range字段进行分段(客户端带来的字段多种多样)。然后添加响应206消息的头域等所需要的头域字段,进行续传。
//判断是否为断点续传,分析Range字段,并进行头域拼装。
var range_ext = r.Header.Get("Range") //断点续传标志
data, err := ioutil.ReadAll(rsp.Body)
if range_ext != "" {
slog.Info("part download!")
slog.Info("head range is:%s", range_ext)
var FileStreamSize int64 = rsp.ContentLength
var FileStreamLen string = strconv.FormatInt(FileStreamSize, 10)
length := strings.Index(range_ext, "=")
allrange := range_ext[length+1:]
remove := strings.Index(allrange, "-")
prelen := allrange[:remove]
behind := allrange[remove+1:]
var start int64
var end int64
if prelen == "" {
behindint, _ := strconv.ParseInt(behind, 10, 64)
start = FileStreamSize - behindint
end = FileStreamSize
FileStreamLen = behind
}
if behind == "" {
prelenint, _ := strconv.ParseInt(prelen, 10, 64)
start = prelenint
end = FileStreamSize
FileStreamLen = strconv.FormatInt(end-start, 10)
}
if prelen != "" && behind != "" {
prelenint, _ := strconv.ParseInt(prelen, 10, 64)
behindint, _ := strconv.ParseInt(behind, 10, 64)
start = prelenint
end = behindint
FileStreamLen = strconv.FormatInt(end-start+1, 10)
}
slog.Info("start:%t,end:%t,allrange:%s,FileSize:%t,FileLen:%t", start,end,allrange,FileStreamSize, FileStreamLen)
w.Header().Add("Accept-Ranges", "bytes")
w.Header().Add("Etag", etag)
w.Header().Add("Content-Length", FileStreamLen)
w.Header().Add("Content-Range", "bytes "+allrange+"/"+strconv.FormatInt(FileStreamSize, 10))
w.WriteHeader(206)
w.Write(data[start:end])
rsp.Body.Close()
slog.Info("w Wirte finished")
}
}