fix(files): 模组包上传也逐段核对 SHA-256、长文件名能写、卡住的导出按时停掉、世界被占用时文件页说明原因并等它结束

This commit is contained in:
Lemon-miaow committed 2026-09-29 01:26:24 +08:00
1 parent 1d1549cea2
commit cb3065da1d
59 files changed
+2538 -338

No files matched your search

+41
View File
@@ -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
}