func()

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
}