package storage import ( "crypto/sha1" "encoding/base64" "hash" "io" ) type ETagWriter struct { io.Writer output io.Writer csum hash.Hash } // NewETagWriter creates a new io.Writer that pipes writes to the provided // output while also calculating the contents ETag. func NewETagWriter(output io.Writer) *ETagWriter { csum := sha1.New() return &ETagWriter{ output: io.MultiWriter(output, csum), csum: csum, } } func (e *ETagWriter) Write(p []byte) (n int, err error) { return e.output.Write(p) } func (e *ETagWriter) ETag() string { csum := e.csum.Sum(nil) return base64.StdEncoding.EncodeToString(csum[:]) } type ETagReader struct { io.Reader input io.Reader csum hash.Hash } // NewETagReader creates a new io.Reader that pipes reads from the provided // input while also calculating the contents ETag. func NewETagReader(input io.Reader) *ETagReader { csum := sha1.New() return &ETagReader{ input: io.TeeReader(input, csum), csum: csum, } } func (e *ETagReader) Read(p []byte) (n int, err error) { return e.input.Read(p) } func (e *ETagReader) ETag() string { csum := e.csum.Sum(nil) return base64.StdEncoding.EncodeToString(csum[:]) }