mirror of
https://git.sr.ht/~sircmpwn/tokidoki
synced 2025-12-12 06:07:22 +01:00
This commit introduces some helpers so that ETags can be calculated at the same time that files get read or written. Besides looking nicer, it should also help reduce lock contention around file access, as files do not need to be opened twice anymore.
58 lines
1.2 KiB
Go
58 lines
1.2 KiB
Go
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[:])
|
|
}
|