in oss/io_utils.go [666:726]
func (r *RangeReader) read(p []byte) (int, error) {
if r.closed {
return 0, fmt.Errorf("RangeReader is closed")
}
// open stream
if r.in == nil {
httpRangeRemains := r.httpRange
if r.httpRange.Count > 0 {
gotNum := r.httpRange.Offset - r.oriHttpRange.Offset
if gotNum > 0 && r.httpRange.Count > gotNum {
httpRangeRemains.Count = r.httpRange.Count - gotNum
}
}
output, err := r.rangeGet(r.context, httpRangeRemains)
if err == nil {
etag := ToString(output.ETag)
if r.etag == "" {
r.etag = etag
r.modTime = output.LastModified
}
if etag != r.etag {
err = fmt.Errorf("Source file is changed, expect etag:%s ,got etag:%s", r.etag, etag)
}
// Partial Response check
var off int64
if output.ContentRange == nil {
off = 0
r.totalSize = output.ContentLength
} else {
off, _, r.totalSize, _ = ParseContentRange(*output.ContentRange)
}
if off != httpRangeRemains.Offset {
err = fmt.Errorf("Range get fail, expect offset:%v, got offset:%v", httpRangeRemains.Offset, off)
}
}
if err != nil {
if output != nil && output.Body != nil {
output.Body.Close()
}
return 0, err
}
body := output.Body
if httpRangeRemains.Count > 0 {
body = NewLimitedReadCloser(output.Body, httpRangeRemains.Count)
}
r.in = body
}
// read from stream
// ignore error when reading from stream
n, err := r.in.Read(p)
if err != nil && err != io.EOF {
r.in.Close()
r.in = nil
err = nil
}
return n, err
}