(ctx context.Context, storage driver.Driver, dstDirPath string, file model.FileStreamer, up driver.UpdateProgress)
| 606 | } |
| 607 | |
| 608 | func Put(ctx context.Context, storage driver.Driver, dstDirPath string, file model.FileStreamer, up driver.UpdateProgress) error { |
| 609 | defer func() { |
| 610 | if err := file.Close(); err != nil { |
| 611 | log.Errorf("failed to close file streamer, %v", err) |
| 612 | } |
| 613 | }() |
| 614 | if storage.Config().CheckStatus && storage.GetStorage().Status != WORK { |
| 615 | return errors.WithMessagef(errs.StorageNotInit, "storage status: %s", storage.GetStorage().Status) |
| 616 | } |
| 617 | // UrlTree PUT |
| 618 | if storage.Config().OnlyIndices { |
| 619 | var link string |
| 620 | dstDirPath, link = urlTreeSplitLineFormPath(stdpath.Join(dstDirPath, file.GetName())) |
| 621 | file = &stream.FileStream{Obj: &model.Object{Name: link}, Closers: utils.Closers{file}} |
| 622 | } |
| 623 | // if file exist and size = 0, delete it |
| 624 | dstDirPath = utils.FixAndCleanPath(dstDirPath) |
| 625 | dstPath := stdpath.Join(dstDirPath, file.GetName()) |
| 626 | tempName := file.GetName() + ".openlist_to_delete" |
| 627 | tempPath := stdpath.Join(dstDirPath, tempName) |
| 628 | fi, err := GetUnwrap(ctx, storage, dstPath) |
| 629 | if err == nil { |
| 630 | if fi.GetSize() == 0 { |
| 631 | err = Remove(ctx, storage, dstPath) |
| 632 | if err != nil { |
| 633 | return errors.WithMessagef(err, "while uploading, failed remove existing file which size = 0") |
| 634 | } |
| 635 | } else if storage.Config().NoOverwriteUpload { |
| 636 | // try to rename old obj |
| 637 | err = Rename(ctx, storage, dstPath, tempName) |
| 638 | if err != nil { |
| 639 | return err |
| 640 | } |
| 641 | } else { |
| 642 | file.SetExist(fi) |
| 643 | } |
| 644 | } |
| 645 | err = MakeDir(ctx, storage, dstDirPath) |
| 646 | if err != nil && !errs.IsObjectAlreadyExists(err) { |
| 647 | return errors.WithMessagef(err, "failed to make dir [%s]", dstDirPath) |
| 648 | } |
| 649 | parentDir, err := GetUnwrap(ctx, storage, dstDirPath) |
| 650 | // this should not happen |
| 651 | if err != nil { |
| 652 | return errors.WithMessagef(err, "failed to get dir [%s]", dstDirPath) |
| 653 | } |
| 654 | if model.ObjHasMask(parentDir, model.NoWrite) { |
| 655 | return errors.WithStack(errs.PermissionDenied) |
| 656 | } |
| 657 | // if up is nil, set a default to prevent panic |
| 658 | if up == nil { |
| 659 | up = func(p float64) {} |
| 660 | } |
| 661 | |
| 662 | // 如果小于0,则通过缓存获取完整大小,可能发生于流式上传 |
| 663 | if file.GetSize() < 0 { |
| 664 | log.Warnf("file size < 0, try to get full size from cache") |
| 665 | file.CacheFullAndWriter(nil, nil) |
no test coverage detected