48 lines
2.2 KiB
Go
48 lines
2.2 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"crypto/sha256"
|
|
"errors"
|
|
|
|
rvboxv1 "github.com/rvbox/rvbox/gen/go/rvbox/v1"
|
|
"github.com/rvbox/rvbox/internal/agentproto"
|
|
"github.com/rvbox/rvbox/internal/client/spool"
|
|
"github.com/rvbox/rvbox/internal/domain"
|
|
)
|
|
|
|
var ErrInvalidScriptTransfer = errors.New("invalid script transfer")
|
|
|
|
// ApplyScriptChunk validates one server script frame and appends it to the
|
|
// durable client spool. The spool accepts only the next contiguous range or
|
|
// an exact replay, so reconnects cannot create holes or duplicate bytes.
|
|
func ApplyScriptChunk(ctx context.Context, store *spool.Store, session Session, chunk *rvboxv1.ScriptChunk, limits agentproto.Limits) (spool.ScriptStatus, error) {
|
|
if store == nil || session.Generation == 0 || chunk == nil || chunk.GetOffset() > limits.MaxScriptBytes || uint64(len(chunk.GetData())) > limits.MaxRawChunkBytes || len(chunk.GetSha256()) != sha256.Size {
|
|
return spool.ScriptStatus{}, ErrInvalidScriptTransfer
|
|
}
|
|
issue, err := domain.ParseUUIDv7(chunk.GetIssueUuid())
|
|
if err != nil || sha256.Sum256(chunk.GetData()) != bytesToDigest(chunk.GetSha256()) {
|
|
return spool.ScriptStatus{}, ErrInvalidScriptTransfer
|
|
}
|
|
return store.AppendScriptChunk(ctx, issue, chunk.GetOffset(), chunk.GetData(), bytesToDigest(chunk.GetSha256()))
|
|
}
|
|
|
|
// ApplyScriptCommit marks a fully received script launch-eligible only after
|
|
// the spool verifies the declared size and whole-body SHA-256.
|
|
func ApplyScriptCommit(ctx context.Context, store *spool.Store, session Session, commit *rvboxv1.ScriptCommit, limits agentproto.Limits) (spool.ScriptStatus, error) {
|
|
if store == nil || session.Generation == 0 || commit == nil || commit.GetSizeBytes() > limits.MaxScriptBytes || len(commit.GetSha256()) != sha256.Size {
|
|
return spool.ScriptStatus{}, ErrInvalidScriptTransfer
|
|
}
|
|
issue, err := domain.ParseUUIDv7(commit.GetIssueUuid())
|
|
if err != nil {
|
|
return spool.ScriptStatus{}, ErrInvalidScriptTransfer
|
|
}
|
|
return store.CommitScript(ctx, issue, spool.ScriptDescriptor{SizeBytes: commit.GetSizeBytes(), SHA256: bytesToDigest(commit.GetSha256())})
|
|
}
|
|
|
|
func bytesToDigest(value []byte) [sha256.Size]byte {
|
|
var digest [sha256.Size]byte
|
|
copy(digest[:], value)
|
|
return digest
|
|
}
|