in oss/checkpoint.go [121:196]
func (cp *downloadCheckpoint) valid() bool {
// Compare the CP's Magic and the MD5
contents, err := os.ReadFile(cp.CpFilePath)
if err != nil {
return false
}
dcp := downloadCheckpoint{}
if err = json.Unmarshal(contents, &dcp.Info); err != nil {
return false
}
js, _ := json.Marshal(dcp.Info.Data)
sum := md5.Sum(js)
md5sum := hex.EncodeToString(sum[:])
if CheckpointMagic != dcp.Info.Magic ||
md5sum != dcp.Info.MD5 {
return false
}
// compare
if !reflect.DeepEqual(cp.Info.Data.ObjectInfo, dcp.Info.Data.ObjectInfo) ||
!reflect.DeepEqual(cp.Info.Data.ObjectMeta, dcp.Info.Data.ObjectMeta) ||
cp.Info.Data.FilePath != dcp.Info.Data.FilePath ||
cp.Info.Data.PartSize != dcp.Info.Data.PartSize {
return false
}
// download info
if dcp.Info.Data.DownloadInfo.Offset < 0 {
return false
}
if dcp.Info.Data.DownloadInfo.Offset == 0 &&
dcp.Info.Data.DownloadInfo.CRC64 != 0 {
return false
}
rOffset := int64(0)
if len(cp.Info.Data.ObjectInfo.Range) > 0 {
if r, err := ParseRange(cp.Info.Data.ObjectInfo.Range); err != nil {
return false
} else {
rOffset = r.Offset
}
}
if dcp.Info.Data.DownloadInfo.Offset < rOffset {
return false
}
remains := (dcp.Info.Data.DownloadInfo.Offset - rOffset) % dcp.Info.Data.PartSize
if remains != 0 {
return false
}
//valid data
if cp.VerifyData && dcp.Info.Data.DownloadInfo.CRC64 != 0 {
if file, err := os.Open(cp.Info.Data.FilePath); err == nil {
hash := NewCRC64(0)
limitN := dcp.Info.Data.DownloadInfo.Offset - rOffset
io.Copy(hash, io.LimitReader(file, limitN))
file.Close()
if hash.Sum64() != dcp.Info.Data.DownloadInfo.CRC64 {
return false
}
}
}
// update
cp.Info.Data.DownloadInfo = dcp.Info.Data.DownloadInfo
return true
}