| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- package tos
- import (
- "crypto/md5"
- "encoding/hex"
- "errors"
- "hash"
- "io"
- "strings"
- )
- var (
- ErrETagMissMatch = errors.New("tos: ETag miss match")
- )
- // ETagCheckReadCloser checks ETag on read EOF
- type ETagCheckReadCloser struct {
- reader io.Reader
- closer io.Closer
- checksum hash.Hash
- eTag string
- requestID string
- }
- func NewETagCheckReadCloser(reader io.ReadCloser, eTag, requestID string) *ETagCheckReadCloser {
- checksum := md5.New()
- return &ETagCheckReadCloser{
- reader: io.TeeReader(reader, checksum),
- closer: reader,
- checksum: checksum,
- eTag: strings.Trim(eTag, `"`),
- requestID: requestID,
- }
- }
- func (ec *ETagCheckReadCloser) Read(p []byte) (n int, err error) {
- n, err = ec.reader.Read(p)
- if err == io.EOF && len(ec.eTag) > 0 {
- sum := ec.checksum.Sum(nil)
- if hexSum := hex.EncodeToString(sum); hexSum != ec.eTag {
- return n, &ChecksumError{
- RequestID: ec.requestID,
- ExpectedChecksum: ec.eTag,
- ActualChecksum: hexSum,
- }
- }
- }
- return n, err
- }
- func (ec *ETagCheckReadCloser) Close() error {
- return ec.closer.Close()
- }
|