fix(files): 模组包上传也逐段核对 SHA-256、长文件名能写、卡住的导出按时停掉、世界被占用时文件页说明原因并等它结束
This commit is contained in:
59 files changed
+2538
-338
No files matched your search
@@ -0,0 +1,41 @@
|
||||
package submit
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
)
|
||||
|
||||
// ErrDigestMismatch reports bytes that do not hash to the SHA-256 their sender
|
||||
// computed over them (the request's Content-Digest): they changed on the way.
|
||||
// The API answers 400 digest_mismatch, and the client sends them again.
|
||||
var ErrDigestMismatch = errors.New("submit: the bytes that arrived do not match the digest they were sent with")
|
||||
|
||||
// VerifyDigest passes r through and, where it ends, answers ErrDigestMismatch in
|
||||
// place of io.EOF unless what went by hashes to want, a SHA-256. The stores
|
||||
// treat that like any read that breaks off: UploadPart cuts the part back off,
|
||||
// and UploadContext never lets the blob replace the one before it. So bytes
|
||||
// changed on the way are never kept.
|
||||
func VerifyDigest(r io.Reader, want []byte) io.Reader {
|
||||
return &digestReader{r: r, h: sha256.New(), want: want}
|
||||
}
|
||||
|
||||
type digestReader struct {
|
||||
r io.Reader
|
||||
h hash.Hash
|
||||
want []byte
|
||||
}
|
||||
|
||||
func (d *digestReader) Read(p []byte) (int, error) {
|
||||
n, err := d.r.Read(p)
|
||||
d.h.Write(p[:n])
|
||||
if err == io.EOF {
|
||||
if got := d.h.Sum(nil); !bytes.Equal(got, d.want) {
|
||||
return n, fmt.Errorf("%w: they hash to %x, sent as %x", ErrDigestMismatch, got, d.want)
|
||||
}
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
Reference in new issue
Block a user