1
0
mirror of https://github.com/haiwen/seafile-server.git synced 2025-09-04 17:00:35 +00:00

Add verify blocks after sync (#715)

Co-authored-by: 杨赫然 <heran.yang@seafile.com>
This commit is contained in:
feiniks
2024-11-18 11:34:38 +08:00
committed by GitHub
parent 2cf6b99f40
commit 665d0083bd
4 changed files with 203 additions and 0 deletions

View File

@@ -1055,6 +1055,12 @@ func putUpdateBranchCB(rsp http.ResponseWriter, r *http.Request) *appError {
return &appError{nil, msg, seafHTTPResNoQuota}
}
if option.VerifyClientBlocks {
if body, err := checkBlocks(r.Context(), repo, base, newCommit); err != nil {
return &appError{nil, body, seafHTTPResBlockMissing}
}
}
token := r.Header.Get("Seafile-Repo-Token")
if token == "" {
token = utils.GetAuthorizationToken(r.Header)
@@ -1072,6 +1078,81 @@ func putUpdateBranchCB(rsp http.ResponseWriter, r *http.Request) *appError {
return nil
}
type checkBlockAux struct {
storeID string
version int
fileList []string
}
func checkBlocks(ctx context.Context, repo *repomgr.Repo, base, remote *commitmgr.Commit) (string, error) {
aux := new(checkBlockAux)
aux.storeID = repo.StoreID
aux.version = repo.Version
opt := &diff.DiffOptions{
FileCB: checkFileBlocks,
DirCB: checkDirCB,
Ctx: ctx,
RepoID: repo.StoreID}
opt.Data = aux
trees := []string{base.RootID, remote.RootID}
if err := diff.DiffTrees(trees, opt); err != nil {
return "", err
}
if len(aux.fileList) == 0 {
return "", nil
}
body, _ := json.Marshal(aux.fileList)
return string(body), fmt.Errorf("block is missing")
}
func checkFileBlocks(ctx context.Context, baseDir string, files []*fsmgr.SeafDirent, data interface{}) error {
select {
case <-ctx.Done():
return context.Canceled
default:
}
file1 := files[0]
file2 := files[1]
aux, ok := data.(*checkBlockAux)
if !ok {
err := fmt.Errorf("failed to assert results")
return err
}
if file2 == nil || file2.ID == emptySHA1 || (file1 != nil && file1.ID == file2.ID) {
return nil
}
file, err := fsmgr.GetSeafile(aux.storeID, file2.ID)
if err != nil {
return err
}
for _, blkID := range file.BlkIDs {
if !blockmgr.Exists(aux.storeID, blkID) {
aux.fileList = append(aux.fileList, file2.Name)
return nil
}
}
return nil
}
func checkDirCB(ctx context.Context, baseDir string, dirs []*fsmgr.SeafDirent, data interface{}, recurse *bool) error {
select {
case <-ctx.Done():
return context.Canceled
default:
}
return nil
}
func getHeadCommit(rsp http.ResponseWriter, r *http.Request) *appError {
vars := mux.Vars(r)
repoID := vars["repoid"]